I want to consider role as an attribute of a user rather than having an independent role class, hence I don't need to have a table for roles in my DB. But the generic spring UserDetails
service passes GrantedAuthority
(i.e. Collection<GrantedAuthority> getAuthorities())
as one of the user detail parameters.
What I want to do is replacing this generic GrantedAuthority
parameter with a role (String role) declared in my 'User' class as shown below.
@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;
}
}
And my customUserdetail service class:
@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);
}
}
}
It returns an error since I passed user.getRole()
, which is String, instead of Collection<GrantedAuthority> getAuthorities()
, which is the default role type in spring security.
how can I customize it so that I can use the role (which is a string type) I've declared as an attribute of the 'User' class?
Mind:
the normal security flow must be preserved!. meaning, without affecting the normal spring security flow.
Thank you in advance!.
It can be done by implementing UserDetails interface by your User entity and overriding getAuthorities() method:
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;
}
}
And it's better to keep to Spring Security naming convention for role names, i.e. to start it with the "ROLE_" prefix.
Your data model is decidedly different from Spring Security and its contract. To whit, in Spring Security, a user can have multiple roles.. This is part of the contract laid out by its interfaces. Your proposed data model violates that, and hence could not be made to work with Spring Security without a tremendous amount of what I like to call "Frankensteining". You'd also lose a great deal of flexibility that comes with the Spring Security design. In short, it's more effort than it's worth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With