JWT不会过期

问题描述 投票:0回答:1

我正在使用Identity Server 4进行身份验证并通过efCore生成JWT,我有一个API和一个应该检索数据列表的get请求,因此当我使用邮递员“登录”时,如果我生成了令牌,再次登录并使用第一个令牌,尽管我对该特定操作具有AllowAnonymous,但get请求返回401和数据列表,有人知道这种行为的原因吗

获取端点

[HttpGet]
        [AllowAnonymous]
        public override Task<ActionResult<List<DataVM>>> Get()
        {
            return base.Get();
        }

CRUD骨架

[HttpGet]
        public virtual async Task<ActionResult<List<TValueModel>>> Get()
        {
            var userClaim = User.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject);
            List<TValueModel> records;
            if (userClaim != null)
            {
                records = await Mediator.Send(new GetAll<TModel, TValueModel>
                {
                    UserId = Guid.Parse(userClaim.Value)
                });
                return records;
            }
            records = await Mediator.Send(new GetAll<TModel, TValueModel>());
            return records;
        }

启动

services.AddIdentity<User, Role>(options =>
                {
                    options.User.RequireUniqueEmail = true;


                })
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.Configure<SecurityStampValidatorOptions>(options => options.ValidationInterval = TimeSpan.FromSeconds(10));

            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;

            })
                .AddInMemoryIdentityResources(IdentityConfig.Ids)
                .AddInMemoryApiResources(IdentityConfig.Apis)
                .AddInMemoryClients(IdentityConfig.Clients)
                .AddAspNetIdentity<User>();


            builder.AddDeveloperSigningCredential();

            services.AddTransient<IProfileService, ProfileService>();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
                options.DefaultForbidScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
            })
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = Configuration.GetValue<string>("Host");
                options.RequireHttpsMetadata = false;
                options.JwtBearerEvents.OnAuthenticationFailed =
                    C =>
                    {
                        C.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        return Task.CompletedTask;
                    };
                options.ApiName = "api1";
            });
jwt identityserver4 jwt-auth ef-core-3.0
1个回答
1
投票

我认为这里发生的事情是AuthorizationMiddleware(added to the pipeline in your 'UseAuthorization' call)甚至在未命中控制器之前就将响应的状态代码设置为401。

[如果您使用MVC进行路由,则将通过从路由中检索的AuthorizationFilter执行授权。如果您使用的是端点路由,由于您提到这是一个api,因此AuthorizationMiddleware处理的可能性更大路由的授权(通过UseAuthorization调用添加到管道中)。

AuthorizeFilter和AuthorizationMiddleware都具有用于授权的镜像逻辑,无论最终使用哪种逻辑,其行为极有可能是相同的。

假设您在控制器上设置了Authorize属性或配置了其他一些授权数据,那么授权逻辑中的问题区域就是执行身份验证的AuthorizationMiddleware中的一部分。发生before the AllowAnonymous attribute is even searched for on the route。即使路由用AllowAnonymous属性标记,这也会导致应用任何与身份验证相关的失败。

由于已为身份验证方案配置了以下内容:

options.JwtBearerEvents.OnAuthenticationFailed =
    C =>
    {
        C.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };

当JwtBearer身份验证方案尝试基于令牌对用户进行身份验证时,似乎身份验证失败,并导致根据上面配置的OnAuthenticationFailed事件将状态代码设置为401。但是,此身份验证失败不会使请求失败,并且Web应用程序仍然能够执行端点操作,从而导致返回列表和未授权状态代码。

关于令牌为什么未通过身份验证的另一个问题,这需要进一步调查您的IdentityServer配置以及配置中使用的值。

这里还通过其他上下文讨论了使用AllowAnonymous对路由上的请求进行身份验证的ASP.NET Core的这种行为:https://github.com/aspnet/Security/issues/1577

© www.soinside.com 2019 - 2024. All rights reserved.