Background
I would like to authorize an ApplicationUser
based on their ApplicationRole
s' RoleClaim
s. I would like to implement this like so:
public class RoleClaimAuthorizeAttribute : AuthorizeAttribute
{
public RoleClaim RoleClaim { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
foreach (ApplicationRole role in Roles)
{
if ((RoleClaim & role.Claims) > 0)
{
return true;
}
}
return false;
}
}
Then I could decorate controller actions like so:
[RoleClaimAuthorize(RoleClaim =
RoleClaim.CanCreateRoles |
RoleClaim.CanReadRoles |
RoleClaim.CanDeleteRoles |
RoleClaim.CanUpdateRoles
)]
//
// GET: /Roles/
public ActionResult Index()
{
return View(_roleManager.Roles);
}
Question
The problem I'm encountering is any method I can find of reaching an ApplicationUser
's ApplicationRole
s from my custom authorize attribute returns a string array of ApplicationRole.Name
not an array of ApplicationRole
so I can't get to ApplicationRole.Claims
. I'm also using Unity instead of Owin to handle ApplicationRoleManager
so I can't request ApplicationRoleManager
via HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>()
.
So how can I get to a collection of ApplicationRole
objects for the current user and thus ApplicationRole.Claims
?
Or if it's a more appropriate solution, how can I store a string array of the current ApplicationUser
's ApplicationRole
s' RoleClaim
s in HttpContext
much like how roles are stored? I'm aware my authorization attribute couldn't work as described in this situation but it's a situation I can work with nonetheless.
Relevant Classes
ApplicationUser
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser<Guid, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public override Guid Id { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, Guid> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, Guid> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
return userIdentity;
}
}
ApplicationRole
public class ApplicationRole : IdentityRole<Guid, ApplicationUserRole>
{
public ApplicationRole() : base()
{
this.Id = Guid.NewGuid();
}
public ApplicationRole(string name)
: this()
{
this.Name = name;
}
public ApplicationRole(string name, params string[] claims)
: this(name)
{
Claims = (RoleClaim)Enum.Parse(typeof(RoleClaim), String.Join(",", claims));
}
public RoleClaim Claims { get; set; }
}
RoleClaim
[Flags]
public enum RoleClaim : int
{
CanCreateUsers = 1,
CanReadUsers = 2,
CanUpdateUsers = 4,
CanDeleteUsers = 8,
CanCreateRoles = 16,
CanReadRoles = 32,
CanUpdateRoles = 64,
CanDeleteRoles = 128,
CanCreateTests = 256,
CanReadTests = 512,
CanUpdateTests = 1024,
CanDeleteTests = 2048
}
ApplicationRoleManager
public class ApplicationRoleManager : RoleManager<ApplicationRole, Guid>
{
public ApplicationRoleManager(IRoleStore<ApplicationRole, Guid> store) : base(store)
{
}
}