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?
Just looking for some thoughts that might help me see what's happening here.
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.
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); }
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With