繁体   English   中英

角色/用户的ASP.NET MVC黑名单

[英]ASP.NET MVC Blacklist for Roles/Users

问题摘要:在ASP.NET MVC中,是否存在防止特定用户或角色访问操作的干净方法?

显然,以下内容将允许角色AdminEditor访问整个控制器。

[Authorize(Roles = "Admin, Editor")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

如果我只希望Admin角色有权访问“ About操作,则可以执行以下操作:

[Authorize(Roles = "Admin, Editor")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [Authorize(Roles = "Admin")] // this will take precedence over the controller's authorization
    public ActionResult About()
    {
        return View();
    }
}

有没有一种方法可以做到这一点而无需列出需要访问的每个角色,而仅指定应该阻止其访问的角色?

这是我用来解决此问题的类的代码。 它从AuthorizeAttribute派生而来,并将允许任何通过身份验证的用户通过与参数设置的规范匹配的用户。

(请注意,重要的方法是AuthorizeCore其他所有内容基本上都是从AuthorizeAttribute复制或继承的)

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class BlackListAttribute : AuthorizeAttribute
{
    private static readonly string[] _emptyArray = new string[0];

    private string _roles;
    private string _users;

    private string[] _rolesSplit = _emptyArray;
    private string[] _usersSplit = _emptyArray;

    public new string Roles
    {
        get { return _roles ?? String.Empty; }
        set
        {
            _roles = value;
            _rolesSplit = SplitString(value);
        }
    }

    public new string Users
    {
        get { return _users ?? String.Empty; }
        set
        {
            _users = value;
            _usersSplit = SplitString(value);
        }
    }
    // This is the important part. Everything else is either inherited from AuthorizeAttribute or, in the case of private or internal members, copied from AuthorizeAttribute.
    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        IPrincipal user = httpContext.User;

        if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
        {
            return false;
        }

        if (_usersSplit.Length > 0 && _usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
        {
            return false;
        }

        if (_rolesSplit.Length > 0 && _rolesSplit.Any(user.IsInRole))
        {
            return false;
        }

        return true;
    }

    internal static string[] SplitString(string original)
    {
        if (String.IsNullOrEmpty(original))
        {
            return _emptyArray;
        }

        var split = from piece in original.Split(',')
                    let trimmed = piece.Trim()
                    where !String.IsNullOrEmpty(trimmed)
                    select trimmed;
        return split.ToArray();
    }
}

您可以在控制器或其他类似AuthorizeAttribute操作上使用它:

[Authorize(Roles = "Admin, Editor")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
    [BlackList(Roles = "Editor")]
    public ActionResult About()
    {
        return View();
    }
}

像这样创建自己的黑名单类:

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

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

现在,您将阻止所需的角色:

[Authorize]
[Blacklist (Roles = "Admin", "Editor")]
    public ActionResult Index() {
    return View();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM