用Apple签名“ Invalid_client”错误的ASP.NET核心令牌请求

发布于 2025-02-04 04:56:52 字数 5113 浏览 4 评论 0 原文

我正在尝试使用OpenIDConnect客户端库中的ASP.NET Core应用程序中的Apple登录。在本文的帮助下,。当我在Apple Console中创建应用程序 https://developer.apple.com/accoint/资源/标识符。但是,当我创建另一个应用程序(以及带有相应键的服务标识符)时,新应用程序不起作用。

  1. 用apple

    创建app id

    创建应用程序ID
  2. 创建服务标识符,并使用Apple启用

  3. 创建服务标识符,为此应用创建密钥

  4. 密钥

,直到我撤销第一个应用程序并为新应用创建新密钥。

如何创建两个工作应用程序?我有限制吗?

添加“ Apple”外部提供商:

.AddOpenIdConnect("apple", async options =>
            {
                options.ResponseType = "code id_token"; // hybrid flow due to lack of PKCE support
                options.ResponseMode = "form_post"; // form post due to prevent PII in the URL
                options.UsePkce = false; // apple does not currently support PKCE (April 2021)
                options.DisableTelemetry = true;

                options.Scope.Clear(); // apple does not support the profile scope
                options.Scope.Add("openid");
                options.Scope.Add("email");
                options.Scope.Add("name");

                options.Authority = "https://appleid.apple.com";
                options.ClientId = configuration["Authentication:Apple:ClientId"]; // Service ID
                options.CallbackPath = "/signin-apple";

                options.Events.OnAuthorizationCodeReceived = context =>
                {
                    context.TokenEndpointRequest.ClientSecret = AppleTokenGenerator.CreateNewToken(configuration["Authentication:Apple:Iss"],configuration["Authentication:Apple:ClientId"], configuration["Authentication:Apple:ClientSecret"]);
                    return Task.CompletedTask;
                };

               

                // TODO
            })

按照 https://www.scottbrady91.com/openid-connect/implementing-sign-sign-in-with-with-apple-in-aspnet-core。

public static string CreateNewToken(string iss, string sub, string privateKey)
        {
            const string aud = "https://appleid.apple.com";
            var now = DateTime.UtcNow;

            
            var ecdsa = ECDsa.Create();
            ecdsa?.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out _);

            var handler = new JsonWebTokenHandler();
            return handler.CreateToken(new SecurityTokenDescriptor
            {
                Issuer = iss,
                Audience = aud,
                Claims = new Dictionary<string, object> { { "sub", sub } },
                Expires = now.AddMinutes(60), // expiry can be a maximum of 6 months - generate one per request or re-use until expiration
                IssuedAt = now,
                NotBefore = now.AddMinutes(-60),
                SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(ecdsa), SecurityAlgorithms.EcdsaSha256)
            });
        }

授权请求正常。 No errors and redirecting browser to options.CallbackPath = "/signin-apple";

Error occures on token request: OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'error_description is null' ,error_uri:'error_uri为null'。

i o'pecturated请求:

curl --location --request POST 'https://appleid.apple.com/auth/token?grant_type=authorization_code&client_id=ua.secret.site&code=c3a55f910698647768b41e76a80881778.0.rwqy.Pt5lhGYR0eKHHmIOhsrkrw&redirect_uri=https://local.test:5001/signin-apple&client_secret=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1YS5zZWNyZXQuc2l0ZSIsImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJleHAiOjE2NTQwOTg2NjYsImlzcyI6IjdCNjREQzJYUE4iLCJpYXQiOjE2NTQwOTUwNjYsIm5iZiI6MTY1NDA5MTQ2Nn0.PkaPgnCF4u53w9yZgRXqmJ1xyN2DhTIukoknvRQ0jLfU4riVEUqPwh5c0Umx_cteadrcTjID-J_iH3hFPxUTrA'

获取此响应:

{
    "error": "invalid_client"
}

没有有用的响应标头

,但在另一个客户端,一切都还好

我还为两个不同应用程序(t- Testing应用程序,P-生产应用程序)释放和撤销了实验键。 这是结果:

“在此处输入图像描述”

结论: 尽管为不同的应用程序创建了两个键中的两个键中的一个中,但一次键正在工作。键正在对单个应用程序的关键旋转规则无效(),但有时没有。 我很困惑。

