C# 使用ASP.Net核心中的Authorize属性返回HTTP 403
在使用ASP.NETWebAPI时,我曾经有一个我将根据情况返回HTTPC# 使用ASP.Net核心中的Authorize属性返回HTTP 403,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,在使用ASP.NETWebAPI时,我曾经有一个我将根据情况返回HTTP403或401。e、 g.如果用户未通过身份验证,则返回401;如果用户已通过身份验证,但没有相应的权限,请返回403。在那上面 现在看来,在新的ASP.Net核心中,他们不再支持基于策略的方法。然而,核心MVC似乎受到了与它的前辈相同的“针对所有身份验证错误只返回401”方法的影响 如何覆盖框架以获得所需的行为?我最终使用中间件实现了这一点: public class AuthorizeCorrectlyMiddlewar
403
或401
。e、 g.如果用户未通过身份验证,则返回401
;如果用户已通过身份验证,但没有相应的权限,请返回403
。在那上面
现在看来,在新的ASP.Net核心中,他们不再支持基于策略的方法。然而,核心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()之前配置,
,在打开一个后,它看起来实际上应该可以工作…某种程度上
在您的启动.Configure
中,如果您只调用app.UseMvc()
而不注册任何其他中间件,您将获得401
中与身份验证相关的任何错误(未经身份验证、已验证但无权限)
但是,如果您注册了一个支持它的身份验证中间件,则未经身份验证的将正确获得401
,无权限的将正确获得403
。对我来说,我使用了jwtbearermiddle软件
,它允许通过身份验证。关键部分是在创建中间件时设置自动挑战
选项:
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.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
app.UseMvc();
AutomaticAuthenticate
将自动设置ClaimsPrincipal
,以便您可以在控制器中访问User
AutomaticChallenge
允许身份验证中间件在发生身份验证错误时修改响应(在这种情况下,适当设置401
或403
)
如果您有自己的身份验证方案要实现,那么您将继承AuthenticationMiddleware
和AuthenticationHandler
,类似于。这是我要建议的,但不确定如何仅将其应用于某些控制器/操作,就像使用属性一样。这是危险的,因为在使用next(上下文)调用next middleware/delegate后写入HttpResponse(在本例中通过设置statuscode)如果管道中的其他中间件已经开始写入响应,则将引发异常。忘记提及…。在修改状态码之前,至少应检查context.response.HasStarted==false。根据@blowdart,如果MVC6 Authorize属性在用户经过身份验证但未经授权的情况下仍然返回401而不是403,那么要么是应该提交的错误,要么是您做错了什么。我只是根据设计假设,无论在何种情况下,它都返回401。如果这种行为不是预期的,我将在aspnet/security中提交一个bug。请参阅此处的最后一条评论:我没有使用JWTBeareAuthentication,而是使用cookie auth。设置AutomaticChallenge=true会在授权失败时自动重定向。我不想重定向,但403的。从我在文档中看到的情况来看,这是不可能的。Cookie auth是webforms时代带有“FormsAuthentication”的默认设置。我认为这种行为是模仿这种行为的。e、 g.如果某人未通过身份验证,您希望将其重定向到登录页面,之后将使用其身份验证令牌设置cookie。如果您想要cookieauth和JWT的行为,您可能需要使用AuthenticationMiddleware
和AuthenticationHandler
实现自定义身份验证方案。为我解决了一个大问题。谢谢我们如何在Identity Core 2中使用它?那里没有这样的选择