Spring Security 中 Role 和 GrantedAuthority 的区别 [英] Difference between Role and GrantedAuthority in Spring Security
问题描述
Spring Security 中有一些概念和实现,例如 GrantedAuthority
接口来获取 authority 来授权/控制访问.
There are concepts and implementations in Spring Security, such as the GrantedAuthority
interface to get an authority to authorize/control an access.
我想要允许的操作,例如 createSubUsers 或 deleteAccounts,我会允许 admin(具有角色 <代码>ROLE_ADMIN).
I would like that to permissible operations, such as createSubUsers, or deleteAccounts, which I would allow to an admin (with role ROLE_ADMIN
).
当我在网上看到教程/演示时,我感到很困惑.我尝试将我读到的内容联系起来,但我认为我们可以互换对待两者.
I am getting confused as the tutorials/demos I see online. I try to connect what I read, but I think we treat the two interchangeably.
我看到 hasRole
消耗了 GrantedAuthority
字符串?我绝对是在理解上做错了.Spring Security 中的这些概念是什么?
I see hasRole
consuming a GrantedAuthority
string? I most definitely am doing it wrong in understanding. What are these conceptually in Spring Security?
如何存储用户的角色,与该角色的权限分开?
How do I store the role of a user, separate from the authorities for that role?
我也在查看 org.springframework.security.core.userdetails.UserDetails
接口,该接口用于身份验证提供者引用的 DAO,它使用 User
(注意最后的 GrantedAuthority):
I'm also looking at the org.springframework.security.core.userdetails.UserDetails
interface which is used in the authentication-provider referenced DAO, which consumes a User
(note last GrantedAuthority):
public User(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities)
或者有没有其他方法可以区分另外两个?还是不支持,我们必须自己制作?
Or is there any other way to differentiate the other two? Or is it not supported and we have to make our own?
推荐答案
将 GrantedAuthority 视为权限"或权利".这些权限"(通常)表示为字符串(使用 getAuthority()
方法).这些字符串可让您识别权限,并让您的选民决定是否授予对某些内容的访问权限.
Think of a GrantedAuthority as being a "permission" or a "right". Those "permissions" are (normally) expressed as strings (with the getAuthority()
method). Those strings let you identify the permissions and let your voters decide if they grant access to something.
您可以通过将用户置于安全上下文中来向用户授予不同的 GrantedAuthority(权限).您通常通过实现自己的 UserDetailsService 来实现,该服务返回 UserDetails 实现,该实现返回所需的 GrantedAuthorities.
You can grant different GrantedAuthoritys (permissions) to users by putting them into the security context. You normally do that by implementing your own UserDetailsService that returns a UserDetails implementation that returns the needed GrantedAuthorities.
角色(因为它们在许多示例中使用)只是具有命名约定的权限",即角色是以前缀 ROLE_
开头的 GrantedAuthority.没有什么了.角色只是 GrantedAuthority - 权限" - 权利".您会在 Spring Security 中看到很多地方,其中带有 ROLE_
前缀的角色被特殊处理,例如在 RoleVoter 中,默认使用 ROLE_
前缀.这允许您提供不带 ROLE_
前缀的角色名称.在 Spring security 4 之前,角色"的这种特殊处理并没有得到非常一致的遵循,并且权限和角色通常被视为相同的(例如,您可以在 hasAuthority()
方法的实现中看到在 SecurityExpressionRoot - 只调用 hasRole()
).使用 Spring Security 4,角色的处理更加一致,处理角色"的代码(如 RoleVoter
、hasRole
表达式等)总是添加 ROLE_
前缀.所以 hasAuthority('ROLE_ADMIN')
与 hasRole('ADMIN')
的意思相同,因为 ROLE_
前缀是自动添加的.参见spring security 3 to 4 迁移指南 了解更多信息.
Roles (as they are used in many examples) are just "permissions" with a naming convention that says that a role is a GrantedAuthority that starts with the prefix ROLE_
. There's nothing more. A role is just a GrantedAuthority - a "permission" - a "right". You see a lot of places in spring security where the role with its ROLE_
prefix is handled specially as e.g. in the RoleVoter, where the ROLE_
prefix is used as a default. This allows you to provide the role names withtout the ROLE_
prefix. Prior to Spring security 4, this special handling of "roles" has not been followed very consistently and authorities and roles were often treated the same (as you e.g. can see in the implementation of the hasAuthority()
method in SecurityExpressionRoot - which simply calls hasRole()
). With Spring Security 4, the treatment of roles is more consistent and code that deals with "roles" (like the RoleVoter
, the hasRole
expression etc.) always adds the ROLE_
prefix for you. So hasAuthority('ROLE_ADMIN')
means the the same as hasRole('ADMIN')
because the ROLE_
prefix gets added automatically. See the spring security 3 to 4 migration guide for futher information.
但仍然:角色只是具有特殊ROLE_
前缀的权限.所以在 Spring security 3 @PreAuthorize("hasRole('ROLE_XYZ')")
和 @PreAuthorize("hasAuthority('ROLE_XYZ')")
和 Spring 是一样的security 4 @PreAuthorize("hasRole('XYZ')")
与 @PreAuthorize("hasAuthority('ROLE_XYZ')")
相同.
But still: a role is just an authority with a special ROLE_
prefix. So in Spring security 3 @PreAuthorize("hasRole('ROLE_XYZ')")
is the same as @PreAuthorize("hasAuthority('ROLE_XYZ')")
and in Spring security 4 @PreAuthorize("hasRole('XYZ')")
is the same as @PreAuthorize("hasAuthority('ROLE_XYZ')")
.
关于您的用例:
用户有角色,角色可以执行某些操作.
Users have roles and roles can perform certain operations.
对于用户所属的角色和角色可以执行的操作,您可以在 GrantedAuthorities
中结束.角色的GrantedAuthorities
有前缀ROLE_
,操作有前缀OP_
.操作权限的示例可以是 OP_DELETE_ACCOUNT
、OP_CREATE_USER
、OP_RUN_BATCH_JOB
等.角色可以是ROLE_ADMIN
、ROLE_USER
、ROLE_OWNER
等
You could end up in GrantedAuthorities
for the roles a user belongs to and the operations a role can perform. The GrantedAuthorities
for the roles have the prefix ROLE_
and the operations have the prefix OP_
. An example for operation authorities could be OP_DELETE_ACCOUNT
, OP_CREATE_USER
, OP_RUN_BATCH_JOB
etc. Roles can be ROLE_ADMIN
, ROLE_USER
, ROLE_OWNER
etc.
您最终可能会让您的实体实现 GrantedAuthority
,就像在这个(伪代码)示例中一样:
You could end up having your entities implement GrantedAuthority
like in this (pseudo-code) example:
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@ManyToMany
private final List<Operation> allowedOperations = new ArrayList<>();
@Override
public String getAuthority() {
return id;
}
public Collection<GrantedAuthority> getAllowedOperations() {
return allowedOperations;
}
}
@Entity
class User {
@Id
private String id;
@ManyToMany
private final List<Role> roles = new ArrayList<>();
public Collection<Role> getRoles() {
return roles;
}
}
@Entity
class Operation implements GrantedAuthority {
@Id
private String id;
@Override
public String getAuthority() {
return id;
}
}
您在数据库中创建的角色和操作的 ID 将是 GrantedAuthority 表示,例如ROLE_ADMIN
、OP_DELETE_ACCOUNT
等.当用户通过身份验证时,确保其所有角色的所有 GrantedAuthorities 和相应操作都从 UserDetails.getAuthorities() 方法返回.
The ids of the roles and operations you create in your database would be the GrantedAuthority representation, e.g. ROLE_ADMIN
, OP_DELETE_ACCOUNT
etc. When a user is authenticated, make sure that all GrantedAuthorities of all its roles and the corresponding operations are returned from the UserDetails.getAuthorities() method.
示例:id 为 ROLE_ADMIN
的管理员角色具有分配给它的操作 OP_DELETE_ACCOUNT
、OP_READ_ACCOUNT
、OP_RUN_BATCH_JOB
.id 为 ROLE_USER
的用户角色具有操作 OP_READ_ACCOUNT
.
Example:
The admin role with id ROLE_ADMIN
has the operations OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
assigned to it.
The user role with id ROLE_USER
has the operation OP_READ_ACCOUNT
.
如果管理员登录生成的安全上下文将具有 GrantedAuthorities:ROLE_ADMIN
、OP_DELETE_ACCOUNT
、OP_READ_ACCOUNT
、OP_RUN_BATCH_JOB
If an admin logs in the resulting security context will have the GrantedAuthorities:
ROLE_ADMIN
, OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
如果用户登录,它将具有:ROLE_USER
, OP_READ_ACCOUNT
If a user logs it, it will have:
ROLE_USER
, OP_READ_ACCOUNT
UserDetailsService 会负责收集所有角色和这些角色的所有操作,并通过返回的 UserDetails 实例中的 getAuthorities() 方法使它们可用.
The UserDetailsService would take care to collect all roles and all operations of those roles and make them available by the method getAuthorities() in the returned UserDetails instance.
这篇关于Spring Security 中 Role 和 GrantedAuthority 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!