【问题标题】:Default Authorization role at Controller level and override at method控制器级别的默认授权角色和方法上的覆盖
【发布时间】:2013-05-07 23:19:38
【问题描述】:

我正在尝试设置对控制器上方法的默认访问权限,因此我在ApiController 上添加了[Authorize] 属性。

在大多数情况下,除非被 [AllowAnonymous] 属性覆盖,否则它可以正常工作。

现在我想在组合中添加另一个级别。对于我的默认授权方法,我希望它们需要特定的角色(例如管理员),因此我将控制器级别属性更新为[Authorize(roles="admin")]。对于少数例外,我不在乎他们是什么角色(只要经过身份验证就足够了)。

我认为我可以坚持在控制器级别设置 Authorize 属性并在单个方法级别覆盖它,但这似乎与[AllowAnonymous] 的工作方式不同。

对于如何在不必记住使用默认访问级别装饰每个新方法的情况下进行此操作有什么建议吗?像[Authorize(roles="*")] 这样的东西?即使我需要一个默认角色,每个用户都是AuthenticatedUsers的一部分,那也没问题。

【问题讨论】:

    标签: c# asp.net-mvc controller asp.net-web-api authorization


    【解决方案1】:

    创建一个标记属性怎么样? AllowAnonymous 就是这样一个标记,顺便说一句。当标记存在时,创建您自己的 Authorize 属性并清除角色。

    [MyAuth(Roles = "admin")]
    public class ValuesController : ApiController
    {
        [ExemptRoles]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
    }
    
    public class ExemptRolesAttribute : Attribute { }
    
    public class MyAuthAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (actionContext.ActionDescriptor.GetCustomAttributes<ExemptRolesAttribute>().Any())
                base.Roles = String.Empty;
    
            base.OnAuthorization(actionContext);
        }
    }
    

    【讨论】:

      【解决方案2】:

      这基本上就是我正在做的事情。我创建了一个自定义 AuthorizeAttribute 并覆盖了 OnAuthorization 方法。

      然后我可以检查用户是否是当前自定义属性中标记的任何角色。
      如果没有,我会退回到默认的授权处理。

      public class InternalAuthorizeAttribute : AuthorizeAttribute
      {
          public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
          {
              if(actionContext == null)
                  throw new ArgumentNullException("actionContext");
              if (AuthorizeRequest(actionContext))
                  return;
      
              // no special authorization found. fall back to base (handles AllowAnonymous, and Controller level attribute)
              base.OnAuthorization(actionContext);
          }
      
      
          private bool AuthorizeRequest(HttpActionContext actionContext)
          {
              if (!actionContext.ActionDescriptor.GetCustomAttributes<InternalAuthorizeAttribute>().Any())
                  return false;
      
              foreach (AuthorizeAttribute attribute in actionContext.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>())
              {
                  foreach (var role in attribute.Roles.Split(','))
                  {
                      if (HttpContext.Current.User.IsInRole(role)) return true;
                  }
              }
              return false;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-01-09
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 2013-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-04
        相关资源
        最近更新 更多