Home > Blockchain >  _signInManager.GetExternalLoginInfoAsync() returns null for Apple Login
_signInManager.GetExternalLoginInfoAsync() returns null for Apple Login

Time:09-24

I have setup "Login with Apple" in my .Net Core Razor Pages app (.Net 5) which is using Microsoft Identity Framework for user management.

I followed this tutorial of Scott which helped me as far as the Apple Login page.

But after the successful login when the Call-Back endpoint is called, I am getting null in the _signInManager.GetExternalLoginInfoAsync() method call.

My initial research suggested that the ID Token may not contain required data. Which is correct because the ID Token returned by the Apple does not contain email or name even though it is requested in the scope.

Sample request:https://appleid.apple.com/auth/authorize?client_id=net.demo.client&redirect_uri=https://demo.website.net/signin-apple&response_type=code id_token&scope=email name&response_mode=form_post&nonce=637679-omitted

Here's the Authentication setup called from Startup.ConfigureServices() method:

IdentityModelEventSource.ShowPII = true;
        services.AddAuthentication(options =>
        {
            //options.DefaultAuthenticateScheme = "cookie";//Commented because this line was causing the Google login stop.
            //options.DefaultChallengeScheme = "apple";//Commented because this line was causing the Google login stop.
        })
               .AddCookie("cookie")
               .AddOpenIdConnect("apple", "Apple", async options =>
               {
                   options.Authority = "https://appleid.apple.com"; // disco doc: https://appleid.apple.com/.well-known/openid-configuration

                   options.ResponseType = "code id_token";
                   options.SignInScheme = "cookie";

                   options.DisableTelemetry = true;

                   options.Scope.Clear(); // otherwise I had consent request issues
                   options.Scope.Add("email");
                   options.Scope.Add("name");
                   options.ClientId = "net.demo.client"; // Service ID
                   options.CallbackPath = "/signin-apple"; // corresponding to your redirect URI

                   options.Events.OnAuthorizationCodeReceived = context =>
                      {
                          context.TokenEndpointRequest.ClientSecret = TokenGenerator.CreateNewToken();
                          return Task.CompletedTask;
                      };
                   options.Events.OnRedirectToIdentityProvider = context =>
                   {
                       var builder = new UriBuilder(context.ProtocolMessage.RedirectUri);
                       builder.Scheme = "https";
                       builder.Port = -1;
                       context.ProtocolMessage.RedirectUri = builder.ToString();
                       return Task.FromResult(0);
                   };
                   options.UsePkce = false; // apple does not currently support PKCE (April 2021)
               })
           ;

Here's the call-back endpoint:

public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");
        if (remoteError != null)
        {
            ErrorMessage = $"Error from external provider: {remoteError}";
            return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
        }
        var info = await _signInManager.GetExternalLoginInfoAsync();//Returns null.
        if (info == null)
        {
            ErrorMessage = "Error loading external login information.";
            return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
        }
    //Code omitted...
}

CodePudding user response:

Is ASP.Net Identity configured to use the "cookie" scheme for external logins?

By default it will use IdentityConstants.ExternalScheme. Try using:

options.SignInScheme = IdentityConstants.ExternalScheme; 

instead of

options.SignInScheme = "cookie";
  • Related