如何使ASP.NET Web API适当地响应403或401?

Art*_*dez 13 authentication rest authorization http asp.net-web-api

我正在使用ASP.NET Web API.我确实喜欢添加属性来指定API控制器的访问级别,如下所示:

[Authorize]
public IEnumerable<Activity> Get()
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都那么好,但是当我使用角色时,概念就会分崩离析

[Authorize(Roles = "Manager")]
public IEnumerable<Activity> Get()
Run Code Online (Sandbox Code Playgroud)

我的用户可能在一段时间之前登录到系统,然后在某些时候他们点击了一个"被禁止"的资源.尝试再次登录的用户没有任何意义.由于他们的合法帐户无权访问该URL.但目前他们获得401(未经授权)而不是403(被禁止),就像他们使用错误的帐户登录一样.但是用户只有一个帐户,用户不会要求拥有属于其他人的帐户.

还有其他人处理过这个问题吗?有谁知道如何解决这一问题?我非常愿意编写代码来解决这个问题,但我目前无法从哪里开始.

Cle*_*ud8 31

阅读Parv的建议,我创建了以下名为[WebApiAuthorize]的自定义过滤器.

关键是HandleUnauthorizedRequest()方法.当代码在此方法中执行时,这是因为用户"由于某种原因"未经授权....所以现在我们只确定"为什么"....然后:

  1. 调用默认行为的基本方法(返回401)....或....
  2. 用403返回我们自己的回复.

如您所见,它在适当时返回403(经过身份验证,但未经授权).

public class WebApiAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext ctx)
    {
        if (!ctx.RequestContext.Principal.Identity.IsAuthenticated)
            base.HandleUnauthorizedRequest(ctx);
        else
        {
            // Authenticated, but not AUTHORIZED.  Return 403 instead!
            ctx.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用,只需将自定义过滤器抛出控制器或这样的动作......

[WebApiAuthorize(Roles = "YourRoleA,YourRoleB")]
public class AdminController : ApiController
{
    public List<Admin> GetAdmins()
    {
        ...
    }
} 
Run Code Online (Sandbox Code Playgroud)


Par*_*rma 0

你能做的就是进行定制Authorize attribute,然后 AuthorizeCore处理OnAuthorizationFailed在后一种情况下,您可以发送您喜欢的任何响应

看看这里