【问题标题】:spring boot security- adding custom role namesspring boot security-添加自定义角色名称
【发布时间】:2022-01-10 06:52:26
【问题描述】:

我正在关注 Spring Boot JPA 身份验证安全教程。我已经为用户和管理员设置了身份验证。

但是在 MySQL 数据库中,我有自定义角色,例如“校长”、“老师”和“学生”

如何将这些自定义角色添加到我的身份验证中。

我假设我需要在 UserDetails 类中执行此操作。到目前为止,这是我的代码

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class UserDetails implements UserDetails {

    private String username;
    private String password;
    private boolean active;
    private List<GrantedAuthority> authorities;

    public MyUserDetails(User user) {
        this.username = user.getUsername();
        this.password = user.getPassword();
        this.active = user.isActive();
        this.authorities = Arrays.stream(user.getTheType().split(","))
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return active;
    }
}

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    对于教程/课程,您可以(尝试)重命名/重构:

    • 角色(用户、管理员...角色或权限?tomayto、tomahto(只需添加/截断ROLE_;)
    • db 列。

    但侵入性最小且非常有效(仅适用于 2 个角色/少数组合)的方法如下:

    // adjust to requirements:
    static final String REGEX_USERS = "student"; // exact match
    static final String REGEX_ADMINS = "(teacher|principal)"; // group OR match
    static final String AUTH_ADMINS = "ADMINS";
    static final String AUTH_USERS = "USERS";
    

    ...然后:

    this.authorities = Arrays.stream(
             user
             .getTheType()
             .replaceAll(REGEX_USERS, USERS)
             .replaceAll(REGEX_ADMINS, ADMINS)
             .split(",")
           )
           .map(SimpleGrantedAuthority::new)
           .collect(Collectors.toList());
    

    独立测试:

    package com.example.demo;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    
    class TestO {
    
      static final String REGEX_USERS = "student";
      static final String REGEX_ADMINS = "(teacher|principal)";
    
      static final String AUTH_ADMINS = "ADMINS";
      static final String AUTH_USERS = "USERS";
    
      public static void main(String[] args) {
    
        String testData1 = "student";
        String testData2 = "teacher,principal";
        List<GrantedAuthority> result1 = Arrays.stream(testData1
            .replaceAll(REGEX_USERS, AUTH_USERS)
            .replaceAll(REGEX_ADMINS, AUTH_ADMINS)
            .split(","))
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toList());
        System.out.format("%s%n", result1);
        List<GrantedAuthority> result2 = Arrays.stream(testData2
            .replaceAll(REGEX_USERS, AUTH_USERS)
            .replaceAll(REGEX_ADMINS, AUTH_ADMINS)
            .split(","))
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toList());
        System.out.format("%s%n", result2);
    
      }
    }
    

    打印:

    [USERS]
    [ADMINS, ADMINS]
    

    如果我关于角色映射的假设(!)是正确的:

    • 所有student都是USERS
    • 所有teacher都是ADMINS
    • 只有 1(少数)principal ..还有ADMIN(还有teacher ?? ...拜托!学校系统差异很大...;-)
    • principal 是唯一一个在他的(权限)列表中有逗号的人!?
    • (不是studentteacher!?)

    那么可能(并且在任何“特定授权”的情况下):

    private java.util.Set<GrantedAuthority> authorities;
    

    ...然后还有:

    Collectors.toSet() // + refacotrings
    

    是首选! (What is the difference between Set and List?!;)

    所以:

    Set<GrantedAuthority> result2 = Arrays.stream(testData2
            .replaceAll(REGEX_USERS, "USERS")
            .replaceAll(REGEX_ADMINS, "ADMINS")
            .split(","))
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toSet());
    System.out.format("%s%n", result2);
    

    打印:

    ...
    [ADMINS]
    

    另见(reg. 高效字符串替换):

    Java Replacing multiple different substring in a string at once (or in the most efficient way)

    【讨论】:

    • 谢谢,如果我想添加一个额外的用户,我该怎么做呢?所以我有三个自定义用户,如果这使得 snese
    • 欢迎您! :-) 对于其他用户:我们将再添加一个正则表达式和replaceAll
    • 如果我们对数据非常了解/有良好的假设,我们可以从中获得更高的效率! (例如。当你知道它是 always teacher, principalnever principal,teacher, ..or that student never has comma ...类似的事情:) ..那么我们甚至不会拆分(+stream+collect),而是替换! ;)
    • ..或“只要有逗号,它就是管理员”! :):) ..和测试测试测试! :)
    猜你喜欢
    • 2016-01-17
    • 2016-10-16
    • 2014-12-26
    • 2011-07-21
    • 1970-01-01
    • 2018-09-22
    • 2018-10-28
    • 2013-05-20
    • 2021-11-22
    相关资源
    最近更新 更多