将 singin 与 Apple 与 Identity Server 4 集成

问题描述

我花了一些时间弄清楚如何让 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;
            }
        }

如果您在任何地方需要帮助,请告诉我,我可以添加更多信息。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...