Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Apple登录-验证ID令牌_C#_Jwt_Openid Connect_Apple Sign In - Fatal编程技术网

C# Apple登录-验证ID令牌

C# Apple登录-验证ID令牌,c#,jwt,openid-connect,apple-sign-in,C#,Jwt,Openid Connect,Apple Sign In,我正在实施Apple登录移动应用程序。成功登录后,我获得了有效期为一天的ID令牌 以下是我在登录后收到的JWT令牌示例: eyJraWQiOiJZdXlYb1kiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLmNsdWJiYWJsZSIsImV4cCI6MTYxODU4NTcyOCwiaWF0IjoxNjE4NDk5MzI4LCJzdWIiOiIwMDE4NTAuMzdkY2Nm

我正在实施Apple登录移动应用程序。成功登录后,我获得了有效期为一天的ID令牌

以下是我在登录后收到的JWT令牌示例:

eyJraWQiOiJZdXlYb1kiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLmNsdWJiYWJsZSIsImV4cCI6MTYxODU4NTcyOCwiaWF0IjoxNjE4NDk5MzI4LCJzdWIiOiIwMDE4NTAuMzdkY2NmZGIxYzEyNDliY2E2NjE5YThkYjQ2MWFlNDkuMDQzMyIsImNfaGFzaCI6InVMTUV1eTRCaFozRVc1NXR1OXZtZGciLCJhdXRoX3RpbWUiOjE2MTg0OTkzMjgsIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.e86uz4Qqu63mD0hHVdzBU3EfW0G-rDUprBiXkyPkvPIHIWPM1LyjpFs2GeoWAcdfUdmGww6C8SLLgk4iMKjK_yrpxiQBmbIzdCLBrwW4P8Y40llcrotyRuwyalfycyUJ8GP9yqjs5_R7yZlDd4oq0wrDNyXVjlbdGSfNUGqmXScBgXm3yCH0rD85GK0hX3XM-fA133Y5tj1DRALZhnw2GLy-6YEPBlqFE-cvu9aif9ajuDx3gPwp9AQ_nXP3pWjSg2G5eYx7UMpowXbAVoDSlhQVu_KJgxPsW61i50QnhykmeNA7LxA2iLQnlGk5VKzNlATub49SybUnmPSViO_Fbw
现在我想使用
System.IdentityModel.Tokens.Jwt
下的
JwtSecurityTokenHandler
验证这个令牌

我编写了以下代码:

tokenHandler.ValidateToken(body.access_token, new TokenValidationParameters() 
{ 
    ValidateIssuer = true,
    ValidIssuers = new List<string> { appleTokenIssuerName },
    ValidateAudience = true,
    ValidAudiences =  new List<string> { appleAppClientId },
    ValidateLifetime = false,
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = // I want to pass signing key here but I'm not sure how can I do that.
}, out SecurityToken token);
tokenHandler.ValidateToken(body.access\u token,新的TokenValidationParameters()
{ 
validateisuer=true,
ValidIssuers=新列表{appleTokenIssuerName},
ValidateAudience=true,
Validudiences=新列表{AppleAppClient},
ValidateLifetime=false,
ValidateSuersigningKey=true,
IssuerSigningKey=//我想在这里传递签名密钥,但我不确定如何传递。
},out SecurityToken(令牌);
Apple签名密钥可在此处设置为Json web密钥-


您能帮我找到将此密钥提供给
SecurityKey
参数的正确方法吗?

最简单的方法是使用
JsonWebKey
并将带有其中一个密钥的JSON传递给构造函数。一个更优雅的方法是创建一个解析器,它可以在需要时从苹果下载这些密钥。这还将使您能够在Apple旋转时创建备用键和刷新键。

需要从中派生的对象。这方面的例子有或

由于发布的链接包含JWK格式的公钥,
JsonWebKey
(如中所述)是一个封闭的解决方案:

using Microsoft.IdentityModel.Tokens;
...
string jwkSerialized = @"{
                        ""kty"":""RSA"",
                        ""kid"":""YuyXoY"",
                        ""use"":""sig"",
                        ""alg"":""RS256"",
                        ""n"":""1JiU4l3YCeT4o0gVmxGTEK1IXR-Ghdg5Bzka12tzmtdCxU00ChH66aV-4HRBjF1t95IsaeHeDFRgmF0lJbTDTqa6_VZo2hc0zTiUAsGLacN6slePvDcR1IMucQGtPP5tGhIbU-HKabsKOFdD4VQ5PCXifjpN9R-1qOR571BxCAl4u1kUUIePAAJcBcqGRFSI_I1j_jbN3gflK_8ZNmgnPrXA0kZXzj1I7ZHgekGbZoxmDrzYm2zmja1MsE5A_JX7itBYnlR41LOtvLRCNtw7K3EFlbfB6hkPL-Swk5XNGbWZdTROmaTNzJhV-lWT0gGm6V1qWAK2qOZoIDa_3Ud0Gw"",
                        ""e"":""AQAB""
                        }";
