I need to enable my admin user to change access permissions for users on the fly, such that they can create new Roles and add permissions to those Roles.
I want to be able to create an Authorize
attribute to stick above my controller class that I can add roles to from a database, so that I don't have to 'set' the roles during development, as in [Authorize(Roles="Role1, Role2")]
etc.
So something like [Authorize(Roles = GetListOfRoles()]
I found this question - ASP.NET MVC Authorize user with many roles which does something similar but maybe there's a way to change this such that it gets a list of permissions/roles from the db?
The Authorize attribute enables you to restrict access to resources based on roles. It is a declarative attribute that can be applied to a controller or an action method.
The Authorize Attribute This means that once the request matches a supported route and is resolved to controller and method, it gets executed no matter what. Put another way, any public method defined on the controller class can be run if only the user calls the right URL.
This is how I pulled off an attribute that could authorize users per method based on the permissions of the role of that user. I hope this helps somebody else:
/// <summary>
/// Custom authorization attribute for setting per-method accessibility
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class SetPermissionsAttribute : AuthorizeAttribute
{
/// <summary>
/// The name of each action that must be permissible for this method, separated by a comma.
/// </summary>
public string Permissions { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
SalesDBContext db = new SalesDBContext();
UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
ApplicationDbContext dbu = new ApplicationDbContext();
bool isUserAuthorized = base.AuthorizeCore(httpContext);
string[] permissions = Permissions.Split(',').ToArray();
IEnumerable<string> perms = permissions.Intersect(db.Permissions.Select(p => p.ActionName));
List<IdentityRole> roles = new List<IdentityRole>();
if (perms.Count() > 0)
{
foreach (var item in perms)
{
var currentUserId = httpContext.User.Identity.GetUserId();
var relatedPermisssionRole = dbu.Roles.Find(db.Permissions.Single(p => p.ActionName == item).RoleId).Name;
if (userManager.IsInRole(currentUserId, relatedPermisssionRole))
{
return true;
}
}
}
return false;
}
}
What about something like this:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyCustomAuthorizationAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// Do some logic here to pull authorised roles from backing store (AppSettings, MSSQL, MySQL, MongoDB etc)
...
// Check that the user belongs to one or more of these roles
bool isUserAuthorized = ....;
if(isUserAuthorized)
return true;
return base.AuthorizeCore(httpContext);
}
}
You could use it with a database, or simply maintain a list of authorized roles in the web.config.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With