Spring - 从控制器调用自定义身份验证提供程序

7

我在Spring Security配置中定义了一个自定义认证提供者。这个类实现了AuthenticationProvider接口,我可以成功地使用页面上定义的表单登录。问题是,我不仅想在登录页面上调用这个类,还想在注册页面上调用它。

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

我尝试在注册控制器中创建一个org.springframework.security.Authentication类,并在我的自定义AuthenticationProvider类上调用authenticate方法,这没有出错,但用户没有登录。我必须调用Spring Security过滤器链中更高级别的方法才能完成这个操作吗?我应该将控制器重定向到j_spring_security_check URL吗?如果是这样,我应该如何传递用户名/密码?

2个回答

3
您的问题在于,虽然您已成功验证了用户,但没有将此身份验证结果存储在用户的SecurityContext中。在Web应用程序中,这是一个ThreadLocal对象SecurityContextPersistenceFilter将使用它来将用户凭据存储在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()方法,将认证结果以记住我Cookie的形式存储在此时。


3
你需要将AuthenticationProvider.authenticate()的结果放入SecurityContext中(从SecurityContextHolder获取)。
同时要注意AuthenticationSuccessEvent - 如果你的应用程序依赖于此事件(一些Spring Security功能也可能使用它),你应该发布它(可以通过自动装配获取默认的AuthenticationEventPublisher)。将你的身份验证提供程序包装在ProviderManager中可能很有用,它会自动使用给定的发布者发布事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接