Asp.net web api JwtSecurityTokenHandler 4.0.0破坏性更改?

Asp.net web api JwtSecurityTokenHandler 4.0.0破坏性更改?,asp.net-web-api,oauth-2.0,jwt,Asp.net Web Api,Oauth 2.0,Jwt,这是Linqpad中JwtSecurityTokenHandler 4.0.0的简化测试。代码与JwtSecurityTokenHandler 3.0.2配合良好,生成并验证了令牌。在4.0.0中,经过必要的更改后,我不断获取SecurityTokenSignatureKeyNotFoundException:IDX10500:签名验证失败。无法解析SecurityKeyIdentifier。很明显,有些东西已经改变了,或者我做错了什么,新版本更严格了。有什么建议吗 string jwtIssu

这是Linqpad中JwtSecurityTokenHandler 4.0.0的简化测试。代码与JwtSecurityTokenHandler 3.0.2配合良好,生成并验证了令牌。在4.0.0中,经过必要的更改后,我不断获取SecurityTokenSignatureKeyNotFoundException:IDX10500:签名验证失败。无法解析SecurityKeyIdentifier。很明显,有些东西已经改变了,或者我做错了什么,新版本更严格了。有什么建议吗

string jwtIssuer = "issuer";
string jwtAudience = "audience";

X509Store store = new X509Store(StoreName.My,  StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = store.Certificates.OfType<X509Certificate2>().FirstOrDefault( c => c.SubjectName.Name.Equals("CN=DEV_CERT", StringComparison.OrdinalIgnoreCase));
store.Close();
// Token generation and signing
X509SigningCredentials signingCredentials = new X509SigningCredentials(cert);
JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
IList<System.Security.Claims.Claim> payloadClaims = new List<System.Security.Claims.Claim>() { 
    new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name , "name"), 
};

#if JWT302
    Lifetime lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddSeconds(24*60*60));
    JwtSecurityToken jwt = new JwtSecurityToken( jwtIssuer, jwtAudience, payloadClaims,  lifetime, signingCredentials);
#else
    JwtSecurityToken jwt = new JwtSecurityToken( jwtIssuer, jwtAudience, payloadClaims, DateTime.UtcNow, DateTime.UtcNow.AddSeconds(24*60*60), signingCredentials);
#endif

string token = jwtHandler.WriteToken(jwt); 

// Token validation
var signingToken = new RsaSecurityToken((RSACryptoServiceProvider)cert.PublicKey.Key);

JwtSecurityTokenHandler jwtHandler2 = new JwtSecurityTokenHandler();

#if JWT302
TokenValidationParameters vp = new TokenValidationParameters() {  
                                        AllowedAudience = jwtAudience, 
                                        ValidIssuer = jwtIssuer,
                                        ValidateIssuer = true
                                        ,SigningToken = signingToken 
                                        };

    var principal  = jwtHandler2.ValidateToken(token, vp);
#else
TokenValidationParameters vp = new TokenValidationParameters() { 
                                        ValidAudience = jwtAudience, 
                                        ValidIssuer = jwtIssuer,
                                        ValidateIssuer = true
                                        ,IssuerSigningToken = signingToken 
                                        };

    SecurityToken validatedToken;

    var principal  = jwtHandler2.ValidateToken(token, vp, out validatedToken);
