.Net Core API JWT 令牌验证

.Net Core API JWT Token Validation

在 .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"]}";
                });

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

我们是否需要显式验证签名以检查负载是否已被篡改?

我想你正在寻找这个:

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

这里 zhiliaxu 详细解释了使用 .AddJwtBearer() 时实际验证的方式和内容,他的结论是:

Now it is clear that

  • JWT signature is validated without providing any key or certification in our service’s source code.
  • JWT signing key is retrieved from the well-known URL https://login.microsoftonline.com/common/discovery/keys, based on JwtBearerOptions.Authority property.
  • The signing key is cached in the JwtBearerHandler singleton instance, and so our ASP.NET Core service only needs to retrieve it once throughout its lifecycle.

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

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

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

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

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