【问题标题】:Custom JWT token validation in .NET Core 2.2.NET Core 2.2 中的自定义 JWT 令牌验证
【发布时间】:2022-03-26 02:41:50
【问题描述】:

我正在尝试使用自定义验证来验证 JWT 令牌。令牌是在我自己的 API 之外的另一个 API 中生成的,但我有办法根据服务验证它。

我不知道缺少什么...即使我的验证是正确的,我也会不断收到 401 代码。

编辑:添加了令牌验证参数并增加了令牌验证的精度

到目前为止,这是我的代码:

Startup.cs

services.AddAuthentication(options =>
            {
               var tokenValidationParameters = new TokenValidationParameters
               {
                   ValidateIssuer = false,
                   ValidateAudience = false,
                   ValidateIssuerSigningKey = false
               };

                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })//.AddCustomAuthenticationBearer();

                .AddJwtBearer(options =>
            {
                options.SecurityTokenValidators.Clear();
                options.SecurityTokenValidators.Add(new CustomJwtSecurityTokenHandler(_configuration));
                options.TokenValidationParameters = tokenValidationParameters;
                options.SaveToken = false;
                options.Events = new JwtBearerEvents
                {
                    OnTokenValidated = context =>
                    {
                        context.Success();
                        return Task.CompletedTask;
                    }
                };
            });

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //else
            //{
            //    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            //    app.UseHsts();
            //}

            //app.UseHttpsRedirection();
            app.UseAuthentication();
            app.UseMvc();

            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                foreach (var description in provider.ApiVersionDescriptions)
                {
                    options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                }
            });
        }

CustomJwtSecurityTokenHandler

public class CustomJwtSecurityTokenHandler : ISecurityTokenValidator
    {
        public bool CanValidateToken => true;
        public int MaximumTokenSizeInBytes { get; set; } = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;

        private readonly JwtSecurityTokenHandler _tokenHandler;
        private readonly string _fcAuthUrl;

        public CustomJwtSecurityTokenHandler(IConfiguration configuration)
        {
            _tokenHandler = new JwtSecurityTokenHandler();
            _fcAuthUrl = configuration["Authentication:BaseUri"];
        }

        public bool CanReadToken(string securityToken)
        {
            return _tokenHandler.CanReadToken(securityToken);
        }

        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters,
            out SecurityToken validatedToken)
        {
            var jwt = _tokenHandler.ReadJwtToken(securityToken);
            var accessToken = jwt.Claims.FirstOrDefault(c => c.Type == "auth_token")?.Value;

            if (accessToken == null)
            {
                validatedToken = null;
                return null;
            }

            var task = IsTokenValid(accessToken);
            task.Wait();
            if (task.Result)
            {
                validatedToken = new JsonWebToken(securityToken);
                return new ClaimsPrincipal();
            }

            validatedToken = null;
            return null;
        }

        private async Task<bool> IsTokenValid(string accessToken)
        {
            // My validation here
            // Simple http call to authentication service to validate token
        }
    }

这是我的一次通话记录:

2020-02-21 16:12:58.194 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Hosting.Internal.WebHost] [信息] 请求开始 HTTP/1.1 GET https://localhost:5001/api/notifications/translations

2020-02-21 16:12:58.458 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler] [信息] 成功验证令牌。

2020-02-21 16:12:58.485 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Routing.EndpointMiddleware] [信息] 执行端点 '"NotificationCenter.Api.Controllers.TranslationController.GetStandardTranslations ( NotificationCenter.API)"'

2020-02-21 16:12:58.522 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker] [信息] 与“{action = \"GetStandardTranslations\" 匹配的路由, 控制器 = \"翻译\"}"。在控制器“NotificationCenter.Api.Controllers.TranslationController”(“NotificationCenter.API”)上执行带有签名“System.Threading.Tasks.Task`1[NotificationCenter.BusinessLogic.DTOs.Responses.TranslationsResponseDTO] GetStandardTranslations()”的控制器操作。

2020-02-21 16:12:58.538 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Authorization.DefaultAuthorizationService] [信息] 授权失败。

2020-02-21 16:12:58.540 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker] [信息] 过滤器“Microsoft.AspNetCore”处的请求授权失败.Mvc.Authorization.AuthorizeFilter"'。

2020-02-21 16:12:58.547 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Mvc.ChallengeResult] [信息] 使用身份验证方案 ([]) 执行 ChallengeResult。

2020-02-21 16:12:58.557 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler] [信息] AuthenticationScheme:“Bearer”受到挑战。

2020-02-21 16:12:58.562 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker] [信息] 执行操作“NotificationCenter.Api.Controllers.TranslationController.GetStandardTranslations (NotificationCenter.API)”在 32.8311 毫秒内

2020-02-21 16:12:58.585 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Routing.EndpointMiddleware] [信息] 执行的端点'"NotificationCenter.Api.Controllers.TranslationController.GetStandardTranslations ( NotificationCenter.API)"'

2020-02-21 16:12:58.628 +01:00 [0HLTMS23C48IQ:00000001] [] [Microsoft.AspNetCore.Hosting.Internal.WebHost] [信息] 请求在 433.6413 毫秒 401 内完成

【问题讨论】:

  • 什么是tokenValidationParameters?这非常关键,您还删除了IsTokenValid 的内容,这似乎是相关的代码。
  • 你好,我添加了相关代码。 IsTokenValid 只是对我们的身份验证服务的 HTTP 调用。

标签: c# .net asp.net-core jwt customization


【解决方案1】:

尝试使用 _tokenHandler 验证它,而不是 new JsonWebToken,如下所示:

validatedToken = _tokenHandler.ReadJwtToken(securityToken);

【讨论】:

    猜你喜欢
    • 2020-01-20
    • 2021-06-27
    • 2019-12-03
    • 2017-10-26
    • 2017-01-03
    • 2020-04-04
    • 2019-12-22
    • 2019-12-24
    • 2020-08-22
    相关资源
    最近更新 更多