views:

1255

answers:

2

I have a controller and I want two roles to be able to access it. 1-admin OR 2-moderator

I know you can do [Authorize(Roles="admin, moderators")] but I have my roles in an enum. With the enum I can only authorize ONE role. I can't figure out how to authorize two.

I have tried something like [Authorize(Roles=MyEnum.Admin, MyEnum.Moderator)] but that wont compile.

Someone once suggested this:

 [Authorize(Roles=MyEnum.Admin)]
 [Authorize(MyEnum.Moderator)]
 public ActionResult myAction()
 {
 }

but it doesn't work as an OR. I think in this case the user has to be part of BOTH roles. Am I overlooking some syntax? Or is this a case where I have to roll my own custom authorization?

+5  A: 

Try using the bit OR operator like this:

[Authorize(Roles= MyEnum.Admin | MyEnum.Moderator)]
public ActionResult myAction()
{
}

If that doesn't work, you could just roll your own. I currently just did this on my project. Here's what I did:

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() {}

Also, make sure to add a flags attribute to your enum and make sure they are all valued from 1 and up. Like this:

[Flags]
public enum Roles
{
    Admin = 1,
    Moderator = 1 << 1,
    Newbie = 1 << 2
    etc...
}

The left bit shifting gives the values 1, 2, 4, 8, 16 and so on.

Well, I hope this helps a little.

CalebHC
A: 

Or you could concatenate like:

[Authorize(Roles = Common.Lookup.Item.SecurityRole.Administrator + "," + Common.Lookup.Item.SecurityRole.Intake)]