JsonWebKey jwk = new JsonWebKey(jwkSerialized);
与发布的JWT匹配的密钥可由JWT标题中包含的kid识别,例如使用

如前所述,导入不限于JWK格式。例如,如果密钥采用广泛使用的X.509/SPKI格式,则可以按如下方式导入(例如在.NET Core 3.0+下):

using Microsoft.IdentityModel.Tokens;
using System.Security.Cryptography;
...
byte[] x509der = Convert.FromBase64String("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1JiU4l3YCeT4o0gVmxGTEK1IXR+Ghdg5Bzka12tzmtdCxU00ChH66aV+4HRBjF1t95IsaeHeDFRgmF0lJbTDTqa6/VZo2hc0zTiUAsGLacN6slePvDcR1IMucQGtPP5tGhIbU+HKabsKOFdD4VQ5PCXifjpN9R+1qOR571BxCAl4u1kUUIePAAJcBcqGRFSI/I1j/jbN3gflK/8ZNmgnPrXA0kZXzj1I7ZHgekGbZoxmDrzYm2zmja1MsE5A/JX7itBYnlR41LOtvLRCNtw7K3EFlbfB6hkPL+Swk5XNGbWZdTROmaTNzJhV+lWT0gGm6V1qWAK2qOZoIDa/3Ud0GwIDAQAB");
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportSubjectPublicKeyInfo(x509der, out _); 
RsaSecurityKey rsask = new RsaSecurityKey(rsa);
可以验证两个键的等效性,例如

然后可以使用
jwk
rsask
对发布的JWT进行如下验证:

using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
...
bool verified = false;
string jwt = "eyJraWQiOiJZdXlYb1kiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLmNsdWJiYWJsZSIsImV4cCI6MTYxODU4NTcyOCwiaWF0IjoxNjE4NDk5MzI4LCJzdWIiOiIwMDE4NTAuMzdkY2NmZGIxYzEyNDliY2E2NjE5YThkYjQ2MWFlNDkuMDQzMyIsImNfaGFzaCI6InVMTUV1eTRCaFozRVc1NXR1OXZtZGciLCJhdXRoX3RpbWUiOjE2MTg0OTkzMjgsIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.e86uz4Qqu63mD0hHVdzBU3EfW0G-rDUprBiXkyPkvPIHIWPM1LyjpFs2GeoWAcdfUdmGww6C8SLLgk4iMKjK_yrpxiQBmbIzdCLBrwW4P8Y40llcrotyRuwyalfycyUJ8GP9yqjs5_R7yZlDd4oq0wrDNyXVjlbdGSfNUGqmXScBgXm3yCH0rD85GK0hX3XM-fA133Y5tj1DRALZhnw2GLy-6YEPBlqFE-cvu9aif9ajuDx3gPwp9AQ_nXP3pWjSg2G5eYx7UMpowXbAVoDSlhQVu_KJgxPsW61i50QnhykmeNA7LxA2iLQnlGk5VKzNlATub49SybUnmPSViO_Fbw";
var tokenHandler = new JwtSecurityTokenHandler();
try
{
    tokenHandler.ValidateToken(
        jwt,
        new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuers = new List<string> { "https://appleid.apple.com" },
            ValidateAudience = true,
            ValidAudiences = new List<string> { "com.clubbable" },
            ValidateLifetime = false,
            IssuerSigningKey = jwk // alternatively, rsask can be used            
        },
        out SecurityToken token);
    verified = true;
    Console.WriteLine("Token: " + token.ToString());
}
catch (Exception ex)
{
    Console.WriteLine("Verification failure: " + ex.Message);
}

