2010-07-01 132 views
5

我在我的Spring安全配置中定义了定制认证提供程序。这个类实现了AuthenticationProvider,并且我可以使用我的页面上定义的表单成功登录。问题是我想不仅在登录页面上调用此类,而且还从注册页面调用此类。春 - 从控制器呼叫定制认证提供程序

注册页面使用不同的命令类,并收集比登录表单更多的信息。现在,当用户注册时,我会调用相应的控制器,将记录添加到数据库,然后他们可以登录,但不会自动登录。因为他们刚在注册页面给我他们的用户名/密码,我可以将它传递给自定义AuthenticationProvider类,以便他们也登录吗?

我已经尝试在注册控制器中创建一个org.springframework.security.Authentication类,并在我的客户AuthenticationProvider类上调用authenticate方法,并且这不会出错,但用户未登录。我是否必须在Spring Security过滤器链中调用一个更高的方法才能实现这一点?我应该将控制器重定向到j_spring_security_check URL吗?如果是这样,我将如何通过用户名/密码?

回答

1

您需要将AuthenticationProvider.authenticate()的结果写入SecurityContext(从SecurityContextHolder获取)。

也请注意AuthenticationSuccessEvent - 如果您的应用程序依赖于此事件(一些Spring Security功能也可能使用它),您应该发布它(您可以通过自动装配获取默认的AuthenticationEventPublisher)。将身份验证提供程序包装为ProviderManager可能很有用,它会使用给定的发布者自动发布该事件。

2

您遇到的问题是,虽然您已成功验证用户,但您尚未将此验证的结果存储在用户的SecurityContext中。在Web应用程序this is a ThreadLocal object其中SecurityContextPersistenceFilter将使用store the user's credentials in the HTTPSession

你也应该避免,如果你能直接与您的自定义身份验证提供认证。您的xml配置应包含您的自定义身份验证提供程序已连线到的AuthenticationManager。例如,

<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> 

如果接线authenticationManager到您的注册服务,并利用它将另外,

我们的注册服务如下操作

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

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

我们也可选择在这一点上的认证结果存储在记得,我使用的TokenBasedRememberMeServicesonLoginSuccess()方法使用网站