问题描述
我花了一些时间弄清楚如何让 Apple 登录与身份服务器一起工作,以下是要遵循的步骤。下次有时间我会改进答案。
解决方法
更新您的 startup.cs 配置服务方法以支持与 Apple 签署。
services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
auth.DefaultSignInScheme = ProviderSchemaConstants.Apple;
}).AddOpenIdConnect(ProviderSchemaConstants.Apple,ProviderDisplayNameConstants.Apple,async options =>
{
options.ClientId = this.Configuration["SignInWithApple:ClientId"];
options.ResponseType = "code";
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.DisableTelemetry = true;
options.CallbackPath = "/signin-apple";
options.Scope.Clear();
options.Scope.Add("email");
options.Scope.Add("name");
options.Configuration = new OpenIdConnectConfiguration
{
AuthorizationEndpoint = "https://appleid.apple.com/auth/authorize",TokenEndpoint = "https://appleid.apple.com/auth/token"
};
options.Events.OnAuthorizationCodeReceived = context =>
{
context.TokenEndpointRequest.ClientSecret = this.CreateNewToken();
return Task.CompletedTask;
};
options.TokenValidationParameters.ValidIssuer = "https://appleid.apple.com";
var jwks = await new HttpClient().GetStringAsync("https://appleid.apple.com/auth/keys");
options.TokenValidationParameters.IssuerSigningKeys = new JsonWebKeySet(jwks).Keys;
options.ProtocolValidator.RequireNonce = false;
});
将此方法添加到 Startup.cs 的底部或单独的文件中。
private string CreateNewToken()
{
try
{
const string iss = "ACCOUNT_ID_NEED_TO_BE_REPLACED"; // your account's team ID found in the dev portal
const string aud = "https://appleid.apple.com";
const string sub = "CLIENTNAME_FROM_APPLE_DEVELOPER_PORTAL"; // same as client_id
// var fileInfo = await System.IO.File.ReadAllBytesAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"AuthKey_KEYID_NEED_TO_BE_REPLACeD.p8"));
const string privateKey = "KEY_NEED_TO_BE_REPLACED"; // contents of .p8 file
var cngKey = CngKey.Import(
Convert.FromBase64String(privateKey),CngKeyBlobFormat.Pkcs8PrivateBlob);
var d = DateTime.UtcNow.AddDays(-5);
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateJwtSecurityToken(
issuer: iss,audience: aud,subject: new ClaimsIdentity(new List<Claim> { new Claim("sub",sub) }),expires: d.AddMonths(3),// expiry can be a maximum of 6 months
issuedAt: d,notBefore: d,signingCredentials: new SigningCredentials(
new ECDsaSecurityKey(new ECDsaCng(cngKey)),SecurityAlgorithms.EcdsaSha256));
return handler.WriteToken(token);
}
catch (Exception exception)
{
throw exception;
}
}
如果您在任何地方需要帮助,请告诉我,我可以添加更多信息。