简体   繁体   English

“授权”属性与“角色”是否考虑了“索赔”

[英]does Authorize attribute with Roles take Claims into account

I tried searching everywhere on the web, but I can't seem to figure out this important part. 我尝试在网络上的所有位置进行搜索,但似乎无法弄清楚这一重要部分。

Basically, if we do a DB call each time when checking if a user belongs to a role - this will have negative effect on performance. 基本上,如果我们在检查用户是否属于某个角色时每次都进行一次数据库调用-这会对性能产生负面影响。

I saw code examples listing all user roles, eg 我看到了列出所有用户角色的代码示例,例如

var roles = ((ClaimsIdentity)User.Identity).Claims
            .Where(c => c.Type == ClaimTypes.Role)
            .Select(c => c.Value);

the code can be used in controller action, it is also possible to fetch claims the same way in an Attribute Filter . 该代码可用于控制器操作,也可以在Attribute Filter中以相同的方式获取声明。

From this example I infer that Claims come into play (seems to be most performant solution). 从这个示例中,我推断Claims发挥了作用(似乎是性能最高的解决方案)。

I tried to find out if Authorize attribute with Roles verifies user's claims , but the official Microsoft documentation doesn't cover this bit. 我试图找出是否 Authorize 使用角色属性核实用户的说法 ,但微软官方文档不包括该位。

AuthorizeAttribute class AuthorizeAttribute

Specifies that access to a controller or action method is restricted to users who meet the authorization requirement. 指定对控制器或操作方法的访问仅限于满足授权要求的用户。

Properties: 属性:

Roles - Gets or sets the user roles that are authorized to access the controller or action method. Roles -获取或设置有权访问控制器或操作方法的用户角色。

And that's the extent of what we have. 这就是我们所拥有的范围。

Both the Authorize attribute as eg User.IsInRole look at the User.Identity roles claims. 这两个Authorize属性(例如User.IsInRole)都查看User.Identity角色声明。

By default the Authority (where the user logs in) will add the roles from the AspNetUserRoles table as claims of type ' http://schemas.microsoft.com/ws/2008/06/identity/claims/role '. 默认情况下,授权机构(用户登录的地方)将从AspNetUserRoles表中添加角色,作为类型为' http://schemas.microsoft.com/ws/2008/06/identity/claims/role '的声明。 See WIF claimtypes members . 请参阅WIF声明类型成员

The client app will automatically take the information from the token / cookie and convert this as User.Identity. 客户端应用程序将自动从令牌/ cookie中获取信息,并将其转换为User.Identity。 As the claim type matches, the role type claims are mapped as roles. 当声明类型匹配时,角色类型声明将映射为角色。

This means that the app doesn't need access to the user store. 这意味着该应用不需要访问用户存储。 In most cases this is also not possible. 在大多数情况下,这也是不可能的。 So it is actually not about performance, but about accessibility. 因此,实际上与性能无关,而与可访问性有关。 Usually apps don't have access to the Identity context. 通常,应用程序无权访问身份上下文。 So UserManager is not an option. 因此,UserManager不是一个选择。

There is however a drawback when using claims. 然而,在使用权利要求时存在缺点。 The information is dated. 该信息已过时。 When the user logs in a snapshot of the claims at that time are added to the Identity. 当用户登录时,声明的快照将被添加到身份中。 If in the meantime claims (or roles) are updated in the database, then these changes are not noted. 同时,如果声明(或角色)在数据库中更新,则不会记录这些更改。 Only after the user logs in again, the changes become effective. 只有在用户再次登录后,更改才会生效。

This means that claims are only suitable for pieces of information that do not (frequently) change unless you find a way to invalidate claims. 这意味着声明仅适用于(经常)不会更改的信息,除非您找到使声明无效的方法。 But that would probably mean to access the database or call the authority. 但这可能意味着要访问数据库或调用权限。

That's why I wouldn't recommend the use of roles. 这就是为什么我不建议使用角色的原因。 As roles tend to be used for authorization, but you can't revoke access in the meantime. 由于角色倾向于用于授权,但与此同时您不能撤消访问权限。 So until you solve that, you may want to consider an alternative. 因此,在解决该问题之前,您可能需要考虑替代方法。

Sticking to UserManager is not an alternative, because the context may not be available for all apps. 坚持使用UserManager并不是另一种选择,因为上下文可能不适用于所有应用程序。

That's why resource-based authorization may be a solution for you. 因此,基于资源的授权可能是您的解决方案。 Please read my answer here for additional thoughts. 在此处阅读我的答案以获取其他想法。

Open your Startup file and change this: 打开您的启动文件并更改此:

services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();

to this: 对此:

services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultUI()
                .AddDefaultTokenProviders();

Then the Roles should start working. 然后,角色应开始工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM