Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add new user to Spring Security at runtime

Tags:

I save users in a DB table via Hibernate and I am using Spring Security to authenticate:

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.authentication.builders.*;
import org.springframework.security.config.annotation.web.configuration.*;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}

And this works perfectly, but there is a point - user is loaded during server start. I need to write method RegisterUser(User user) that add new user to Spring Security in runtime. This method should focus only on this task. I dont know how to start to implement this feature so thanks for any advices! ;)

Ofc User have fields like login, password, role string etc etc...

Please do not post solutions with Spring MVC. This system is RESTful app using Spring Web Boost and Spring Security Boost in version 4.0.x

like image 581
Przemysław Malinowski Avatar asked Aug 27 '15 08:08

Przemysław Malinowski


2 Answers

You probably want to store your users in a database and not in memory, if they are registering :)

  1. Create the authorities for the user

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
    
  2. Instantiate the user (with a class implementing UserDetails)

    UserDetails user = new User("[email protected]", passwordEncoder.encode("s3cr3t"), authorities);
    
  3. Save the user somewhere useful. The JdbcUserDetailsManager can save a user to a database easily.

    userDetailsManager.createUser(user);
    
  4. Create a UsernamePasswordAuthenticationToken

    Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, authorities);
    
  5. Add the Authentication to the SecurityContext

    SecurityContextHolder.getContext().setAuthentication(authentication);
    
like image 99
Neil McGuigan Avatar answered Sep 22 '22 06:09

Neil McGuigan


You can use Spring Data JPA for user creation.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

usage:

User user = new User();
userRepository.save(user);

How to authenticate above user:

  1. Create custom AuthenticationProvider, select user data from your DB and authenticate:
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserRepository userRepository;

    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        final UsernamePasswordAuthenticationToken upAuth = (UsernamePasswordAuthenticationToken) authentication;
        final String name = (String) authentication.getPrincipal();

        final String password = (String) upAuth.getCredentials();

        final String storedPassword = userRepository.findByName(name).map(User::getPassword)
            .orElseThrow(() -> new BadCredentialsException("illegal id or passowrd"));

        if (Objects.equals(password, "") || !Objects.equals(password, storedPassword)) {
            throw new BadCredentialsException("illegal id or passowrd");
        }

        final Object principal = authentication.getPrincipal();
        final UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(
            principal, authentication.getCredentials(),
            Collections.emptyList());
        result.setDetails(authentication.getDetails());

        return result;
    }
    ...
  1. Configure with WebSecurityConfigurerAdapter for using above AuthenticationProvider:
@EnableWebSecurity
public class MyWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAuthenticationProvider authProvider;

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .httpBasic();
        http.authenticationProvider(authProvider);
    }
}

refs:

  • Spring Security Architecture
  • complete code sample
like image 27
DEWA Kazuyuki - 出羽和之 Avatar answered Sep 20 '22 06:09

DEWA Kazuyuki - 出羽和之