I am using spring security for authentication and successfully able to get User
object (org.springframework.security.core.userdetails.User
) anywhere I
A better way of doing this is to create a UserDetaisService that returns an object that extends your type of Object and implements UserDetails. This means you only need to perform one database lookup.
By having the result of loadUserByUsername implement UserDetails and extend your User object, you can refer to it as the custom user object and Spring Security can refer to it as a UserDetails.
For example:
@Service
public class UserRepositoryUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
@Autowired
public UserRepositoryUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = userRepository.findByEmail(username);
if(user == null) {
throw new UsernameNotFoundException("Could not find user " + username);
}
return new UserRepositoryUserDetails(user);
}
private final static class UserRepositoryUserDetails extends User implements UserDetails {
private UserRepositoryUserDetails(User user) {
super(user);
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return AuthorityUtils.createAuthorityList("ROLE_USER");
}
@Override
public String getUsername() {
return getEmail();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
private static final long serialVersionUID = 5639683223516504866L;
}
}
You can then refer to the custom UserDetailsService in your configuration. For example:
If you are using Spring Security 3.2.x+ you can use Spring Security's @AuthenticationPrincipal to resolve the custom user object. For example:
@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {
// .. find messags for this user and return them ...
}
Otherwise you can use the following:
@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(Authentication auth) {
User customUser = (User) auth.getPrincipal();
...
}
If using the XML configuration, you will need to register AuthenticationPrincipalArgumentResolver with Spring MVC.
You can find details about this in my github sample project. The README also reference the recorded webinar.