Post Impatica
Post Impatica

Reputation: 16423

IdentityServer4 and OidcClient on IOS prompt

I have IDS4 and a Xamarin.Forms app all working fine except one little issue. Every single time the iOS app accesses the IDP server it first gives me this prompt:

"AppName" Wants to Use "" to Sign In This allows the app and website to share information about you

What is causing this?

enter image description here

Upvotes: 0

Views: 731

Answers (1)

Post Impatica
Post Impatica

Reputation: 16423

I have this error using IdentityModel.OidcClient2. Please see this link for the cause. This is the gist of it:

Cause

This is a system dialog that was added in iOS 11 to SFAuthenticationSession. It is triggered by this code in AppAuth:

SFAuthenticationSession* authenticationVC = 
 [[SFAuthenticationSession alloc] initWithURL:requestURL 
                            callbackURLScheme:redirectScheme 
                            completionHandler:^(NSURL * _Nullable callbackURL, 
                                                NSError * _Nullable error) { 

There isn't a way to get rid of the dialog, except to not use SFAuthenticationSession which means you lose Single SignOn, which is worse.

I ended up using SFSafariViewController instead of SFAuthenticationSession by using the method mentioned by MLeech HERE

Solution

Which basically meant add these lines to your AppDelegate.cs

 public override UIWindow Window
    {
        get;
        set;
    }

    public static Action<string> CallbackHandler { get; set; }

    public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
    {
        CallbackHandler(url.AbsoluteString);
        CallbackHandler = null;

        return true;
    }

Then use this code for your SFAuthenticationSessionBrowser.cs

public class SFAuthenticationSessionBrowser : IBrowser
{
    public Task<BrowserResult> InvokeAsync(BrowserOptions options)
    {
        var task = new TaskCompletionSource<BrowserResult>();

        var safari = new SFSafariViewController(new NSUrl(options.StartUrl));

        AppDelegate.CallbackHandler = async url =>
        {
            await safari.DismissViewControllerAsync(true);
            task.SetResult(new BrowserResult()
            {
                Response = url
            });
        };

        // https://forums.xamarin.com/discussion/24689/how-to-acces-the-current-view-uiviewcontroller-from-an-external-service
        var window = UIApplication.SharedApplication.KeyWindow;
        var vc = window.RootViewController;
        while (vc.PresentedViewController != null)
        {
            vc = vc.PresentedViewController;
        }
        vc.PresentViewController(safari, true, null);

        return task.Task;
    }
}

Upvotes: 2

Related Questions