SPRING: Add custom user details to spring security user

Just like Avinash said, you can make your User class implement UserDetails and you can also implement UserDetailsService and override corresponding methods to return the custom User object:

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    //get user from the database, via Hibernate
    @Autowired
    private UserDao userDao;

    @Transactional(readOnly=true)
    @Override
    public UserDetails loadUserByUsername(final String username)
        throws UsernameNotFoundException {
//CUSTOM USER HERE vvv
        User user = userDao.findByUserName(username);
        List<GrantedAuthority> authorities =
                                      buildUserAuthority(user.getUserRole());
//if you're implementing UserDetails you wouldn't need to call this method and instead return the User as it is
        //return buildUserForAuthentication(user, authorities);
return user;

    }

    // Converts user to spring.springframework.security.core.userdetails.User
    private User buildUserForAuthentication(user,
        List<GrantedAuthority> authorities) {
        return new User(user.getUsername(), user.getPassword(),
            user.isEnabled(), true, true, true, authorities);
    }

    private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {

        Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

        // add user's authorities
        for (UserRole userRole : userRoles) {
            setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
        }

        List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

        return Result;
    }

}

And you just configure your WebConfigurerAdapter using the custom UserdetailsService :

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    //authorization logic here ...
}

    @Bean
    public PasswordEncoder passwordEncoder(){
        // return preferred PasswordEncoder ...//
    }


}

Here, a sample of a custom UserDetails implementation: custom UserDetails


Create your class implementing UserDetails interface.

public class User implements UserDetails {
    // Your user properties
    // implement methods
}

And then, once authenticated, you can access this object anywhere in the project like this.

User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

I had worked on this in the following way.

AccountDetailsService.java

@Service
public class AccountDetailsService implements UserDetailsService {

    @Autowired
    AccountRepository accountRepository;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException, JSONException {
        return loadUser(s);
    }

    public UserDetails loadUserByUsernameWithoutCredentials(String s) throws UsernameNotFoundException, JSONException {
        CustomUserDetails customUserDetails=loadUser(s);
        if (customUserDetails != null){
            customUserDetails.eraseCredentials();
        }
        return customUserDetails;
    }

    private CustomUserDetails loadUser(String s) throws UsernameNotFoundException, JSONException {

        Account userAccount = accountDbRepository.getAccountByUserName(s);
        if (userAccount==null){
            return null;
        }
        Collection<GrantedAuthority> grantedAuthoritySet = new HashSet<>();

        for (int i=0; i<userAccount.getRoles().size();i++)
        {
            JSONObject jsonObject = new JSONObject(userAccount.getRoles().get(i));
            String role = jsonObject.getString("role");
            gas.add(new SimpleGrantedAuthority(role));
        }
        return new CustomUserDetails(userAccount.getEmail(),userAccount.getDisplayName(),userAccount.getUserName(),userAccount.getPassword(),userAccount.getEnabled(),gas);

    }

}

CustomUserDetails.java

public class CustomUserDetails implements UserDetails {

private Collection<? extends GrantedAuthority> authorities;

private String email;

private String displayName;

private String password;

private String username;

private Boolean enabled;

private Boolean accountNonExpired;

private Boolean accountNonLocked;

private boolean credentialsNonExpired;

public CustomUserDetails(String email, String displayName, String username, String password, Boolean enabled, Collection<? extends GrantedAuthority> authorities) {
    this.email = email;
    this.displayName = displayName;
    this.enabled=enabled;
    this.username=username;
    this.password=password;
    this.accountNonExpired=true;
    this.accountNonLocked=true;
    this.credentialsNonExpired=true;
    this.authorities=authorities;
}

public CustomUserDetails(String email, String displayName, String password, String username, Boolean enabled, Boolean accountNonExpired, Boolean accountNonLocked, boolean credentialsNonExpired, Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
        this.email = email;
        this.displayName = displayName;
        this.password = password;
        this.username = username;
        this.enabled = enabled;
        this.accountNonExpired = accountNonExpired;
        this.accountNonLocked = accountNonLocked;
        this.credentialsNonExpired = credentialsNonExpired;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    public void eraseCredentials(){
        this.password=null;
    }

}