Search code examples
javaspringspring-mvcspring-security

SPRING: Add custom user details to spring security user


I'm currently working on a Spring MVC application and I need to add a custom field to my Spring Security log-in user right when I log in (I insert username, password, custom value). This value needs to be available on everywhere when the user is logged in (e.g. via pricipal.getValue).

I read a lot about custom user classes and custom services, but can't really find a working solution for my problem...

Any help would be great!


Solution

  • 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