Asp.net WebApi 中的自定义授权 - 真是一团糟? [英] Custom Authorization in Asp.net WebApi - what a mess?

查看:29
本文介绍了Asp.net WebApi 中的自定义授权 - 真是一团糟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一些关于 WebApi 授权的资源(书籍和 SO 答案).

假设我想添加仅允许某些用户访问的自定义属性:

案例#1

我见过这种覆盖 OnAuthorization 的方法,它在出现问题时设置响应

 公共类 AllowOnlyCertainUsers : AuthorizeAttribute{公共覆盖无效 OnAuthorization(HttpActionContext actionContext){if (/*检查用户是否正常*/){actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);}}}

案例#2

但我也看到了这个类似的例子,它也覆盖了 OnAuthorization 但调用了 base :

public override void OnAuthorization(HttpActionContext actionContext){base.OnAuthorization(actionContext);//如果根本没有授权,不要打扰如果(actionContext.Response == null){//...}}

然后,您检查HttpActionContext.Response 是否设置.如果没有设置,则表示请求已授权,用户没问题

案例#3

但我也见过这种覆盖 IsAuthorized 的方法:

 公共类 AllowOnlyCertainUsers : AuthorizeAttribute{protected override bool IsAuthorized(HttpActionContext context){if (/*检查用户是否正常*/){返回真;//或假}}}

案例 #4

然后我看到了一个类似的例子,但调用了 base.IsAuthorized(context) :

protected override bool IsAuthorized(HttpActionContext context){if (something1 && something2 && base.IsAuthorized(context))//??返回真;返回假;}

还有一件事

最后多米尼克在.免责声明:这是我写的.

I'm reading from several resources (books and SO answers) about authorization in WebApi.

Suppose I want to add Custom Attribute which allows access only for Certain Users:

Case #1

I've seen this approach of overriding OnAuthorization , which sets response if something is wrong

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 public override void OnAuthorization(HttpActionContext actionContext)
  {
   if ( /*check if user OK or not*/)
   {
     actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
   }
  }
}

Case #2

But I've also seen this similar example which also overriding OnAuthorization but with calling to base :

public override void OnAuthorization(HttpActionContext actionContext) 
{ 
  base.OnAuthorization(actionContext);

    // If not authorized at all, don't bother

    if (actionContext.Response == null)  
     {
      //...
     }
}

Then, you check if the HttpActionContext.Response is set or not. If it’s not set, it means that the request is authorized and the user is ok

Case #3

But I've also seen this approach of overriding IsAuthorized :

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 protected override bool IsAuthorized(HttpActionContext context)
  {
   if ( /*check if user OK or not*/)
   {
    return true;// or false
   }
  }
}

Case #4

And then I saw similar example one but with calling base.IsAuthorized(context) :

protected override bool IsAuthorized(HttpActionContext context)
{
 if (something1 && something2 && base.IsAuthorized(context)) //??
 return true;
 return false;
}

One more thing

And finally Dominick said here :

You shouldn't override OnAuthorization - because you would be missing [AllowAnonymous] handling.

Questions

  • 1) Which methods should I use : IsAuthorized or OnAuthorization ? ( or when to use which)

  • 2) when should I call base.IsAuthorized or base.OnAuthorization` ?

  • 3) Is this how they built it ? that if the response is null then everything is ok ? ( case #2)

NB

Please notice , I'm using ( and want to use ) only AuthorizeAttribute which already inherits from AuthorizationFilterAttribute

Why ?

Becuase I'm at the first stage in : http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

Anyway Im asking via extending Authorize attribute .

解决方案

Which methods should I use : IsAuthorized or OnAuthorization ? ( or when to use which)

You will extend AuthorizationFilterAttribute if your authorization logic is not dependent on the identity established and roles. For user related authorization, you will extend and use AuthorizeAttribute. For the former case, you will override OnAuthorization. For the latter case, you will override IsAuthorized. As you could see from the source code of these attributes, OnAuthorization is marked virtual for you to override if you derive from AuthorizationFilterAttribute. On the other hand, the IsAuthorized method is marked virtual in AuthorizeAttribute. I believe this is a good pointer to the intended usage.

when should I call base.IsAuthorized or base.OnAuthorization?

The answer to this question lies in how OO generally works. If you override a method, you can either completely provide a new implementation or piggy back on the implementation provided by parent and enhance the behavior. For example, take the case of IsAuthorized(HttpActionContext). The base class behavior is to check the user/role against what is specified in the filter vs the identity established. Say, you want to do all that but in addition, you want to check something else, may be based on a request header or something. In that case, you can provide an override like this.

protected override bool IsAuthorized(HttpActionContext actionContext)
{
    bool isAuthroized = base.IsAuthorized(actionContext);
    // Here you look at the header and do your additional stuff based on actionContext
    // and store the result in isRequestHeaderOk
    // Then, you can combine the results
    // return isAuthorized && isRequestHeaderOk;
}

I'm sorry but don't understand your Q3. BTW, Authorization filter has been around for a long time and people use it for all kinds of things and sometimes incorrectly as well.

One more thing. And finally there was this guy here who said : You shouldn't override OnAuthorization - because you would be missing [AllowAnonymous] handling.

The guy who said that is the God of access control - Dominick. Obviously it will be correct. If you look at the implementation of OnAuthorization (copied below),

public override void OnAuthorization(HttpActionContext actionContext)
{
    if (actionContext == null)
    {
        throw Error.ArgumentNull("actionContext");
    }

    if (SkipAuthorization(actionContext))
    {
        return;
    }

    if (!IsAuthorized(actionContext))
    {
        HandleUnauthorizedRequest(actionContext);
    }
}

the call to SkipAuthorization is the part that ensures AllowAnonymous filters are applied, that is, authorization is skipped. If you override this method, you loose that behavior. Actually, if you decide to base your authorization on users/roles, at that point you would have decided to derive from AuthorizeAttribute. Only correct option left for you at that point will be to override IsAuthorized and not the already overridden OnAuthorization, although it is technically possible to do either.

PS. In ASP.NET Web API, there is another filter called authentication filter. Idea is that you use that for authentication and authorization filter for authorization, as the name indicates. However, there are lots of examples where this boundary is fudged. Lots of authroization filter examples will do some kind of authentication. Anyways, if you have time and want to understand a bit more, take a look at this MSDN article. Disclaimer: It was written by me.

这篇关于Asp.net WebApi 中的自定义授权 - 真是一团糟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