Identityserver4 Identity server 4:拦截302并将其替换为401
我有一个应用程序,它同时托管Identity Server 4和一个客户端应用程序(Vue),它使用一个区域中定义的两个rest服务来管理站点。其思想是,与特定角色关联的用户可以访问客户端应用程序并调用rest服务来执行操作 目前,我的问题是,当用户不属于管理员角色时,api返回302。我想把它改成401,但我遇到了一些问题 如果这是一个简单的aspnet核心应用程序,那么我只需将lambda传递给负责请求的cookie处理程序的Identityserver4 Identity server 4:拦截302并将其替换为401,identityserver4,Identityserver4,我有一个应用程序,它同时托管Identity Server 4和一个客户端应用程序(Vue),它使用一个区域中定义的两个rest服务来管理站点。其思想是,与特定角色关联的用户可以访问客户端应用程序并调用rest服务来执行操作 目前,我的问题是,当用户不属于管理员角色时,api返回302。我想把它改成401,但我遇到了一些问题 如果这是一个简单的aspnet核心应用程序,那么我只需将lambda传递给负责请求的cookie处理程序的OnRedirectToLogin属性。不幸的是,IS4只允许我设
OnRedirectToLogin
属性。不幸的是,IS4只允许我设置cookie的一些基本设置(过期和滑动)。同样,我可以重写cookie处理程序。因此,我尝试了以下几点:
services.AddIdentityServer()
... // other configurations
services.AddAuthentication(sharedOptions => {
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;//IdentityServerConstants.ExternalCookieAuthenticationScheme;
sharedOptions.DefaultChallengeScheme = IdentityServerConstants.SignoutScheme;
})
... //other external providers...
.AddCookie( CookieAuthenticationDefaults.AuthenticationScheme, options => {
options.Events = new CookieAuthenticationEvents {
OnRedirectToLogin = ctx => {
if (ctx.Request.Path.StartsWithSegments("/Admin", StringComparison.OrdinalIgnoreCase)) {
ctx.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
}
return Task.CompletedTask;
};
});
我希望每当请求被重定向到登录页面时,我的处理程序都会被调用,但这种情况从未发生过。有人能帮忙吗
谢谢
编辑:只需补充一点,我也在使用aspnet identity来管理用户帐户…不久前,我为这个目的编写了一个中间件,从未回头看,因此如果您没有找到更好的解决方案,也许该解决方案也可以帮助您:
public class RedirectHandlingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RedirectHandlingMiddleware> _logger;
public RedirectHandlingMiddleware(RequestDelegate next, ILogger<RedirectHandlingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
await HandleRedirect(context, ex);
await _next(context);
}
private Task HandleRedirect(HttpContext context)
{
if (context.Request.Path.StartsWithSegments("/Admin", StringComparison.OrdinalIgnoreCase) && context.Response.StatusCode == 302)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
return Task.CompletedTask;
}
}
公共类重定向处理中间件
{
private readonly RequestDelegate\u next;
专用只读ILogger\u记录器;
公共重定向处理中间件(RequestDelegate next,ILogger logger)
{
_下一个=下一个;
_记录器=记录器;
}
公共异步任务调用(HttpContext上下文)
{
wait HandleRedirect(上下文,ex);
等待下一步(上下文);
}
私有任务HandleRedirect(HttpContext上下文)
{
if(context.Request.Path.StartsWithSegments(“/Admin”,StringComparison.ordinallingorecase)和&context.Response.StatusCode==302)
{
context.Response.StatusCode=(int)HttpStatusCode.Unauthorized;
}
返回Task.CompletedTask;
}
}
只需在Startup.cs中注册:
app.UseAuthentication();
app.UseMiddleware<RedirectHandlingMiddleware>();
app.UseAuthentication();
app.UseMiddleware();
在此处发布答案,以防有人感兴趣
经过一些挖掘,我发现使用identity意味着你不能像我那样定制cookie处理程序。幸运的是,可以由configureApplicationOkie
扩展方法配置的ConfigureAuthenticationEvent
已经做了正确的事情:如果它检测到当前请求是AJAX调用,它将返回401;如果不是,它将返回302。问题是:vue客户端发出的请求没有被视为AJAX请求,因为它没有将X-request-With
头设置为XMLHttpRequest
因此,只需将axios配置为在所有调用中设置标头:
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
你好我尝试在UseIdentityServer调用后注册中间件,但它不起作用…@LuisAbreu实际上我给你的代码不正确,永远不会起作用,请尝试新代码。