簡體   English   中英

ASP.Net Identity Check以獲取多個角色以獲得訪問權限

[英]ASP.Net Identity Check for multiple roles to get access

是否有可能在授予訪問權限之前獲得asp.net身份要求2個角色的成員身份?

我的系統中有2層權限。 首先是允許訪問某些功能的公司類型,其次是限制特定方法和使用權的公司類型。

CompanyType= Host,Expert,Manufacturer,Supplier,Consultant
Accesslevel= Admin,ReadOnly,ReadWrite

我希望能夠做這樣的事情:

[Authorize(Roles = "Expert && ReadWrite || ReadOnly")]

目標是擁有一種同時處理這兩種角色的方式:

HostAdmin, HostReadOnly, HostReadWrite, ExpertAdmin ....

謝謝你的時間。

是的,您可以要求多個角色,只需添加更多授權屬性即可:

[Authorize(Roles="members")]
[Authorize(Roles="admin")]

這將要求用戶同時具有成員和管理員角色

有關更多詳細信息-> 允許多個角色訪問控制器操作

我創建了一個自定義過濾器屬性來滿足您的需求。 我做了一些簡化:我將&&更改為&|| | 解析器還支持xor ^ ,不支持! 和括號

[CustomAuthorize(Roles = "Expert & (ReadWrite | ReadOnly)")]

這是自定義授權屬性

/// <summary>
/// [CustomAuthorize(Roles = "A & (!B | C) ^ D")]
/// </summary>
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    /*
     *  Exp -> SubExp '&' SubExp // AND
     *  Exp -> SubExp '|' SubExp // OR
     *  Exp -> SubExp '^' SubExp // XOR
     *  SubExp -> '(' Exp ')'
     *  SubExp -> '!' Exp        // NOT
     *  SubExp -> RoleName
     *  RoleName -> [a-z]
     */

    private const char TokenSeparator = ' ';
    private const char TokenAnd = '&';
    private const char TokenOr = '|';
    private const char TokenXor = '^';
    private const char TokenNot = '!';
    private const char TokenParentheseOpen = '(';
    private const char TokenParentheseClose = ')';

    abstract class Node
    {
        public abstract bool Eval(IPrincipal principal);
    }

    abstract class UnaryNode : Node
    {
        private readonly Node _expression;

        public Node Expression
        {
            get { return _expression; }
        }

        protected UnaryNode(Node expression)
        {
            _expression = expression;
        }
    }

    abstract class BinaryNode : Node
    {
        private readonly Node _leftExpression;
        private readonly Node _rightExpression;

        public Node LeftExpression
        {
            get { return _leftExpression; }
        }

        public Node RightExpression
        {
            get { return _rightExpression; }
        }

        protected BinaryNode(Node leftExpression, Node rightExpression)
        {
            _leftExpression = leftExpression;
            _rightExpression = rightExpression;
        }
    }

    class AndNode : BinaryNode
    {
        public AndNode(Node leftExpression, Node rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override bool Eval(IPrincipal principal)
        {
            return LeftExpression.Eval(principal) && RightExpression.Eval(principal);
        }
    }

    class OrNode : BinaryNode
    {
        public OrNode(Node leftExpression, Node rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override bool Eval(IPrincipal principal)
        {
            return LeftExpression.Eval(principal) || RightExpression.Eval(principal);
        }
    }

    class XorNode : BinaryNode
    {
        public XorNode(Node leftExpression, Node rightExpression)
            : base(leftExpression, rightExpression)
        {
        }

        public override bool Eval(IPrincipal principal)
        {
            return LeftExpression.Eval(principal) ^ RightExpression.Eval(principal);
        }
    }

    class NotNode : UnaryNode
    {
        public NotNode(Node expression)
            : base(expression)
        {
        }

        public override bool Eval(IPrincipal principal)
        {
            return !Expression.Eval(principal);
        }
    }

    class RoleNode : Node
    {
        private readonly string _roleName;

        public string RoleName
        {
            get { return _roleName; }
        }

        public RoleNode(string roleName)
        {
            _roleName = roleName;
        }

        public override bool Eval(IPrincipal principal)
        {
            return principal.IsInRole(RoleName);
        }
    }

    private Node _expression;

    void Parse(string text)
    {
        if (text == null) throw new ArgumentNullException("text");

        var delimiters = new[] { TokenSeparator, TokenAnd, TokenOr, TokenXor, TokenNot, TokenParentheseOpen, TokenParentheseClose };

        List<string> tokens = new List<string>();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            if (c == TokenSeparator)
                continue;

            if (delimiters.Contains(c))
            {
                if (sb.Length > 0)
                {
                    tokens.Add(sb.ToString());
                    sb.Clear();
                }

                tokens.Add(c.ToString(CultureInfo.InvariantCulture));
            }
            else
            {
                sb.Append(c);
            }
        }

        if (sb.Length > 0)
        {
            tokens.Add(sb.ToString());
        }

        _expression = Parse(tokens.ToArray());
    }

    Node Parse(string[] tokens)
    {
        int index = 0;
        return ParseExp(tokens, ref index);
    }

    Node ParseExp(string[] tokens, ref int index)
    {
        Node leftExp = ParseSubExp(tokens, ref index);
        if (index > tokens.Length)
            return leftExp;

        string token = tokens[index];

        if (token == "&")
        {
            index++;
            Node rightExp = ParseSubExp(tokens, ref index);
            return new AndNode(leftExp, rightExp);
        }
        else if (token == "|")
        {
            index++;
            Node rightExp = ParseSubExp(tokens, ref index);
            return new OrNode(leftExp, rightExp);
        }
        else if (token == "^")
        {
            index++;
            Node rightExp = ParseSubExp(tokens, ref index);
            return new XorNode(leftExp, rightExp);
        }
        else
        {
            throw new Exception("Expected '&' or '|' or EOF");
        }
    }

    Node ParseSubExp(string[] tokens, ref  int index)
    {
        string token = tokens[index];

        if (token == "(")
        {
            index++;
            Node node = ParseExp(tokens, ref index);

            if (tokens[index] != ")")
                throw new Exception("Expected ')'");

            index++; // Skip ')'

            return node;
        }
        else if (token == "!")
        {
            index++;
            Node node = ParseExp(tokens, ref index);
            return new NotNode(node);
        }
        else
        {
            index++;
            return new RoleNode(token);
        }
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null) throw new ArgumentNullException("httpContext");

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated)
        {
            return false;
        }

        if (_expression == null)
        {
            Parse(Roles);
        }

        if (_expression != null)
        {
            return _expression.Eval(user);
        }

        return true;
    }
}

否則,您可以使用默認的AuthorizeAttribute

// (role1 OR role2) AND (role3 OR role4)
[Authorize(Roles = "Role1, Role2")] 
[Authorize(Roles = "Role3, Role4")] 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM