13

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.

2 Answers 2

12

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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()   

3 Comments

That didnt change anything. Btw. your last code snippet gives me: "java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to ..........CustomUserDetails"
can you debug your app and say what class will return SecurityContextHolder.getContext().getAuthentication().getPrincipal() ?
class org.springframework.security.core.userdetails.User

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.