Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP .NET MVC Securing a Controller/Action

If I want only administrator to access the action called "ManagerUser", I know I can do this:

[Authorize( Roles = Constants.ROLES_ADMINISTRATOR )]
public ActionResult ManageUser( string id )
{
}

What if I want to give everyone access except to administrator? I do not want to write all roles up there on function :|.

Any recommendations/way outs?

like image 846
effkay Avatar asked Dec 04 '22 13:12

effkay


2 Answers

You can create your own custom Authorize attribute, something like "AuthorizeAllExceptAdmin." Within that class you would simply need to check whether or not the current user was an admin, and if they were reject it, otherwise accept it.

Here's a good tutorial, but you'll probably end up with something like:

public class AuthorizeAllExceptAdmin : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return !httpContext.User.IsInRole(Constants.ROLES_ADMINISTRATOR);
    }
}

Then your controller method becomes:

[AuthorizeAllExceptAdmin] 
public ActionResult SomethingOnlyNonAdminsCanDo() 
{ 
} 

Here's an example of the custom attribute that takes in roles to deny.

public class DoNotAuthorize : AuthorizeAttribute
{
    private IEnumerable<string> _rolesToReject;

    public DoNotAuthorize(IEnumerable<string> rolesToReject)
    {
        _rolesToReject = rolesToReject;        
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        foreach (var role in _rolesToReject)
        {
            if (httpContext.User.IsInRole(role))
                return false;
        }

        return true;
    }
}

Then your controller method becomes:

[DoNotAuthorize(new [] {Constants.ROLES_ADMINISTRATOR})] 
public ActionResult SomethingOnlyNonAdminsCanDo() 
{ 
} 

I would put some thought into it before choosing one of the above options. If you think you'll have several methods (or entire controllers) with similar authorization requirements (i.e, several actions an admin can not perform) then I would stick with the non-parameterized custom attribute. This way, you can evolve them all together (by only changing the custom attribute) later on. For example, maybe later on you want admins to be able to go into a special mode where they can perform these actions.

Alternatively, if the autorization is more varied amongst the actions, then using the parameterized list makes sense, since they'll evolve relatively independently.

like image 173
reustmd Avatar answered Dec 22 '22 21:12

reustmd


Besides creating a custom AuthorizeAttribute, suggested by manu, you could use PrincipalPermission, with a Deny-SecurityAction:

[PrincipalPermission(SecurityAction.Deny, Role="Administrator")]
like image 34
Pbirkoff Avatar answered Dec 22 '22 20:12

Pbirkoff