Console.WriteLine("Verified: " + verified);
使用Microsoft.IdentityModel.Tokens;
使用制度;
使用System.Collections.Generic;
使用System.IdentityModel.Tokens.Jwt;
...
bool-verified=false;
字符串jwt="Eyjrawqioijzdxlyb1kilcHbgCjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjIjHrWjIjIjIjIjIjIjIjIjBwBwBjUy9TiizIjIyWyWyWyWyWyWyWyWyWyWyWyWyWyWjJyWjJJJJJJJJJJJzSiSiZ4c4c4c4c4c6TyxNjIzNzNjIzNzNzNjIzNdNjNjNjNjNjNjNjNjNjI6月6日,6月6日,6月6日,6月8日,8月8日,8月8日,8月8日,8月8日,8月8日,8月8日,8月8日,8月8日,6月6日,6月6日,6月6日,6月8日,6月8日,6月8日,8月8日,8月8日,8月8日,8月8日,8日,8月8月8日,8日,8月8日,8日,8月8日,8日,8月8日,8月8日,8日,8月8日,8月8日,8月8日,8日,8日,8日,8月8日,8日,8月8日,8月8日,8日,8日,8日,8月8日,8月8日,在8月8日,8月8日,8月8日,在8月8日,在8月8日,49SYBUNMPSVIO_Fbw”;
var tokenHandler=new JwtSecurityTokenHandler();
尝试
{
tokenHandler.ValidateToken(
jwt,
新的TokenValidationParameters
{
validateisuer=true,
ValidIssuers=新列表{”https://appleid.apple.com" },
ValidateAudience=true,
Validudiences=新列表{“com.clubable”},
ValidateLifetime=false,
IssuerSigningKey=jwk//或者,也可以使用rsask
},
out SecurityToken(令牌);
验证=真实;
Console.WriteLine(“Token:+Token.ToString());
}
捕获(例外情况除外)
{
Console.WriteLine(“验证失败:+ex.Message”);
}
控制台写入线(“已验证:+已验证);

你能帮我看看一些代码示例或参考资料吗?
Microsoft.IdentityModel.Tokens.JsonWebKey“to”System.IdentityModel.Tokens.SecurityKey“
是我尝试你的解决方案时遇到的错误!@HirenDesai-我无法在本地(.NET Core 3.1)或在线(.NET Core 5.0)上重现此错误:。这是整个错误消息吗?您使用的是什么.NET环境/版本?我使用的是
.NET Framework v4.8
Microsoft.IdentityModel.Tokens v5.3.0
System.IdentityModel.Tokens.Jwt v4.0.3.308261200
我正在处理Azure移动应用程序项目
Microsoft.Azure.Mobile.Server。身份验证取决于关于
System.IdentityModel.Tokens.Jwt(>4.0.3&&<5.0.0)
你应该从一开始就在问题中发布这些信息,特别是当涉及到这些旧版本时(当前版本的
System.IdentityModel.Tokens.Jwt
是v6.10.2)。在我的计算机上,代码在.NET Framework 4.8下可成功执行到
Microsoft.IdentityModel.Tokens v5.3.0
System.IdentityModel.Tokens.Jwt v5.0.0
。以下任何
System.IdentityModel.Tokens.Jwt v5.0.0
都无法编译(CS0246:…'JwtSecurityTokenHandler'。这可能在Azure下有所不同。这似乎是特定环境/配置的问题。