I`m trying to implement Sign In With Apple in my Asp.Net Core application using OpenIdConnect client library. With help of this article https://www.scottbrady91.com/openid-connect/implementing-sign-in-with-apple-in-aspnet-core. Everything works fine when I create application in apple console https://developer.apple.com/account/resources/identifiers. But when I create another application (and service identifier with corresponding key) the new application doesnt work.

  1. Create App ID with signin with apple

  2. with Sign In With Apple enabled

  3. Creating service identifier with Sign In With Apple enabled

  4. Create key for this app

  5. Use this key for client_secret generation

If I create another app/serviceId/key it doesnt work untill I revoke key for first app and create new key for new app.

How can I create two working apps? I there any restriction?

Adding "apple" external provider:

.AddOpenIdConnect("apple", async options =>
            {
                options.ResponseType = "code id_token"; // hybrid flow due to lack of PKCE support
                options.ResponseMode = "form_post"; // form post due to prevent PII in the URL
                options.UsePkce = false; // apple does not currently support PKCE (April 2021)
                options.DisableTelemetry = true;

                options.Scope.Clear(); // apple does not support the profile scope
                options.Scope.Add("openid");
                options.Scope.Add("email");
                options.Scope.Add("name");

                options.Authority = "https://appleid.apple.com";
                options.ClientId = configuration["Authentication:Apple:ClientId"]; // Service ID
                options.CallbackPath = "/signin-apple";

                options.Events.OnAuthorizationCodeReceived = context =>
                {
                    context.TokenEndpointRequest.ClientSecret = AppleTokenGenerator.CreateNewToken(configuration["Authentication:Apple:Iss"],configuration["Authentication:Apple:ClientId"], configuration["Authentication:Apple:ClientSecret"]);
                    return Task.CompletedTask;
                };

               

                // TODO
            })

Generating client_secret as described in https://www.scottbrady91.com/openid-connect/implementing-sign-in-with-apple-in-aspnet-core.:

public static string CreateNewToken(string iss, string sub, string privateKey)
        {
            const string aud = "https://appleid.apple.com";
            var now = DateTime.UtcNow;

            
            var ecdsa = ECDsa.Create();
            ecdsa?.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out _);

            var handler = new JsonWebTokenHandler();
            return handler.CreateToken(new SecurityTokenDescriptor
            {
                Issuer = iss,
                Audience = aud,
                Claims = new Dictionary<string, object> { { "sub", sub } },
                Expires = now.AddMinutes(60), // expiry can be a maximum of 6 months - generate one per request or re-use until expiration
                IssuedAt = now,
                NotBefore = now.AddMinutes(-60),
                SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(ecdsa), SecurityAlgorithms.EcdsaSha256)
            });
        }

Authorization request works fine. No errors and redirecting browser to options.CallbackPath = "/signin-apple";

Error occures on token request: OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'error_description is null', error_uri: 'error_uri is null'.

I`ve simulated request:

curl --location --request POST 'https://appleid.apple.com/auth/token?grant_type=authorization_code&client_id=ua.secret.site&code=c3a55f910698647768b41e76a80881778.0.rwqy.Pt5lhGYR0eKHHmIOhsrkrw&redirect_uri=https://local.test:5001/signin-apple&client_secret=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1YS5zZWNyZXQuc2l0ZSIsImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJleHAiOjE2NTQwOTg2NjYsImlzcyI6IjdCNjREQzJYUE4iLCJpYXQiOjE2NTQwOTUwNjYsIm5iZiI6MTY1NDA5MTQ2Nn0.PkaPgnCF4u53w9yZgRXqmJ1xyN2DhTIukoknvRQ0jLfU4riVEUqPwh5c0Umx_cteadrcTjID-J_iH3hFPxUTrA'

and getting this response:

{
    "error": "invalid_client"
}

with no usefull response headers

But with another client everything is ok

Also I`ve made experiment releasing and revoking keys for two different applications (t - testing app, p - production app).
Here is the result:

enter image description here

Conclusion:
Only one of two keys is working at a time, despite being created for diferent applications. Keys are being invalidated acording to key rotation rules for SINGLE application (https://help.apple.com/developer-account/?lang=en#/dev77c875b7e), but sometimes NOT.
I`am so confused.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月寒剑心 2025-02-11 04:56:52

魔术是添加此

SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(ecdsa){KeyId = keyId},
SecurityAlgorithms.EcdsaSha256)

键时可以正常工作,但是如果有多个键,我想它使用了最后的键进行验证。
您需要添加 keyID 以使Apple识别验证密钥。

The magic was to add this

SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(ecdsa){KeyId = keyId},
SecurityAlgorithms.EcdsaSha256)

It works fine when there is one key, but if there are multiple, I guess it uses the last key for validation.
You need to add keyId for Apple to recognize the key for validation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文