当Spring Security对用户进行身份验证时,如何在会话中管理自定义用户对象?

时间:2009-12-08 11:00:32

标签: java spring-security

Spring Security对用户进行身份验证时,它会创建一个UserDetail对象,并且可以在web-app中查找当前的UserId。但是,假设我想保留一个自定义用户对象,其中包含首选项和其他详细信息以及UserDetails或替换UserDetails。

因此,在Spring Security进行身份验证时如何向会话添加自定义用户对象 成功?以及如何在Spring Security注销登录用户时从会话中删除自定义用户对象。

或者有没有合适的方法来做到这一点?

2 个答案:

答案 0 :(得分:18)

执行此操作的最佳方法IMO是让您的某个服务(可能是UserService)实现UserDetailsS​​ervice,并在spring security XML中指定您希望使用自己的用户详细信息服务。

UserDetailsS​​ervice需要做的是实现loadByUsername(String username)方法。此方法需要返回实现UserDetails的类。这可以是您自己的自定义对象存储您喜欢的任何内容。这样做的好处是,您可以通过spring security taglib从JSP访问对象的属性,并且它也始终可以从Spring Security Security中的SecurityContextHolder单例(线程安全)中获得。

以下是此文档的链接:spring security manual, chapter 8 这篇博客文章讨论了为密码加密实现自定义用户详细信息服务:example usage

希望这有帮助

编辑:忘记提及在注销时将从安全上下文和会话中删除该对象。这是最有用的,它完全由春季安全管理。

答案 1 :(得分:0)

你绝对需要自己编写UserDetailService。在Principal对象中有用户,AuthenticationToken中还有一个Details对象,您可以存储其他登录信息的Map(String,String)。

public class RequestFormDeatils extends SpringSecurityFilter {

   protected void doFilterHttp(HttpServletRequest request, ...) {
      SecurityContext sec = SecurityContextHolder.getContent();
      AbstractAuthenticationToken auth = (AbstractAuthenticationToken)sec.getAuthentication();
      Map<String, String> m = new HashMap<String, String>;
      m.put("myCustom1", request.getParameter("myCustom1"));
      m.put("myCustom2", request.getParameter("myCustom2"));
      auth.setDetails(m);
}

现在,您的代码中的任何位置都可以使用SecurityContext传播此安全相关信息,而无需将其与您的UserDetails对象耦合,或将其作为参数传递。我在Spring安全过滤器链末尾的SecurityFilter中执行此代码。

<bean id="requestFormFilter" class="...RequestFormDetails">
   <custom-filter position="LAST" />
</bean> 

删除用户时会删除此信息(例如在注销时)。