我尝试在网络上的任何地方进行搜索,但似乎无法弄清这一重要部分。
基本上,如果我们每次在检查用户是否属于某个角色时都进行一次数据库调用-这会对性能产生负面影响。
我看到了列出所有用户角色的代码示例,例如
var roles = ((ClaimsIdentity)User.Identity).Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value);
该代码可用于控制器操作,也可以在属性过滤器中以相同的方式获取声明。
从此示例中,我推断Claims
起着作用(似乎是性能最高的解决方案)。
我试图找出是否 Authorize
具有“角色”属性来验证用户的声明,但是official Microsoft documentation并不涵盖这一点。
AuthorizeAttribute
课程指定对控制器或操作方法的访问仅限于满足授权要求的用户。
属性:
Roles
-获取或设置有权访问控制器或操作方法的用户角色。
这就是我们所拥有的范围。
答案 0 :(得分:1)
两个Authorize属性均为User.IsInRole查看User.Identity角色声明。
默认情况下,授权机构(用户登录的地方)将从AspNetUserRoles表中添加角色,作为类型为“ http://schemas.microsoft.com/ws/2008/06/identity/claims/role
”的声明。参见WIF claimtypes members。
客户端应用程序将自动从令牌/ cookie中获取信息,并将其转换为User.Identity。当声明类型匹配时,角色类型声明将映射为角色。
这意味着该应用不需要访问用户存储。在大多数情况下,这也是不可能的。因此,实际上与性能无关,而与可访问性有关。通常,应用程序无权访问身份上下文。因此UserManager不是一个选择。
但是,使用索赔时有一个缺点。该信息已过时。当用户登录时,声明的快照将被添加到身份中。同时,如果声明(或角色)在数据库中更新,则不会记录这些更改。只有在用户再次登录后,更改才会生效。
这意味着声明仅适用于(通常)不会更改的信息,除非您找到使声明无效的方法。但这可能意味着要访问数据库或调用权限。
这就是为什么我不建议使用角色的原因。由于角色倾向于用于授权,但与此同时您不能撤消访问权限。因此,在解决该问题之前,您可能需要考虑替代方法。
不能选择与UserManager绑定,因为上下文可能不适用于所有应用程序。
这就是为什么基于资源的授权可以为您提供解决方案的原因。请阅读我的回答here,以获取其他想法。
答案 1 :(得分:0)
打开您的启动文件并更改它:
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
对此:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
然后角色应该开始工作。