public static string GenerateSecretToken(AppleSignInOptions options) { var cngKey = CngKey.Import( Convert.FromBase64String(CleanP8Key(options.P8Key)), CngKeyBlobFormat.Pkcs8PrivateBlob); var jwtHandler = new JwtSecurityTokenHandler(); var jwtToken = jwtHandler.CreateJwtSecurityToken( issuer: options.TeamId, audience: APPLE_ISSUER, subject: new ClaimsIdentity(new List <Claim> { new Claim("sub", options.ServerId) }), expires: DateTime.UtcNow.AddMinutes(5), issuedAt: DateTime.UtcNow, notBefore: DateTime.UtcNow, signingCredentials: new SigningCredentials( new ECDsaSecurityKey(new ECDsaCng(cngKey)), SecurityAlgorithms.EcdsaSha256)); return(jwtHandler.WriteToken(jwtToken)); }
public static AuthenticationBuilder AddAppleSignIn(this AuthenticationBuilder authenticationBuilder, AppleSignInOptions appleOptions, Action <OpenIdConnectOptions> configureOptions = default) { return(authenticationBuilder.AddOpenIdConnect("Apple", async options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.ResponseType = "code id_token"; options.Scope.Clear(); options.Scope.Add("name"); options.Scope.Add("email"); options.ClientId = appleOptions.ServerId; // ServerId is client id options.CallbackPath = "/signin-apple"; // Default callback path options.TokenValidationParameters.ValidIssuer = APPLE_ISSUER; // Which issuer we expect options.SaveTokens = true; options.Configuration = new OpenIdConnectConfiguration { AuthorizationEndpoint = APPLE_AUTH_URL, TokenEndpoint = APPLE_TOKEN_URL, }; options.Events.OnAuthorizationCodeReceived = context => { context.TokenEndpointRequest.ClientSecret = GenerateSecretToken(appleOptions); return Task.CompletedTask; }; // Get the identity token signing key we expect var jwks = await new HttpClient().GetStringAsync(APPLE_JWT_KEYS_URL); options.TokenValidationParameters.IssuerSigningKey = new JsonWebKeySet(jwks).Keys.FirstOrDefault(); })); }