使用ASP.Net Core中的Authorize属性返回HTTP 403
当使用ASP.Net WebAPI时,我曾经拥有一个自定义的Authorize
属性,根据具体情况,我将使用它来返回HTTP 403
或401
。 例如,如果用户未被认证,则返回401
; 如果用户通过身份验证但没有适当的权限,则返回403
。 在这里看到更多的讨论。
现在看来,在新的ASP.Net Core中,他们不希望你重写Authorize
属性,而是偏向于基于策略的方法。 但是,似乎Core MVC遭遇了前所未有的“对于所有认证错误只返回401
”的方法。
我如何重写框架以获得我想要的行为?
我最终用中间件来完成它:
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;
}
}
}
}
应该在调用app.UseMvc()
之前在Startup.Configure
中注册。
在这里打开一个问题后,看起来这实际上应该工作......有点。
在你的Startup.Configure
,如果你只是调用app.UseMvc()
并且不注册任何其他中间件,那么你会得到401
任何与认证有关的错误(未认证,认证但没有许可)。
但是,如果您注册了支持该认证中间件的认证中间件之一,则您将正确获取401
未认证的认证中心件,并且无法获得403
的认证中间件。 对我而言,我使用JwtBearerMiddleware
,它允许通过JSON Web令牌进行身份验证。 关键部分是在创建中间件时设置AutomaticChallenge
选项:
在Startup.Configure
:
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
app.UseMvc();
AutomaticAuthenticate
将AutomaticAuthenticate
设置ClaimsPrincipal
以便您可以访问控制器中的User
。 AutomaticChallenge
挑战允许认证中间件在发生认证错误时修改响应(在这种情况下适当地设置401
或403
)。
如果您有自己的身份验证方案要实现,那么您将继承AuthenticationMiddleware
和AuthenticationHandler
类似于JWT实现的工作方式。
上一篇: Return HTTP 403 using Authorize attribute in ASP.Net Core