C# 如何从HttpContext访问角色对象,或者更具体地说,如何从自定义授权属性访问角色对象? 背景
我想根据他们的C# 如何从HttpContext访问角色对象,或者更具体地说,如何从自定义授权属性访问角色对象? 背景,c#,asp.net-identity-2,asp.net-mvc-5.2,C#,Asp.net Identity 2,Asp.net Mvc 5.2,我想根据他们的ApplicationRolesRoleClaims授权ApplicationUser。我想这样实施: public class RoleClaimAuthorizeAttribute : AuthorizeAttribute { public RoleClaim RoleClaim { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) {
ApplicationRole
sRoleClaim
s授权ApplicationUser
。我想这样实施:
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;
}
}
[RoleClaimAuthorize(RoleClaim =
RoleClaim.CanCreateRoles |
RoleClaim.CanReadRoles |
RoleClaim.CanDeleteRoles |
RoleClaim.CanUpdateRoles
)]
//
// GET: /Roles/
public ActionResult Index()
{
return View(_roleManager.Roles);
}
然后我可以这样装饰控制器动作:
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;
}
}
[RoleClaimAuthorize(RoleClaim =
RoleClaim.CanCreateRoles |
RoleClaim.CanReadRoles |
RoleClaim.CanDeleteRoles |
RoleClaim.CanUpdateRoles
)]
//
// GET: /Roles/
public ActionResult Index()
{
return View(_roleManager.Roles);
}
问题: 我遇到的问题是,我能找到的任何从自定义授权属性访问
ApplicationUser
的ApplicationRole
s的方法都会返回ApplicationRole的字符串数组。Name
不是ApplicationRole
的数组,因此我无法访问ApplicationRole。声明。我还使用Unity而不是Owin来处理ApplicationRoleManager
,因此我无法通过HttpContext.Current.GetOwinContext().Get()请求ApplicationRoleManager
那么,如何才能获得当前用户的ApplicationRole
对象集合,从而获得ApplicationRole.Claims
或者,如果这是一个更合适的解决方案,我如何在HttpContext
中存储当前ApplicationUser
的ApplicationRole
sRoleClaim
s的字符串数组,就像存储角色一样?我知道我的授权属性在这种情况下无法正常工作,但我仍然可以处理这种情况
相关类
应用程序用户
应用程序角色管理器
公共类应用程序RoleManager:RoleManager
{
公共应用程序角色管理器(IRoleStore存储):基本(存储)
{
}
}
如果您在Unity中注册了角色管理器,只需调用以下方法,您就可以随时随地检索角色管理器,包括自定义属性:
var roleManager = DependencyResolver.Current.GetService<ApplicationRoleManager>();
现在,当用户登录时,RoleClaims
作为声明添加。您可以在属性中检索它们,如下所示:
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
private readonly ApplicationRoleManager _roleManager;
public ApplicationSignInManager(ApplicationUserManager userManager,
IAuthenticationManager authenticationManager,
ApplicationRoleManager rolemanager)
: base(userManager, authenticationManager)
{
//inject the role manager to the sign in manager
_roleManager=rolemanager;
}
public override async Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
var ident= await user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
// add your custom claims here
var userRoles=user.Roles.Select(r=>r.RoleId);
ident.AddClaims(_roleManager.Roles.Where(r => userRoles.Any(ur => ur == r.Id))
.Select(r=>r.Claims).ToList()
.Select(c => new Claim("RoleClaims", c.ToString())));
return ident;
}
}
public class RoleClaimAuthorizeAttribute : AuthorizeAttribute
{
public RoleClaim RoleClaim { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
foreach (var claims in GetClaims(httpContext.User.Identity as ClaimsIdentity))
{
if ((RoleClaim & claims) > 0)
{
return true;
}
}
return false;
}
private IEnumerable<RoleClaim> GetClaims(ClaimsIdentity ident)
{
return ident==null
? Enumerable.Empty<RoleClaim>()
: ident.Claims.Where(c=>c.Type=="RoleClaims")
.Select(c=>(RoleClaim)Enum.Parse(typeof(RoleClaim), c.Value));
}
}
公共类RoleClaimAuthorizeAttribute:AuthorizeAttribute
{
公共RoleClaim RoleClaim{get;set;}
受保护的覆盖bool AuthorizeCore(HttpContextBase httpContext)
{
foreach(GetClaims中的var声明(httpContext.User.Identity as ClaimsIdentity))
{
如果((RoleClaim&索赔)>0)
{
返回true;
}
}
返回false;
}
私人IEnumerable GetClaims(索赔实体标识)
{
返回标识==null
?可枚举。空()
:ident.Claims.Where(c=>c.Type==“RoleClaims”)
.Select(c=>(RoleClaim)Enum.Parse(typeof(RoleClaim),c.Value));
}
}
感谢您提供的替代解决方案,它比我想象的要好得多。从ApplicationSignInManager
中的CreateUserIdentityAsync
下的ident.AddClaims
行出现问题。异常如下:无法创建类型为“ApplicationUserRole
”的常量值。在此上下文中仅支持基元类型或枚举类型。进行了一点挖掘,看起来这是来自Linq查询的where一半,我自己在寻找如何修复它,但我认为我应该发布。不幸的是,这并不能解决问题。以下代码是导致异常的原因,只是它仅在枚举可枚举项时才会抛出:\u rolemanger.Roles.Where(r=>user.Roles.Any(ur=>ur.RoleId==r.Id))
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
private readonly ApplicationRoleManager _roleManager;
public ApplicationSignInManager(ApplicationUserManager userManager,
IAuthenticationManager authenticationManager,
ApplicationRoleManager rolemanager)
: base(userManager, authenticationManager)
{
//inject the role manager to the sign in manager
_roleManager=rolemanager;
}
public override async Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
var ident= await user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
// add your custom claims here
var userRoles=user.Roles.Select(r=>r.RoleId);
ident.AddClaims(_roleManager.Roles.Where(r => userRoles.Any(ur => ur == r.Id))
.Select(r=>r.Claims).ToList()
.Select(c => new Claim("RoleClaims", c.ToString())));
return ident;
}
}
public class RoleClaimAuthorizeAttribute : AuthorizeAttribute
{
public RoleClaim RoleClaim { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
foreach (var claims in GetClaims(httpContext.User.Identity as ClaimsIdentity))
{
if ((RoleClaim & claims) > 0)
{
return true;
}
}
return false;
}
private IEnumerable<RoleClaim> GetClaims(ClaimsIdentity ident)
{
return ident==null
? Enumerable.Empty<RoleClaim>()
: ident.Claims.Where(c=>c.Type=="RoleClaims")
.Select(c=>(RoleClaim)Enum.Parse(typeof(RoleClaim), c.Value));
}
}