Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring - Call custom-authentication-provider from a controller

I have a custom-authentication-provider defined in my Spring Security configuration. This class implements AuthenticationProvider, and I can successfully log in using the form defined on my page. The issue is I want to call this class not just on the login page, but from the registration page as well.

The registration page uses a different command class and collects more information than the login form. Right now, when the user registers, I call the appropriate controller, add the record to the database and they can then log in but they aren't logged in automatically. As they've just given me their user name/password on the registration page, can I then pass this to the custom AuthenticationProvider class so they are also logged in?

I've tried creating an org.springframework.security.Authentication class in the registration controller and calling the authenticate method on my customer AuthenticationProvider class, and this doesn't error out, but the user isn't logged in. Do I have to call a method higher in the Spring Security filter chain to accomplish this? Should I redirect the controller to the j_spring_security_check URL? If so, how would I pass the username/password?

like image 301
David Buckley Avatar asked Jul 01 '10 17:07

David Buckley


1 Answers

The problem you are having is that although you have successfully authenticated the user you have not stored the result of this authentication in the user's SecurityContext. In a web application this is a ThreadLocal object which the SecurityContextPersistenceFilter will use to store the user's credentials in the HTTPSession

You should also avoid authenticating directly with your custom authentication provider if you can. Your xml configuration should contain an AuthenticationManager which your custom authentication provider has been wired into. For example,

<bean id="customAuthenticationProvider" 
  class="com.foo.CustomAuthenticationProvider">
  <property name="accountService" ref="accountService"/>
</bean>
<security:authentication-manager alias="authenticationManager">
  <security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>

If you wire the authenticationManager into your registration service and authenticate using that it will additionally,

  • allow you to swap in/out additional authentication providers at later points
  • publish the authentication result to other parts of the Spring Security framework (eg success/failure Exception handling code)

Our registration service does this as follows

final UsernamePasswordAuthenticationToken authRequest = new 
  UsernamePasswordAuthenticationToken(username, password);

final Authentication authentication = 
  authenticationManager.authenticate(authRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);

We also optionally store the authentication result at this point in a remember-me cookie using the onLoginSuccess() method of TokenBasedRememberMeServices.

like image 197
Caoilte Avatar answered Oct 24 '22 19:10

Caoilte