Chi*_*may 209 java spring spring-mvc spring-security
有概念和实现Spring Security的,如GrantedAuthority
界面得到一个权威授权/控制的访问.
我希望这是允许的操作,例如createSubUsers或deleteAccounts,我允许管理员(带角色ROLE_ADMIN
).
我在网上看到的教程/演示让我感到困惑.我尝试连接我读到的内容,但我认为我们可以互换地对待这两者.
我看到hasRole
消费了一个GrantedAuthority
字符串?我肯定在理解上做错了.这些概念在Spring Security中是什么?
如何存储用户的角色,与该角色的权限分开?
我也在查看在org.springframework.security.core.userdetails.UserDetails
身份验证提供程序引用的DAO中使用的接口,它使用了一个User
(注意最后的GrantedAuthority):
public User(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities)
Run Code Online (Sandbox Code Playgroud)
或者还有其他方法可以区分其他两个吗?或者它不受支持,我们必须自己制作?
Jam*_*mes 331
将GrantedAuthority视为"权限"或"权利".那些"权限"(通常)表示为字符串(使用该getAuthority()
方法).这些字符串可让您识别权限,并让您的选民决定是否允许访问某些内容.
您可以将不同的GrantedAuthority(权限)授予用户,方法是将它们放入安全上下文中.您通常通过实现自己的UserDetailsService来执行此操作,该UserDetailsService返回返回所需GrantedAuthorities的UserDetails实现.
角色(在许多示例中使用它们)只是"权限",其命名约定表明角色是以前缀开头的GrantedAuthority ROLE_
.没有别的了.角色只是一个GrantedAuthority - 一个"权限" - 一个"权利".您在spring security中看到很多地方,其ROLE_
前缀的角色专门处理,例如在RoleVoter中,其中ROLE_
前缀用作默认值.这允许您提供不带ROLE_
前缀的角色名称.在Spring security 4之前,对"角色"的这种特殊处理并未得到非常一致的遵守,权威和角色通常被视为相同(例如,hasAuthority()
hasRole()
).使用Spring Security 4,角色的处理较为一致,并以"角色"交易代码(如RoleVoter
中,hasRole
表达等)总是添加ROLE_
前缀为您服务.所以hasAuthority('ROLE_ADMIN')
意味着相同,hasRole('ADMIN')
因为ROLE_
前缀会自动添加.有关更多信息,请参阅spring security 3至4 迁移指南.
但仍然是:角色只是具有特殊ROLE_
前缀的权威.因此,在春季安全3 @PreAuthorize("hasRole('ROLE_XYZ')")
是一样的@PreAuthorize("hasAuthority('ROLE_XYZ')")
,并在Spring Security 4 @PreAuthorize("hasRole('XYZ')")
是一样的@PreAuthorize("hasAuthority('ROLE_XYZ')")
.
关于你的用例:
用户具有角色和角色可以执行某些操作.
您最终GrantedAuthorities
可以获得用户所属的角色以及角色可以执行的操作.在GrantedAuthorities
对角色有前缀ROLE_
和操作都有前缀OP_
.操作部门的例子是OP_DELETE_ACCOUNT
,OP_CREATE_USER
,OP_RUN_BATCH_JOB
等角色可以ROLE_ADMIN,ROLE_USER等.
您最终可能会GrantedAuthority
像在此(伪代码)示例中那样实现您的实体:
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@OneToMany
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;
@OneToMany
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您在数据库中创建的角色和操作的ID将是GrantedAuthority表示形式,例如"ROLE_ADMIN","OP_DELETE_ACCOUNT"等.当用户通过身份验证时,请确保所有角色的所有GrantedAuthorities和相应的操作都是从UserDetails.getAuthorities()方法.
示例:具有标识为ROLE_ADMIN的admin角色具有分配给它的操作OP_DELETE_ACCOUNT,OP_READ_ACCOUNT,OP_RUN_BATCH_JOB.ID为ROLE_USER的用户角色具有操作OP_READ_ACCOUNT.
如果管理员登录生成的安全上下文将具有GrantedAuthorities:ROLE_ADMIN,OP_DELETE_ACCOUNT,OP_READ_ACCOUNT,OP_RUN_BATCH_JOB
如果用户记录它,它将具有:ROLE_USER,OP_READ_ACCOUNT
UserDetailsService将负责收集这些角色的所有角色和所有操作,并通过返回的UserDetails实例中的getAuthorities()方法使它们可用.
理解这些概念之间关系的另一种方法是将 ROLE 解释为权限的容器。
权限是针对特定操作的细粒度权限,有时还带有特定的数据范围或上下文。例如,读取、写入、管理可以表示对给定信息范围的各种权限级别。
此外,权限在请求的处理流程中深入执行,而角色在到达控制器之前通过请求过滤器方式过滤。最佳实践规定在业务层中通过控制器实施权限执行。
另一方面,ROLES 是一组权限的粗粒度表示。ROLE_READER 将仅具有读取或查看权限,而 ROLE_EDITOR 将同时具有读取和写入权限。角色主要用于http等请求处理外围的第一次筛选。... .antMatcher(...).hasRole(ROLE_MANAGER)
在请求的流程中深入实施的权限允许更细粒度的权限应用。例如,用户可能对一级资源具有读写权限,但对子资源仅具有读取权限。拥有 ROLE_READER 将限制他编辑第一级资源的权利,因为他需要写入权限来编辑此资源,但 @PreAuthorize 拦截器可能会阻止他尝试编辑子资源。
杰克
AFAIK GrantedAuthority和角色在Spring安全性中是相同的.GrantedAuthority的getAuthority()字符串是角色(根据默认实现SimpleGrantedAuthority).
对于您的情况,您可以使用分层角色
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_ADMIN > ROLE_createSubUsers
ROLE_ADMIN > ROLE_deleteAccounts
ROLE_USER > ROLE_viewAccounts
</value>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
不是你想要的精确溶胶,但希望它有所帮助
编辑:回复您的评论
角色就像是春天安全的权限.使用带有hasRole的intercept-url可以对哪个角色/权限允许的操作提供非常精细的控制.
我们在应用程序中处理的方式是,我们为每个操作(或rest url)定义权限(即角色),例如view_account,delete_account,add_account等.然后我们为每个用户创建逻辑配置文件,如admin,guest_user,normal_user.配置文件只是权限的逻辑分组,与spring-security无关.添加新用户时,会为其分配配置文件(具有所有允许的权限).现在,当用户尝试执行某些操作时,将针对用户grantAuthorities检查该操作的权限/角色.
defaultn RoleVoter也使用前缀ROLE_,因此任何以ROLE_开头的权限都被视为角色,您可以通过在角色选民中使用自定义RolePrefix并在spring security中使用它来更改此默认行为.
就像其他人提到的那样,我将角色视为更精细权限的容器。
虽然我发现层次角色实现缺乏对这些细粒度权限的精细控制。
因此,我创建了一个库来管理关系并将权限作为安全上下文中的授予权限注入。
我可能在应用程序中有一组权限,例如 CREATE、READ、UPDATE、DELETE,然后与用户的角色相关联。
或更具体的权限,如 READ_POST、READ_PUBLISHED_POST、CREATE_POST、PUBLISH_POST
这些权限是相对静态的,但角色与它们的关系可能是动态的。
例子 -
@Autowired
RolePermissionsRepository repository;
public void setup(){
String roleName = "ROLE_ADMIN";
List<String> permissions = new ArrayList<String>();
permissions.add("CREATE");
permissions.add("READ");
permissions.add("UPDATE");
permissions.add("DELETE");
repository.save(new RolePermissions(roleName, permissions));
}
Run Code Online (Sandbox Code Playgroud)
您可以创建 API 来管理这些权限与角色的关系。
我不想复制/粘贴另一个答案,所以这里是关于 SO 的更完整解释的链接。
/sf/answers/4217635201/
为了重用我的实现,我创建了一个 repo。请随时贡献!
https://github.com/savantly-net/spring-role-permissions
归档时间: |
|
查看次数: |
98470 次 |
最近记录: |