我正在尝试使用权限设置基于角色的安全性。我正在尝试与Spring-Security一起做这件事。
我不想设置ACL,因为它似乎对我的要求来说太过分了。
我只想拥有此article中所述的简单权限和角色。 遗憾的是,该文章没有描述如何实现给定的解决方案。
有人已经尝试过这个并且可以指出我正确的方向吗?也许还有另一篇描述实施的博客文章?
非常感谢。
答案 0 :(得分:75)
我是这篇文章的作者。
毫无疑问,有多种方法可以做到这一点,但我通常采用的方式是实现了解角色和权限的自定义UserDetails
。 Role
和Permission
只是您编写的自定义类。 (没什么好看的 - Role
有一个名称和一组Permission
个实例,Permission
有一个名字。)然后getAuthorities()
返回GrantedAuthority
个对象看起来像这样:
PERM_CREATE_POST
,PERM_UPDATE_POST
,PERM_READ_POST
而不是返回
之类的东西 ROLE_USER
,ROLE_MODERATOR
如果UserDetails
实施方法采用getRoles()
方法,则角色仍可用。 (我建议有一个。)
理想情况下,您可以为用户分配角色,并自动填充相关权限。这将涉及具有知道如何执行该映射的自定义UserDetailsService
,并且它所要做的就是从数据库中获取映射。 (请参阅有关架构的文章。)
然后,您可以根据权限而不是角色来定义授权规则。
希望有所帮助。
答案 1 :(得分:30)
要实现这一点,您似乎必须:
org.springframework.security.authentication.ProviderManager
并将其配置(将其提供商设置)为自定义org.springframework.security.authentication.AuthenticationProvider
。
最后一个应该在其身份验证方法上返回一个身份验证,在您的情况下,应该使用org.springframework.security.core.GrantedAuthority
设置给定用户的所有权限。该文章的技巧是将角色分配给用户,但是,要在Authentication.authorities
对象中设置这些角色的权限。
为此,我建议您阅读API,看看是否可以扩展一些基本的ProviderManager和AuthenticationProvider而不是实现所有内容。我已经通过设置自定义LdapAuthoritiesPopulator的org.springframework.security.ldap.authentication.LdapAuthenticationProvider
来完成此操作,这将为用户检索正确的角色。
希望这次我得到了你想要的东西。 祝你好运。
答案 2 :(得分:6)
基本步骤是:
使用自定义身份验证提供程序
<bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton">
...
</bean>
让自定义提供程序返回自定义UserDetails
实现。这个UserDetailsImpl
会像getAuthorities()
这样:
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>();
for (GrantedAuthority role: roles) {
permissions.addAll(getPermissionsIncludedInRole(role));
}
return permissions;
}
当然,从这里开始,您可以根据具体要求应用大量优化/自定义。
答案 3 :(得分:5)
这是最简单的方法。允许组权限以及用户权限。
-- Postgres syntax
create table users (
user_id serial primary key,
enabled boolean not null default true,
password text not null,
username citext not null unique
);
create index on users (username);
create table groups (
group_id serial primary key,
name citext not null unique
);
create table authorities (
authority_id serial primary key,
authority citext not null unique
);
create table user_authorities (
user_id int references users,
authority_id int references authorities,
primary key (user_id, authority_id)
);
create table group_users (
group_id int references groups,
user_id int referenecs users,
primary key (group_id, user_id)
);
create table group_authorities (
group_id int references groups,
authority_id int references authorities,
primary key (group_id, authority_id)
);
然后在META-INF / applicationContext-security.xml
中<beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder" />
<authentication-manager>
<authentication-provider>
<jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username, password, enabled from users where username=?"
authorities-by-username-query="select users.username, authorities.authority from users join user_authorities using(user_id) join authorities using(authority_id) where users.username=?"
group-authorities-by-username-query="select groups.id, groups.name, authorities.authority from users join group_users using(user_id) join groups using(group_id) join group_authorities using(group_id) join authorities using(authority_id) where users.username=?"
/>
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
答案 4 :(得分:1)
对于我的要求,ACL也是过大的。
我最终创建了一个类似于@Alexander的库,以根据用户的角色成员资格为角色->权限注入GrantedAuthority
列表。
例如,使用数据库保存关系-
@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));
}
在当前安全会话中注入Authentication对象时,它将具有原始角色/授予的权限。
该库为Spring Security提供了2个内置的集成点。
当达到集成点时,将调用PermissionProvider以获得用户所属的每个角色的有效权限。
权限的不同列表添加为Authentication对象中的GrantedAuthority项目。
例如,您还可以实现自定义PermissionProvider
来将关系存储在config中。
此处更完整的解释-https://stackoverflow.com/a/60251931/1308685
源代码在这里- https://github.com/savantly-net/spring-role-permissions
答案 5 :(得分:0)
仅出于完整性考虑(也许其他人不必从头开始实施):
我们和其他所有人一样,已经实现了自己的小型图书馆。它应该使事情变得容易,以便我们的开发人员不必每次都重新实现它。如果Spring Security可以提供现成的rbac支持,那就太好了,因为这种方法比基于默认权限的方法好得多。
查看Github(OSS,MIT许可证),看看它是否适合您的需求。基本上,它仅解决角色<->特权映射。您必须自己提供的缺失部分基本上是用户<->角色映射,例如通过将组(种族/广告组)映射到角色(1:1)或实施其他映射。每个项目都不同,因此没有必要提供一些实现。
我们基本上在内部使用了它,因此我们可以从头开始使用rbac。如果应用程序正在增长,我们以后仍可以用其他一些实现方式替换它,但是对我们来说,从一开始就正确进行设置很重要。
如果您不使用rbac,则很有可能权限将分散在整个代码库中,以后您将很难提取/将这些权限(分组为角色)。 生成的图形也确实有助于对此进行推理/稍后对其进行重构。
答案 6 :(得分:0)
从Baeldung阅读此post之后。我发现解决方案非常简单。
我所做的是将角色和权限添加到GrantedAuthority中。 我可以访问hasRole()和hasAuthority()这两种方法。