使用ASP.Net WebAPI时,我曾经使用custom Authorize
attribute我会根据具体情况返回HTTP 403
或401
。例如如果用户未经过身份验证,请返回401
;如果用户已通过身份验证但没有相应的权限,请返回403
。 See here for more discussion就此而言。
现在看来,在新的ASP.Net Core中,他们don't want you overriding the Authorize
attribute不再支持基于策略的方法了。但是,似乎Core MVC遭受了同样的错误,只需返回401
所有auth错误"接近它的前辈们。
如何覆盖框架以获得我想要的行为?
答案 0 :(得分:8)
我最终用中间件做了:
public class AuthorizeCorrectlyMiddleware
{
readonly RequestDelegate next;
public AuthorizeCorrectlyMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
await next(context);
if (context.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
if (context.User.Identity.IsAuthenticated)
{
//the user is authenticated, yet we are returning a 401
//let's return a 403 instead
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
}
}
}
}
应在Startup.Configure
之前在app.UseMvc()
注册。
答案 1 :(得分:8)
打开issue here后,看起来这实际上应该有效...等等。
在您的Startup.Configure
中,如果您只是致电app.UseMvc()
并且未注册任何其他中间件,则您将获得401
任何与身份验证相关的错误(未经过身份验证,已通过身份验证但未注册权限)。
但是,如果您注册了一个支持它的身份验证中间件,那么您将正确获得401
未经身份验证,403
无权限。对我来说,我使用了允许通过JSON Web Token进行身份验证的JwtBearerMiddleware
。关键部分是在创建中间件时设置AutomaticChallenge
选项:
Startup.Configure
中的:
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
app.UseMvc();
AutomaticAuthenticate
会自动设置ClaimsPrincipal
,以便您可以在控制器中访问User
。 AutomaticChallenge
允许auth中间件在发生auth错误时修改响应(在这种情况下,适当地设置401
或403
)。
如果您要实施自己的身份验证方案,则会继承AuthenticationMiddleware
和AuthenticationHandler
,类似于JWT implementation works。