我在使用 Microsoft Identity Framework 进行用户管理的 .Net Core Razor Pages 应用程序 (.Net 5) 中设置了“使用 Apple 登录”。
我遵循了 Scott 的这个教程,它对我的 Apple 登录页面有所帮助。
但是在调用回调端点时成功登录后,我进入null
了_signInManager.GetExternalLoginInfoAsync()
方法调用。
我最初的研究表明,ID 令牌可能不包含所需的数据。这是正确的,因为 Apple 返回的 ID 令牌不包含email
或name
即使在scope
.
样品要求:https://appleid.apple.com/auth/authorize?client_id=net.demo.client&redirect_uri=https%3A%2F%2Fdemo.website.net%2Fsignin-apple&response_type=code%20id_token&scope=email%20name&response_mode=form_post&nonce=637679-omitted
这是从Startup.ConfigureServices()
方法调用的身份验证设置:
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)
})
;
这是回调端点:
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...
}