.Net Core API JWT 令牌验证

Posted

技术标签:

【中文标题】.Net Core API JWT 令牌验证【英文标题】:.Net Core API JWT Token Validation 【发布时间】:2021-06-27 15:59:44 【问题描述】:

在 .Net Core WEB API 中实现了 JWT Bearer Token 验证,如下所述:

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(opt =>
                
                    opt.Audience = Configuration["AAD:ResourceId"];
                    opt.Authority = $"Configuration["AAD:Instance"]Configuration["AAD:TenantId"]";
                );

怀疑上面提到的代码是否只会验证受众和权限?或者它将验证所有参数,如过期和签名等?

我们是否需要明确验证签名以检查有效负载是否被篡改?

【问题讨论】:

根据我的经验,它正在验证到期和签名,但文档不是那么清楚:JWT bearer authentication performs authentication by extracting and validating a JWT token from the Authorization request header. 【参考方案1】:

我想你正在寻找这个:

https://zhiliaxu.github.io/how-do-aspnet-core-services-validate-jwt-signature-signed-by-aad.html

这里zhiliaxu详细解释了使用.AddJwtBearer()时如何以及实际验证了什么,他的结论是:

现在很明显

在不提供任何密钥或证书的情况下验证 JWT 签名 在我们服务的源代码中。 JWT 签名密钥是从众所周知的 URL https://login.microsoftonline.com/common/discovery/keys 检索到的,基于 JwtBearerOptions.Authority 属性。 签名密钥缓存在 JwtBearerHandler 单例实例中,因此我们的 ASP.NET Core 服务只需要检索它 在其整个生命周期中一次。

同样基于这篇文章,我们可以看看 MSDN 上的ValidateToken() 文档:https://docs.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.jwt.jwtsecuritytokenhandler.validatetoken?view=azure-dotnet 在哪里可以找到方法抛出的不同异常:

SecurityTokenDecryptionFailedException:令牌是 JWE,无法解密。 SecurityTokenEncryptionKeyNotFoundException:令牌“kid”标头声明不为空且解密失败。 SecurityTokenException:令牌“enc”标头声明为 null 或为空。 SecurityTokenExpiredException:令牌“exp”声明为 SecurityTokenInvalidAudienceException:令牌“aud”声明与 ValidAudience 或 ValidAudience 之一不匹配。 SecurityTokenInvalidLifetimeException:令牌“nbf”声明是 >“exp”声明。 SecurityTokenInvalidSignatureException: token.signature 格式不正确。 SecurityTokenNoExpirationException:TokenReplayCache 不为 null 且 expireTime.HasValue 为 false。设置 TokenReplayCache 时,令牌需要过期时间。 SecurityTokenNotYetValidException:令牌 'nbf' 声明是 > DateTime.UtcNow。 SecurityTokenReplayAddFailedException:无法将令牌添加到 TokenReplayCache。 SecurityTokenReplayDetectedException:在缓存中找到令牌。

【讨论】:

调用 API 时出现以下错误:IDX10501:签名验证失败。无法匹配密钥:孩子:'IcMvbl6kv2ZKbug2Ip9MioeTw9A'。所以跟着提到的答案IDX10501:签名验证失败。无法匹配键但仍然得到相同的异常。请让我知道是否需要在 Azure 端进行配置。 似乎没有在 API 上正确设置权限。尝试导航到您的授权发现文档:https://yourauthority.com/.well-known/openid-configuration 您应该会看到一个 JSON 文档作为响应。在 JSON 文档中,您应该会看到 jwks_uri 属性,类似于 https://yourauthority.com/.well-known/openid-configuration/jwks。导航到该 URL,您将获得一个带有您的授权公钥的 json,查看 kid 属性,它应该与您的令牌上的匹配。将您的令牌输入jwt.io 网站以检查其内容并比较孩子(密钥 ID)。 BOL【参考方案2】:

默认情况下,它将验证发行者、受众和生命周期。 TokenValidationParameters 中有很多属性。如果您创建该类的新实例,您将看到哪些字段设置为真/假。或者,您可以将以下内容添加到您的代码、断点并自行调查。

.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
 ...
  options.TokenValidationParameters = new TokenValidationParameters
  
    ValidateIssuer = false,
    ValidateAudience = false, ...
  ; ..
 ...

NB authorityissuer 几乎是同一个概念。另外,请注意ValidIssuerValidateIssuer 之间的区别。

【讨论】:

以上是关于.Net Core API JWT 令牌验证的主要内容,如果未能解决你的问题,请参考以下文章

在 .net core api 中存储/验证存储在 HttpOnly cookie 中的 JWT 令牌

如何从.Net Core API 中的身份验证 JWT 令牌中获取身份用户?

Asp.Net Core API OpenId-Connect 身份验证与 JWT 令牌使用 IdentityModel

NET Core 3.1 MVC 授权/身份验证,带有在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT)

从 ASP.NET Core 中的 API 读取 JWT 令牌

.Net Core 自定义身份验证使用 API 密钥和 Identity Server 4