Asp.Net MVC 5 - 自定义授权无法工作?

3

我有以下带有自定义授权属性的控制器:

[CustomAuthorize(Roles = "Editor, Admin")]
public ActionResult Test()
{
       //...

}

这是我的自定义授权代码:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{

    private readonly string[] _allowedRoles;

    public CustomAuthorizeAttribute(params string[] roles)
    {
        _allowedRoles = roles;

    }

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


        var user = httpContext.User;

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

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


        return true;

    }


}

自定义授权方法返回 true,即使用户不是编辑或管理员?

我认为问题在于:

[CustomAuthorize(Roles = "Editor, Admin")]

我正在将其作为字符串传递,我需要在我的CustomAuthorize方法中将其转换为数组吗?

调试并逐步执行您的代码逻辑。根据用户IsInRole返回true,检查!_allowedRoles.Any(user.IsInRole) - Nkosi
@Nkosi 我需要将角色 params string[] roles 作为参数传递,还是授权属性已经有了 Roles - adam78
调试时,用户是什么类型? - Nkosi
还可以基于属性构造函数尝试 [CustomAuthorize("Editor", "Admin")] - Nkosi
2个回答

1
当前的属性定义没有提及 Roles 属性,也没有填充 _allowedRoles 字段。
这就是为什么你的属性总是返回 true 的原因。
请查看自定义属性的重构逻辑。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute {
    private readonly string[] _allowedRoles;

    public CustomAuthorizeAttribute(params string[] roles) {
        _allowedRoles = roles;
    }

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

        var user = httpContext.User;
        if (user?.Identity?.IsAuthenticated) {
            if (isInRole(user, _allowedRoles)) {
                return true;
            }
            if (!string.IsNullOrWhiteSpace(Roles)) {
                var roles = Roles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (isInRole(user, roles))
                    return true;
            }
            return true;
        }
        return false;
    }

    bool isInRole(IPrincipal user, string[] roles) {
        return roles.Length > 0 && roles.Any(user.IsInRole);
    }
}

可以这样使用:
[CustomAuthorize(Roles = "Editor, Admin")]
public ActionResult Test() {
       //...
}

这里的角色将被拆分并与用户进行匹配检查

或者像这样

[CustomAuthorize("Editor", "Admin")]
public ActionResult Test() {
       //...
}

这将使用参数数组填充属性的构造函数


0

首先,您需要获取当前用户的角色,然后检查这些角色中是否有任何一个允许用户访问控制器:

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


    var user = httpContext.User;

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

    var userRoles = ((ClaimsIdentity)User.Identity).Claims
            .Where(c => c.Type == ClaimTypes.Role)
            .Select(c => c.Value);

    if (_allowedRoles.Length > 0 && !_allowedRoles.Any(x => userRoles.Any(y => x.Equals(y)))))
    {
        return false;
    }


    return true;

}

我没有将角色存储为声明。我认为我需要将角色拆分成一个数组,因为我将其作为字符串 [CustomAuthorize(Roles = "Editor, Admin")] 传递。如何将其拆分为数组并删除逗号分隔符之间的任何空格?以下代码无法正常工作 - _allowedRoles = roles.Split(','); - adam78

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接