Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manually set an authenticated user in Spring Security / SpringMVC

After a new user submits a 'New account' form, I want to manually log that user in so they don't have to login on the subsequent page.

The normal form login page going through the spring security interceptor works just fine.

In the new-account-form controller I am creating a UsernamePasswordAuthenticationToken and setting it in the SecurityContext manually:

SecurityContextHolder.getContext().setAuthentication(authentication); 

On that same page I later check that the user is logged in with:

SecurityContextHolder.getContext().getAuthentication().getAuthorities(); 

This returns the authorities I set earlier in the authentication. All is well.

But when this same code is called on the very next page I load, the authentication token is just UserAnonymous.

I'm not clear why it did not keep the authentication I set on the previous request. Any thoughts?

  • Could it have to do with session ID's not being set up correctly?
  • Is there something that is possibly overwriting my authentication somehow?
  • Perhaps I just need another step to save the authentication?
  • Or is there something I need to do to declare the authentication across the whole session rather than a single request somehow?

Just looking for some thoughts that might help me see what's happening here.

like image 843
David Parks Avatar asked Jan 12 '11 02:01

David Parks


People also ask

How do I manually set an authenticated user in Spring Security?

To, let's manually trigger authentication and then set the resulting Authentication object into the current SecurityContext used by the framework to hold the currently logged-in user: UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(user, pass); Authentication auth = authManager.


2 Answers

I couldn't find any other full solutions so I thought I would post mine. This may be a bit of a hack, but it resolved the issue to the above problem:

public void login(HttpServletRequest request, String userName, String password) {      UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(userName, password);      // Authenticate the user     Authentication authentication = authenticationManager.authenticate(authRequest);     SecurityContext securityContext = SecurityContextHolder.getContext();     securityContext.setAuthentication(authentication);      // Create a new session and add the security context.     HttpSession session = request.getSession(true);     session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext); } 
like image 127
Stuart McIntyre Avatar answered Sep 19 '22 17:09

Stuart McIntyre


I had the same problem as you a while back. I can't remember the details but the following code got things working for me. This code is used within a Spring Webflow flow, hence the RequestContext and ExternalContext classes. But the part that is most relevant to you is the doAutoLogin method.

public String registerUser(UserRegistrationFormBean userRegistrationFormBean,                            RequestContext requestContext,                            ExternalContext externalContext) {      try {         Locale userLocale = requestContext.getExternalContext().getLocale();         this.userService.createNewUser(userRegistrationFormBean, userLocale, Constants.SYSTEM_USER_ID);         String emailAddress = userRegistrationFormBean.getChooseEmailAddressFormBean().getEmailAddress();         String password = userRegistrationFormBean.getChoosePasswordFormBean().getPassword();         doAutoLogin(emailAddress, password, (HttpServletRequest) externalContext.getNativeRequest());         return "success";      } catch (EmailAddressNotUniqueException e) {         MessageResolver messageResolvable                  = new MessageBuilder().error()                                       .source(UserRegistrationFormBean.PROPERTYNAME_EMAIL_ADDRESS)                                       .code("userRegistration.emailAddress.not.unique")                                       .build();         requestContext.getMessageContext().addMessage(messageResolvable);         return "error";     }  }   private void doAutoLogin(String username, String password, HttpServletRequest request) {      try {         // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated         UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);         token.setDetails(new WebAuthenticationDetails(request));         Authentication authentication = this.authenticationProvider.authenticate(token);         logger.debug("Logging in with [{}]", authentication.getPrincipal());         SecurityContextHolder.getContext().setAuthentication(authentication);     } catch (Exception e) {         SecurityContextHolder.getContext().setAuthentication(null);         logger.error("Failure in autoLogin", e);     }  } 
like image 25
KevinS Avatar answered Sep 19 '22 17:09

KevinS