Programmatically log-in a user using spring security

Spring MvcSpring Security

Spring Mvc Problem Overview


The opposite of: https://stackoverflow.com/q/5727380/106261

In my app I have register new user screen, which posts to a controller which creates a new user within db (and does a few obvious checks).I then want this new user to be automatically logged in ... I kind of want somethign like this :

SecurityContextHolder.getContext().setPrincipal(MyNewUser);

Edit Well I have almost implemented based on the answer to https://stackoverflow.com/q/7614541/106261

 Authentication auth = new UsernamePasswordAuthenticationToken(MyNewUser, null);
 SecurityContextHolder.getContext().setPrincipal(MyNewUser);

However, when deployed the jsp can not access my MyNewUser.getWhateverMethods() whereas it does when normal login procedure followed. the code that works nomrally, but throws an error when logged in like above is below :

<sec:authentication property="principal.firstname" /> 

Spring Mvc Solutions


Solution 1 - Spring Mvc

In my controller i have this, which logs user in as normal :

Authentication auth = 
  new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
   
SecurityContextHolder.getContext().setAuthentication(auth);

Where user is my custom user object(implementing UserDetails) that is newly created. The getAuthorities() method does this (just because all my users have the same role):

public Collection<GrantedAuthority> getAuthorities() {
		//make everyone ROLE_USER
		Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
		GrantedAuthority grantedAuthority = new GrantedAuthority() {
			//anonymous inner type
			public String getAuthority() {
				return "ROLE_USER";
			}
		}; 
		grantedAuthorities.add(grantedAuthority);
		return grantedAuthorities;
	}

Solution 2 - Spring Mvc

You can also inject your spring security configured UserDetailsManager to your controller and use that to get the UserDetails which holds the principal and authorities to avoid duplicate code:

// inject

@Autowired
private UserDetailsManager manager; 

// use in your method

UserDetails userDetails = manager.loadUserByUsername (token.getUsername ());
Authentication auth = new UsernamePasswordAuthenticationToken (userDetails.getUsername (),userDetails.getPassword (),userDetails.getAuthorities ());
SecurityContextHolder.getContext().setAuthentication(auth);

Solution 3 - Spring Mvc

From the spring security source AbstractAuthenticationProcessingFilter:

protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        Authentication authResult) throws IOException, ServletException {

    if (logger.isDebugEnabled()) {
        logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
    }

    // you need this
    SecurityContextHolder.getContext().setAuthentication(authResult);

    rememberMeServices.loginSuccess(request, response, authResult);

    if (this.eventPublisher != null) {
        eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
    }

    successHandler.onAuthenticationSuccess(request, response, authResult);
}

Note however that the SecurityContextHolder is usually cleared upon completion of the filter chain.

Solution 4 - Spring Mvc

For anyone trying to do this with Reactive Spring Security, this is what I did and it seemed to work.

private Mono<Authentication> authenticateUser(ServerWebExchange exchange, UserDetails userDetails,String rawPassword) 
	{
		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails.getUsername(),rawPassword);
		
		return reactiveAuthenticationManager.authenticate(token).filter(auth -> auth.isAuthenticated()).flatMap(auth ->
		{
			SecurityContextImpl securityContext = new SecurityContextImpl();
			securityContext.setAuthentication(auth);
			return securityContextRepository.save(exchange,securityContext).then(Mono.just(auth));
		});
	}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNimChimpskyView Question on Stackoverflow
Solution 1 - Spring MvcNimChimpskyView Answer on Stackoverflow
Solution 2 - Spring MvcokrunnerView Answer on Stackoverflow
Solution 3 - Spring MvcSimeonView Answer on Stackoverflow
Solution 4 - Spring MvcShy AlbatrossView Answer on Stackoverflow