C# 忽略JWT中的签名

C# 忽略JWT中的签名,c#,.net,x509certificate,jwt,C#,.net,X509certificate,Jwt,我有一个使用OpenId Connect的web应用程序。我创建了一个自签名证书,但它仍然没有被CA签名。 如何忽略签名验证 这就是我到目前为止所做的: SecurityToken validatedToken = null; var tokenHandler = new JwtSecurityTokenHandler { Configuration = new SecurityTokenHandlerConfiguration { CertificateValidat

我有一个使用OpenId Connect的web应用程序。我创建了一个自签名证书,但它仍然没有被CA签名。 如何忽略签名验证

这就是我到目前为止所做的:

SecurityToken validatedToken = null;

var tokenHandler = new JwtSecurityTokenHandler {
    Configuration = new SecurityTokenHandlerConfiguration {
        CertificateValidator = X509CertificateValidator.None
    },
};

TokenValidationParameters validationParams =
    new TokenValidationParameters()
    {
        ValidAudience = ConfigurationManager.AppSettings["Audience"],
        ValidIssuer = ConfigurationManager.AppSettings["Issuer"],
        AudienceValidator = AudienceValidator,
        ValidateAudience = true,
        ValidateIssuer = true
    };

return tokenHandler.ValidateToken(jwtToken, validationParams, out validatedToken);
它引发以下异常:

IDX10500:签名验证失败。无法解决 SecurityKeyIdentifier:'SecurityKeyIdentifier\r\n(\r\n
IsReadOnly=False\r\n Count=1\r\n子句[0]= System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause\r\n
)\r\n',\n请注意: “{\'typ\”:“JWT\”,“alg\”:“RS256\”,“kid\”:“iss\”:


不要忽略签名,这很危险!

即使使用自签名证书,也可以使用公钥进行签名验证

由于您使用的是OpenId Connect,您应该能够通过转到
/.well-known/jwks
获取签名证书的公钥

然后,您可以按如下方式设置验证参数:

var certificate = new X509Certificate2(Convert.FromBase64String(yourPublicKeyGoesHere));

var validationParameters = new TokenValidationParameters { 
    IssuerSigningTokens = new[] { new X509SecurityToken(certificate) }  
};
之后,您可以调用
ValidateToken

SecurityToken token;
var claimsPrincipal = handler.ValidateToken(encodedToken, validationParameters, out token);
确实要忽略签名吗?

请记住,如果您这样做,您如何知道有人没有篡改令牌内的数据?您可以轻松解码base64 url编码的负载并更改主题。如果您在应用程序中依赖于此,您将遇到麻烦(提示:有人访问其他人的数据

你真的真的想忽略它吗?

您可以使用
ReadToken
跳过所有验证:

var badJwt = new JwtSecurityTokenHandler()
                 .ReadToken(encodedMaliciousToken) as JwtSecurityToken;

但是不要这样做,这是一种不好的做法。

你明白了吗?是的,我明白了。它不应该检查签名,JWT为我们这样做,它不应该在客户端有身份提供者的私钥。因此不需要检查签名。以下更改包括一个解决方法-如果可能的话有帮助的话,我可以提供一个解释的答案detail@Bonomi,它不需要私钥进行验证,只需要从
jwks
端点获取公钥。为什么将
TokenValidationParameter.ValidateSuersuersigningKey
设置为false并不能绕过签名验证?@Veverke查看的源代码,它根本不支持
TokenValidationParameter.ValidateSuersigningKey
。就令牌验证而言,它似乎没有任何影响。。。。。
public TokenValidationParameters CreateTokenValidationParameters()
{
    var result = new TokenValidationParameters
    {
        ValidateIssuer = false,
        ValidIssuer = ValidIssuer,

        ValidateAudience = false,
        ValidAudience = ValidAudience,

        ValidateIssuerSigningKey = false,
        //IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)),
        //comment this and add this line to fool the validation logic
        SignatureValidator = delegate(string token, TokenValidationParameters parameters)
        {
            var jwt = new JwtSecurityToken(token);

            return jwt;
        },

        RequireExpirationTime = true,
        ValidateLifetime = true,

        ClockSkew = TimeSpan.Zero,
    };

    result.RequireSignedTokens = false;
    enter code here
    return result;
}