AuthorizeAttribute with Roles but not hard-coding the Role values
Asked Answered
B

2

5

Is it possible to add the Roles but not hard-coding the values like:

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

I would like to retrieve these roles from a database or configuration file where I wouldn't need to rebuild the application if I needed to add/remove Roles for a Controller Action.

I know with the enums it can be done... http://www.vivienchevallier.com/Articles/create-a-custom-authorizeattribute-that-accepts-parameters-of-type-enum but even this is still not flexible enough for my needs; it's still somewhat of a hard-code, even though it is cleaner.

Bronchoscope answered 28/1, 2012 at 8:3 Comment(0)
S
9

You can create your custom authorization attribute, that will compare user roles and roles from your configuration.

public class ConfigAuthorizationAttribute: AuthorizeAttribute
{
    private readonly IActionRoleConfigService configService;
    private readonly IUserRoleService roleService;

    private string actionName;

    public ConfigAuthorizationAttribute()
    {
        configService = new ActionRoleConfigService();
        roleService = new UserRoleService();
    }

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        actionName = filterContext.ActionDescription.ActionName;
        base.OnAuthorization(filterContext);
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var availableRoles = configService.GetActionRoles(actionName); // return list of strings
        var userName = httpContext.User.Identity.Name;
        var userRoles = roleService.GetUserRoles(userName); // return list of strings
        return availableRoles.Any(x => userRoles.Contains(x));
    }
}

I hope it helps you.

Shiloh answered 28/1, 2012 at 20:3 Comment(3)
What namespaces are IActionRoleConfigService and IUserRoleService in ?Bronchoscope
Can you add the namespaces since there is ambiguity between Mvc and WebApi. Thanks. And AuthorizationContext has many namespaces. :<Towage
@Towage use System.Web.Mvc classes, if you have MVC project.Shiloh
C
3

One solution would be to create an intermediate entity called "Group" where users are added to groups (eg: Admin, Support) and groups have set of Roles. (eg: Create users). This way you can hard code the Roles and configure the relationships between users and groups.

You would need to implement a custom Role Provider. Go through Implementing a Role Provider On MSDN

[Authorize(Roles="CreateUser")]
public ActionResult Create()
{

}
Countrybred answered 28/1, 2012 at 8:26 Comment(1)
To be clear, in my case Groups would be Roles and Roles would be functions. So, using my terminology, each Role would have a number of functions, a one-to-many relationship: Role(1) - Functions(*). My plan would be to use the Action Name as you have done in your 'CreateUser' attribute. In this case, any Roles that have the function to create a user would be allowed.Bronchoscope

© 2022 - 2024 — McMap. All rights reserved.