【问题标题】:java spring : how can I separate user roles and authorities?java spring:如何分离用户角色和权限?
【发布时间】:2021-07-09 19:03:19
【问题描述】:

我目前的理解是 Spring 不区分角色和权限,唯一的区别是角色名称的 ROLE_ 首字母缩写词。

我希望实现的是具有权限的角色。 Aka 如果我给用户角色 ADMIN,他将获得所有相关的权限(例如,访问网站上的路由以更新页面的权限)

我当前的实现如下:我有一个自定义的 Privilege 类,它与 Roles 类具有多对多关系,而 Roles 类与用户类具有多对多关系。当调用 UserDetails 的public Collection<? extends GrantedAuthority> getAuthorities() 时,它会遍历所有权限并获取。

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    for (Role role : this.roles) {
        for (Privilege pri : role.getPrivileges()) {
            SimpleGrantedAuthority auth = new SimpleGrantedAuthority(pri.getName());
            if (!authorities.contains(auth)) {
                authorities.add(auth);
            }
        }
    }
    return authorities;
}

我的问题:有没有更好的方法来做到这一点(最好是原生于 Spring Security)?

EDIT :角色位于数据库中,以允许动态插入新角色。目前权限也是如此,但可能会被删除以进行硬编码(动态权限在此特定实现中没有多大意义)

【问题讨论】:

    标签: java spring spring-security


    【解决方案1】:

    您需要扩展 WebSecurityConfigurerAdapter 来实现这一点,如下所示:

    @Configuration
    @EnableWebSecurity
    @ComponentScan(basePackages = "com.spring.boot.rocks")
    public class ConfigWebSecurity extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests().antMatchers("/css/**")
                .permitAll();
    httpSecurity.authorizeRequests().antMatchers("/only/for/admin/**").access("hasAuthority('ADMIN')")
    ....
    ....
    }
    

    这就是您如何使用 Spring Security 限制/允许对不同端点/URI 的访问。注意最后一行,它限制了所有以/only/for/admin 开头的 URL 的访问权限,以访问除 Admin 之外的所有角色/权限。希望你明白了。有关完整示例,请查看 herehere

    【讨论】:

      【解决方案2】:

      您可以公开RoleHierarchy bean 以在角色和权限之间创建层次结构。

      @Bean
      public RoleHierarchy roleHierarchy() {
          RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
          roleHierarchy.setHierarchy(
                  "ROLE_ADMIN > AUTHORITY_READ\n" +
                  "ROLE_ADMIN > AUTHORITY_WRITE\n" +
                  "ROLE_USER > AUTHORITY_READ");
          return roleHierarchy;
      }
      

      此示例表明,如果用户拥有ROLE_ADMIN,那么他们也拥有AUTHORITY_READAUTHORITY_WRITE
      如果用户拥有ROLE_USER,那么他们也拥有AUTHORITY_READ

      您可以使用换行符\n 分隔多个角色层次结构。

      【讨论】:

      • 有没有办法让它动态化? (抱歉回复晚了)我希望将角色放在数据库中,以便添加/删除权限,并在运行时创建新角色而无需重新编译
      【解决方案3】:

      最后我选择了这个方法:

      @Override
      public Collection<? extends GrantedAuthority> getAuthorities() {
          List<SimpleGrantedAuthority> authorities = new ArrayList<>();
          for (Role role : this.roles) {
              insert_auth(authorities, "ROLE_" + role.getName());
              for (Privilege pri : role.getPrivileges()) {
                  insert_auth(authorities, pri.getName());
              }
          }
          return authorities;
      }
      

      它的最大优势是它在每个端点请求时被调用,使其成为动态的(我可以添加/删除角色和权限,而无需用户注销/登录使其生效)

      这也让我可以相对轻松地进行扩展,因为它可以通过界面和/或脚本进行控制

      【讨论】:

        猜你喜欢
        • 2020-03-26
        • 2016-02-27
        • 2022-08-09
        • 2012-08-27
        • 1970-01-01
        • 2020-10-20
        • 1970-01-01
        • 2015-10-28
        相关资源
        最近更新 更多