JWT 不会过期
JWT does not expire
我正在使用 Identity Server 4 进行身份验证并使用 efCore 生成 JWT,我有一个 API 和一个应该检索数据列表的获取请求,所以当我 "login" 使用 Postman,如果我再次登录并使用第一个令牌获取请求 returns 401 和数据列表,则会生成一个令牌,尽管我对该特定操作有一个 AllowAnonymous,但有人知道这种行为的原因吗
获取端点
[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";
});
我认为这里发生的事情是 AuthorizationMiddleware (added to the pipeline in your 'UseAuthorization' call) 在它到达您的控制器之前将响应的状态代码设置为 401。
如果您使用 MVC 进行路由,授权将由 AuthorizationFilter retrieved from your route.If you're using endpoint routing, which seems more likely since you mentioned that this was an api, the 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 配置和配置中使用的值。
此 ASP.NET 核心身份验证请求在使用 AllowAnonymous 的路由上的行为也在此处讨论以获取更多上下文:https://github.com/aspnet/Security/issues/1577
我正在使用 Identity Server 4 进行身份验证并使用 efCore 生成 JWT,我有一个 API 和一个应该检索数据列表的获取请求,所以当我 "login" 使用 Postman,如果我再次登录并使用第一个令牌获取请求 returns 401 和数据列表,则会生成一个令牌,尽管我对该特定操作有一个 AllowAnonymous,但有人知道这种行为的原因吗
获取端点
[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";
});
我认为这里发生的事情是 AuthorizationMiddleware (added to the pipeline in your 'UseAuthorization' call) 在它到达您的控制器之前将响应的状态代码设置为 401。
如果您使用 MVC 进行路由,授权将由 AuthorizationFilter retrieved from your route.If you're using endpoint routing, which seems more likely since you mentioned that this was an api, the 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 配置和配置中使用的值。
此 ASP.NET 核心身份验证请求在使用 AllowAnonymous 的路由上的行为也在此处讨论以获取更多上下文:https://github.com/aspnet/Security/issues/1577