I am using Spring Security in my application. I need loggedIn user details in the controllers of my application.
For that I am using this code
User loggedInUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
But on running this code I get a classcastexception
java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to model.User
To fix this I referred to this article
Initially I used a CustomUserServiceDetails class
@Service("myUserDetailService")
@Transactional
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger logger = Logger.getLogger(CustomUserDetailsService.class);
@Autowired
private UserDAO userDAO;
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException {
// returns the get(0) of the user list obtained from the db
User domainUser = userDAO.getUser(name);
logger.debug("User fetched from database in loadUserByUsername method " + domainUser);
Set<Role> roles = domainUser.getRole();
logger.debug("role of the user" + roles);
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(Role role: roles){
authorities.add(new SimpleGrantedAuthority(role.getRole()));
logger.debug("role" + role + " role.getRole()" + (role.getRole()));
}
boolean credentialNonExpired = true;
return new org.springframework.security.core.userdetails.User(domainUser.getProfileName(), domainUser.getPassword(), domainUser.isAccountEnabled(),
domainUser.isAccountNonExpired(), credentialNonExpired, domainUser.isAccountNonLocked(),authorities);
}
}
But after referring to the article I removed the setting of GrantedAuthorities from here and moved it to my User class. Implemented spring-security UserDetails class in my User class
Now I have an extra property in my User class
@Entity
@Table(name = "user")
public class User implements UserDetails {
private Collection<GrantedAuthority> authorities;
with a setMethod
public void setAuthorities(Set<Role> roles) {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(Role role: roles){
authorities.add(new SimpleGrantedAuthority(role.getRole()));}
}
A. I am not sure how to map this property to the database. The existing User table schema doesn't contain a GrantedAuthority column besides It's not even a primitive type. I am using Hibernate for object mapping. Can anyone advice me the correct approach to obtain the user class info in the controllers?
B. I also considered the approach of extending the spring's User class and overloading the constructor of my User class. But then every time I initialize my User anywhere in the code I have to provide all the constructors parameters which is not good at all.
Fixed the issue
Solution
Created a CustomUserDetail class which implements Spring's UserDetails interface. Injected my model User class in it.
public class CustomUserDetail implements UserDetails{
private static final long serialVersionUID = 1L;
private User user;
Set<GrantedAuthority> authorities=null;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<GrantedAuthority> authorities)
{
this.authorities=authorities;
}
public String getPassword() {
return user.getPassword();
}
public String getUsername() {
return user.getProfileName();
}
public boolean isAccountNonExpired() {
return user.isAccountNonExpired();
}
public boolean isAccountNonLocked() {
return user.isAccountNonLocked();
}
public boolean isCredentialsNonExpired() {
return user.isCredentialsNonExpired();
}
public boolean isEnabled() {
return user.isAccountEnabled();
}
}
CustomUserServiceDetails
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserDAO userDAO;
public CustomUserDetail loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException {
// returns the get(0) of the user list obtained from the db
User domainUser = userDAO.getUser(name);
Set<Role> roles = domainUser.getRole();
logger.debug("role of the user" + roles);
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(Role role: roles){
authorities.add(new SimpleGrantedAuthority(role.getRole()));
logger.debug("role" + role + " role.getRole()" + (role.getRole()));
}
CustomUserDetail customUserDetail=new CustomUserDetail();
customUserDetail.setUser(domainUser);
customUserDetail.setAuthorities(authorities);
return customUserDetail;
}
}
In my controller method
CustomUserDetail myUserDetails = (CustomUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Integer userId=myUserDetails.getUser().getUserId(); //Fetch the custom property in User class
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