#endif
string jwtIssuer=“issuer”;
string jwtAudience=“观众”;
X509Store=新的X509Store(StoreName.My,StoreLocation.LocalMachine);
打开(OpenFlags.ReadOnly);
X509Certificate2 cert=store.Certificates.OfType().FirstOrDefault(c=>c.SubjectName.Name.Equals(“CN=DEV_cert”,StringComparison.OrdinalIgnoreCase));
store.Close();
//令牌生成和签名
X509SigningCredentials signingCredentials=新的X509SigningCredentials(证书);
JwtSecurityTokenHandler jwtHandler=新的JwtSecurityTokenHandler();
IList payloadClaims=新列表(){
新系统.Security.Claims.Claims(System.Security.Claims.ClaimTypes.Name,“Name”),
};
#如果JWT302
生存期=新生存期(DateTime.UtcNow,DateTime.UtcNow.AddSeconds(24*60*60));
JwtSecurityToken jwt=新的JwtSecurityToken(jwtIssuer、jwtAudience、PayloadClaimes、lifetime、signingCredentials);
#否则
JwtSecurityToken jwt=新的JwtSecurityToken(jwtIssuer、jwtAudience、PayloadClaimes、DateTime.UtcNow、DateTime.UtcNow.AddSeconds(24*60*60),签名凭证);
#恩迪夫
字符串标记=jwtHandler.WriteToken(jwt);
//令牌验证
var signingToken=新的RsaSecurityToken((RSACryptServiceProvider)cert.PublicKey.Key);
JwtSecurityTokenHandler jwtHandler2=新的JwtSecurityTokenHandler();
#如果JWT302
TokenValidationParameters vp=新的TokenValidationParameters(){
AllowedAudience=jwtAudience,
ValidIssuer=jwtIssuer,
validateisuer=true
,SigningToken=SigningToken
};
var principal=jwtHandler2.ValidateToken(令牌,vp);
#否则
TokenValidationParameters vp=新的TokenValidationParameters(){
有效性=JWT观众,
ValidIssuer=jwtIssuer,
validateisuer=true
,IssuerSigningToken=signingToken
};
SecurityToken validatedToken;
var principal=jwtHandler2.ValidateToken(令牌、vp、out validatedToken);
#恩迪夫

很抱歉,您遇到问题。我们将更多地关注上面的内容,看看有什么可能是错误的。同时,我建议看一下global.asax.cs,尤其是global.asax.cs——这是我们对JWT处理程序进行原始使用的示例。 嗯
V.

在以下情况下引发此异常:

  • jwt有一个“孩子”
  • 运行时无法匹配任何签名令牌
  • 在我们调查该问题时,您可以使用委托令牌验证参数.issueSigningKeyResolver直接返回检查签名时使用的签名密钥

    要实现此设置,请将TokenValidationParameters.IssuerSigningkeyResolver设置为一个函数,该函数将返回您在TokenValidationParameters.SigningToken中设置的相同密钥。此委托的目的是指示运行时忽略任何“匹配”语义,只需尝试该键

    如果签名验证仍然失败,这可能是一个关键问题

    如果签名验证没有失败,运行时可能需要修复

    如果您能为我们提供使用该公钥签名的jwt,这将有助于我们进行修复


    感谢您让我们试一试,很抱歉给您带来麻烦。

    在回顾中,如果jwt中存在“kid”,新的匹配算法将不会验证签名。由于您使用X509签名,jwt中将出现x5t。这与RSA密钥不匹配。相反,请尝试添加X509SecurityKey或X509SecurityToken。我尝试添加一个kid,但没有效果。。将重复测试。我可以提供我正在使用的证书、令牌和代码(作为Linqpad脚本或控制台应用程序,请告诉我)。你可以通过gmail直接给我发电子邮件到rmbrunet。这是添加kidSecurityTokenSignatureKeyNotFoundException后的完全异常:IDX10500:签名验证失败。无法解析SecurityKeyIdentifier:“SecurityKeyIdentifier(IsReadOnly=False,Count=2,子句[0]=X509ThumbprintKeyIdentifierClause(哈希=0x6A780AF6E7838FF74783ACA9487DDB6433A98DD2),子句[1]=System.IdentityModel.Tokens.NamedKeyIdentifierClause)”,令牌:“{”类型“:“JWT”,“alg:“RS256”,“kid”:”:“6A780AF6E7838FF74783ACA9487DDB6433A98DD2”,“x5t:“angK9ueDj_dHg6ypSH3bZDOpjdI”{“唯一名称”:“名称”,“iss:“发行人”,“aud:“受众”,“exp:”1409757052,“nbf:”1409670652}使用X509SecurityKey而不是RSASSecurityToken(如您所建议的)验证通过。我打开了这个问题:我们将看一看。