在Spring Security中排除用户详细信息中的GrantedAuthority。

5
我希望将角色考虑为用户属性,而不是独立的角色类,因此我不需要在我的数据库中有一个角色表。但是通用的Spring UserDetails服务通过其中一个用户详细参数 Collection<GrantedAuthority> getAuthorities() 传递GrantedAuthority(即授予权限)。

我想做的是将这个通用的GrantedAuthority参数替换为在我的“User”类中声明的角色(String role),如下所示。
@Entity(name="usr")
public class User {
    @Id
    @Column(unique=true)
    private String username;
    private String password;
    private String role;

    public String getUsername() {               
        return username;        
    }

    public void setUsername(String username) {          
        this.username = username;       
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

以下是我的自定义用户详细信息服务类:

@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository repository;

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {               
        try {
            x.y.User  user = repository.findByUsername(username);

            boolean enabled = true;
            boolean accountNonExpired = true;
            boolean credentialsNonExpired = true;
            boolean accountNonLocked = true;

            return new User(
                    user.getUsername(), 
                    user.getPassword(),
                    enabled,
                    accountNonExpired,
                    credentialsNonExpired,
                    accountNonLocked,
                    user.getRole());        

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }               
}

由于我传递的是String类型的user.getRole()而不是默认角色类型Collection<GrantedAuthority> getAuthorities(),所以它返回了错误。

我该如何自定义它,以便我可以使用我在“User”类中声明为属性的角色(即字符串类型)?

注意:必须保留正常的安全流程!这意味着不能影响正常的Spring Security流程。

提前致谢!

2个回答

5

您可以通过实现UserDetails接口来对您的用户实体进行操作,并重写getAuthorities()方法:

public class User implements UserDetails {
    ...
    private String role;
    ...

    @Override
    public Set<GrantedAuthority> getAuthorities() {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(this.role));
        return authorities;
    }
}

最好遵循Spring Security的角色名称约定,即以"ROLE_"前缀开头。


我也尝试过同样的事情。但是当调用 getAuthorities() 方法时,this.role 总是为空。 - annoirq

4

你的数据模型与Spring Security及其约定明显不同。在Spring Security中,一个用户可以拥有多个角色,这是其接口规定的一部分。你提出的数据模型违反了这一规定,因此无法与Spring Security配合使用,除非进行大量的“弗兰肯斯坦式”的修改。你还将失去Spring Security设计带来的很多灵活性。简而言之,这并不值得付出更多的努力。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接