繁体   English   中英

具有角色和权限的 Spring Security

[英]Spring Security with roles and permissions

我正在尝试使用权限设置基于角色的安全性。 我正在尝试与 Spring-Security 一起执行此操作。

我不想设置 ACL,因为它似乎对我的要求来说太过分了。

我只想拥有本文所述的简单权限和角色。 不幸的是,这篇文章没有描述如何实现给定的解决方案。

有人已经尝试过这个并且可以指出我正确的方向吗? 也许还有另一个博客条目描述了实现?

非常感谢。

我是相关文章的作者。

毫无疑问,有多种方法可以做到这一点,但我通常这样做的方法是实现一个了解角色和权限的自定义UserDetails RolePermission只是您编写的自定义类。 (没有fancy-- Role都有一个名称和一组Permission的情况下,和Permission都有一个名称。)然后getAuthorities()返回GrantedAuthority对象是这个样子的:

PERM_CREATE_POSTPERM_UPDATE_POSTPERM_READ_POST

而不是返回诸如

ROLE_USER , ROLE_MODERATOR

如果您的UserDetails实现具有getRoles()方法,则角色仍然可用。 (我建议有一个。)

理想情况下,您为用户分配角色,并自动填写相关的权限。 这将涉及拥有一个知道如何执行该映射的自定义UserDetailsService ,并且它所要做的就是从数据库中获取映射。 (有关架构,请参阅文章。)

然后,您可以根据权限而不是角色来定义您的授权规则。

希望有帮助。

要实现这一点,您似乎必须:

  1. 创建您的模型(用户、角色、权限)以及检索给定用户权限的方法;
  2. 定义您自己的org.springframework.security.authentication.ProviderManager并将其配置(设置其提供者)为自定义org.springframework.security.authentication.AuthenticationProvider 最后一个应该在其身份验证方法上返回一个身份验证,该身份验证应该使用org.springframework.security.core.GrantedAuthority进行设置,在您的情况下,是给定用户的所有权限。

该文章中的技巧是将角色分配给用户,但是,在Authentication.authorities对象中设置这些角色的权限。

为此,我建议您阅读 API,看看您是否可以扩展一些基本的 ProviderManager 和 AuthenticationProvider 而不是实现所有内容。 我已经通过org.springframework.security.ldap.authentication.LdapAuthenticationProvider设置自定义 LdapAuthoritiesPopulator 来完成该操作,这将为用户检索正确的角色。

希望这次我得到了你要找的东西。 祝你好运。

基本步骤是:

  1. 使用自定义身份验证提供程序

    <bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton"> ... </bean>

  2. 使您的自定义提供程序返回自定义UserDetails实现。 这个UserDetailsImpl将有一个像这样的getAuthorities()

     public Collection<GrantedAuthority> getAuthorities() { List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>(); for (GrantedAuthority role: roles) { permissions.addAll(getPermissionsIncludedInRole(role)); } return permissions; }

当然,从这里您可以针对您的特定要求应用大量优化/自定义。

这是最简单的方法。 允许组权限以及用户权限。

-- 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>

只是为了完整起见(也许其他人不必从头开始实现它):

和其他人一样,我们已经实现了我们自己的小型图书馆。 它应该让事情变得更容易,这样我们的开发人员就不必每次都重新实现它。 如果 spring security 能够提供开箱即用的 rbac 支持那就太好了,因为这种方法比基于默认权限的方法要好得多。

看看Github (OSS,MIT 许可证),看看它是否适合您的需求。 它基本上只解决角色 <-> 权限映射。 您必须自己提供的缺失部分基本上是用户 <-> 角色映射,例如通过将组(racf/ad 组)映射到角色 (1:1) 或通过实施附加映射。 那个在每个项目中都不一样,所以提供一些实现是没有意义的。

我们基本上已经在内部使用了它,因此我们可以从一开始就使用 rbac。 如果应用程序不断增长,我们仍然可以稍后用其他一些实现替换它,但对我们来说在开始时正确设置很重要。

如果您不使用 rbac,则权限很可能分散在整个代码库中,稍后您将很难将它们提取/分组(到角色中)。 生成的图也有助于稍后对其进行推理/重组。

ACL 对我的要求也太过分了。
我最终创建了一个类似于GrantedAuthority的库,以根据用户的角色成员身份为 Role->Permissions 注入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以将关系存储在配置中。

更完整的解释在这里 - https://stackoverflow.com/a/60251931/1308685

源代码在这里 - https://github.com/savantly-net/spring-role-permissions

阅读这篇文章后,来自 Baeldung。 我发现解决方案非常简单。

我所做的是将角色和权限添加到 GrantedAuthority 中。 我能够访问两种方法 hasRole() 和 hasAuthority()。

暂无
暂无

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

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