【问题标题】:ASP.NET MVC: Opposite of [Authorise]ASP.NET MVC:与[授权]相反
【发布时间】:2010-11-25 11:37:22
【问题描述】:

授权过滤器允许您指定可以访问控制器或操作的用户组:

[Authorize(Roles="Administrator")]
public class HomeController : Controller
{
    // code
}

我想知道是否可以改为指定一组无法访问控制器或操作的用户。

【问题讨论】:

  • 我无法想象从白名单实现切换到黑名单实现会有意义的场景。
  • 我不希望我的管理员访问与客户相关的控制器,但我显然需要未经授权的用户和客户才能访问。
  • 在很多情况下它是有意义的,并且大多数授权系统都包含对拒绝的支持。考虑一个场景,除了特定角色的成员之外,所有用户都有权做某事。

标签: asp.net-mvc authorization


【解决方案1】:

简单地限制类:

public class Restrict : AuthorizeAttribute
    {
        public string RestrictedRoles;

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {          
            if (!String.IsNullOrEmpty(RestrictedRoles))
            {
                var roles = RestrictedRoles.Split(',').Select(r => r.Trim());
                foreach (var role in roles)
                {
                    if (httpContext.User.IsInRole(role))
                        return false;
                }
            }

            return true;
        }
    }

用法

【讨论】:

  • 我想你忘记添加你的解决方案的用法和解释了:)
【解决方案2】:

基于ajbeaven's answer,我设法将其扩展到角色列表而不是一个角色。

首先是 Restrict 类:

public class Restrict : AuthorizeAttribute {
    private List<string> _roles;
    public string Roles {
        get {
            string roles = "";
            if (_roles != null && _roles.Count > 0) {
                int counter = 0;
                foreach (string role in _roles) {
                    counter++;
                    if (counter == _roles.Count) {
                        roles = role;
                    } else {
                        roles += role + ",";
                    }
                }
            }
            return roles;
        }
        set {
            _roles = new List<string>();
            string[] roles = value.Split(',');
            foreach (string role in roles) {
                _roles.Add(role);
            }
        }
    }

    public Restrict() {
        _roles = new List<string>();
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext) {
        bool result = true;
        if (httpContext == null) {
            throw new ArgumentNullException("httpContext");
        }
        foreach (string role in _roles) {
            if (httpContext.User.IsInRole(role)) {
                result = false;
                break;
            }
        }
        return result;
    }
}

然后添加 AppRoles 类,使整个解决方案可重用:

public static class AppRoles {
    public const string Role1 = "Role1";
    public const string Role2 = "Role2";
}

用法:

[Authorize]
[Restrict(Roles = AppRoles.Role1 + "," + AppRoles.Role2)]
    public ActionResult Index() {
    return View();
}

【讨论】:

    【解决方案3】:

    在 twk 的建议下,我尝试创建自己的 AuthorizationAttribute:

    public class Restrict : AuthorizeAttribute
    {
        private readonly string _role;
    
        public Restrict(string role)
        {
            _role = role;
        }
    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");
    
            if (httpContext.User.IsInRole(_role))
                return false;
    
            return true;
        }
    }
    

    我是这样使用它的:

    [Restrict("Administrator")]
    public class HomeController : Controller
    {
        // code
    }
    

    我不确定这是否是正确的做法,但它确实有效。

    【讨论】:

    • 您的 Restrict 属性是否一次接受多个角色?
    【解决方案4】:

    您应该准备自己的 ActionFilter 来实现这样的功能。 默认情况下,拒绝一切,但允许由授权操作过滤器定义(如您所知)。

    一些灵感可以找there

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-12
      • 2010-10-21
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多