asp.net mvc用多个枚举装饰[Authorize()]

cod*_*tte 32 asp.net-mvc authorization roles

我有一个控制器,我想要两个角色才能访问它.1-admin或2-moderator

我知道你可以做[授权(角色="管理员,版主")]但我在枚举中有我的角色.凭借枚举,我只能授权一个角色.我无法弄清楚如何授权两个.

我尝试了类似[Authorize(Roles = MyEnum.Admin,MyEnum.Moderator)]但不会编译的东西.

有人曾经这样说过:

 [Authorize(Roles=MyEnum.Admin)]
 [Authorize(MyEnum.Moderator)]
 public ActionResult myAction()
 {
 }
Run Code Online (Sandbox Code Playgroud)

但它不能作为OR.我认为在这种情况下,用户必须是BOTH角色的一部分.我忽略了一些语法吗?或者这是我必须推出自己的自定义授权的情况?

Zai*_*sud 34

这是一个简单而优雅的解决方案,允许您简单地使用以下语法:

[AuthorizeRoles(MyEnum.Admin, MyEnum.Moderator)]
Run Code Online (Sandbox Code Playgroud)

创建自己的属性时,请params在构造函数中使用关键字:

public class AuthorizeRoles : AuthorizeAttribute
{
    public AuthorizeRoles(params MyEnum[] roles)
    {
        ...
    }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这将允许您使用如下属性:

[AuthorizeRoles(MyEnum.Admin, MyEnum.Moderator)]
public ActionResult myAction()
{
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信,这应该是一个公认的解决方案,因为它起作用,并且你不仅限于在接受的答案中最多32个角色.这次真是万分感谢. (7认同)
  • @zoka 同意。这个解决方案比我的更好、更灵活。:) (2认同)

Cal*_*bHC 31

尝试使用这样的位运算符:

[Authorize(Roles= MyEnum.Admin | MyEnum.Moderator)]
public ActionResult myAction()
{
}
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,你可以自己动手.我目前只是在我的项目上做了这个.这是我做的:

public class AuthWhereRole : AuthorizeAttribute
{
    /// <summary>
    /// Add the allowed roles to this property.
    /// </summary>
    public UserRole Is;

    /// <summary>
    /// Checks to see if the user is authenticated and has the
    /// correct role to access a particular view.
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException("httpContext");

        // Make sure the user is authenticated.
        if (!httpContext.User.Identity.IsAuthenticated)
            return false;

        UserRole role = someUser.Role; // Load the user's role here

        // Perform a bitwise operation to see if the user's role
        // is in the passed in role values.
        if (Is != 0 && ((Is & role) != role))
            return false;

        return true;
    }
}

// Example Use
[AuthWhereRole(Is=MyEnum.Admin|MyEnum.Newbie)]
public ActionResult Test() {}
Run Code Online (Sandbox Code Playgroud)

另外,请确保在枚举中添加flags属性,并确保它们的值均为1及以上.像这样:

[Flags]
public enum Roles
{
    Admin = 1,
    Moderator = 1 << 1,
    Newbie = 1 << 2
    etc...
}
Run Code Online (Sandbox Code Playgroud)

左位移位给出值1,2,4,8,16等.

嗯,我希望这有点帮助.

  • 如果用户可能属于多个角色,该怎么办? (2认同)
  • 使用此解决方案,您可能只有32个角色可以进行“或”运算。可能有限制(对我来说是限制)。更好的解决方案是@ZaidMasud提供的解决方案。 (2认同)

bor*_*gas 8

我在这里结合了一些解决方案来创造我个人的最爱.我的自定义属性只是将数据更改为SimpleMembership所期望的格式,并让它处理其他所有内容.

我的角色枚举:

public enum MyRoles
{
    Admin,
    User,
}
Run Code Online (Sandbox Code Playgroud)

要创建角色:

public static void CreateDefaultRoles()
{
    foreach (var role in Enum.GetNames(typeof(MyRoles)))
    {
       if (!Roles.RoleExists(role))
       {
            Roles.CreateRole(role);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

自定义属性:

public class AuthorizeRolesAttribute : AuthorizeAttribute
{
    public AuthorizeRolesAttribute(params MyRoles[] allowedRoles)
    {
        var allowedRolesAsStrings = allowedRoles.Select(x => Enum.GetName(typeof(MyRoles), x));
        Roles = string.Join(",", allowedRolesAsStrings);
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

[AuthorizeRoles(MyRoles.Admin, MyRoles.User)]
public ActionResult MyAction()
{
    return View();
}
Run Code Online (Sandbox Code Playgroud)