Spring Security custom UserDetailsService and custom User class
Solution 1
Ok. My problem was hidden in the code i didnt post.
I thought this detailsService is only to get additional details but it is used for the login itself.
I had "jdbcAuthentication" configured additionally and spring seemed to use this always.
Now that i only got the detailsService configured everything works fine.
edit.:
so i only had to delete this code:
auth.jdbcAuthentication() .dataSource(dataSource)
* .passwordEncoder(passwordEncoder) .usersByUsernameQuery(
// ....
And now it also works with my code in the question above.
Solution 2
Create Extention class:
public class CustomUserDetails extends org.springframework.security.core.userdetails.User{
private User user;
public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities) {
super(user.getName(), user.getPassword(), authorities);
this.user = user;
}
public CustomUserDetails(User user, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
super(user.getName(), user.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.user = user;
}
public User getUser() {
return user;
}
}
Than add it to UserDetailsService:
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = null;
User user = userService.getByLogin(login);
userDetails = new CustomUserDetails(user,
true, true, true, true,
getAuthorities(user.getRole()));
return userDetails;
}
Get it!
(CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()
jvecsei
Updated on July 09, 2022Comments
-
jvecsei almost 2 years
I am trying to save additional data in de user principal object.
What i did was:
implement the "UserDetails" interface to my existing user class where my additional data is saved ( like email address etc. ).
@Entity public class User implements UserDetails {
Then i created a UserDetailsService implementation:
@Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired UserDAO userDAO; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userDAO.findOneByUsername(username); if (user == null) throw new UsernameNotFoundException("username " + username + " not found"); System.out.println("---------------------> FOUND ------------->" + user.getEmail()); return user; } }
Last step was to add the UserDetailsService in my Security configuration.
@Configuration @EnableWebMvcSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()); // ... } @Override protected void configure(HttpSecurity http) throws Exception { http.userDetailsService(userDetailsService()); // ... } @Override protected UserDetailsService userDetailsService() { return userDetailsService; }
I see in my console that "loadUserByName" gets called twice ( because of the "Found" output ).
When i try to access the principal object in my controller ->
System.out.println(SecurityContextHolder.getContext() .getAuthentication().getPrincipal());
I dont get my additional data. When i try to cast it to my User object i get a could not cast exception.
Is there anything I am missing??
Thank you in advance.
-
jvecsei over 9 yearsThat didnt change anything. Btw. your last code snippet gives me: "java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to ..........CustomUserDetails"
-
hleb.albau over 9 yearscan you debug your app and say what class will return
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
? -
jvecsei over 9 yearsclass org.springframework.security.core.userdetails.User