我想将角色视为用户的属性而不是具有独立的角色类,因此我不需要在我的数据库中拥有角色表。但通用弹簧UserDetails
服务将GrantedAuthority
(即Collection<GrantedAuthority> getAuthorities())
)作为用户详细信息参数之一传递。
我想要做的是将此通用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;
}
}
我的customUserdetail服务类:
@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);
}
}
}
它返回错误,因为我传递了user.getRole()
,这是String,而不是Collection<GrantedAuthority> getAuthorities()
,这是spring security中的默认角色类型。
如何自定义它以便我可以使用我已声明为“用户”类属性的角色(字符串类型)?
Mind:
必须保留正常的安全流程!意思是,不影响正常的弹簧安全流程。
提前谢谢你!
答案 0 :(得分:3)
您的数据模型与Spring Security及其合同明显不同。对于whit,在Spring Security中,用户可以拥有多个角色。这是其界面所规定的合同的一部分。您建议的数据模型违反了这一规定,因此如果没有我称之为“Frankensteining”的大量内容,则无法使用Spring Security。您还将失去Spring Security设计带来的极大灵活性。简而言之,它的努力程度超过了它的价值。
答案 1 :(得分:3)
可以通过User实体实现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_”前缀启动它。