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

2022-09-02 10:35:41

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

那么,当Spring Security成功通过认证时,如何将自定义用户对象添加到会话中呢?以及如何在Spring Security注销登录用户时从会话中删除自定义用户对象。

或者有什么合适的方法可以做到这一点吗?


答案 1

完成此IMO的最佳方法是让您的一个服务(可能是UserService)实现UserDetailsService,并在spring security XML中指定您希望使用自己的用户详细信息服务。

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

以下是指向此文档的链接:spring安全手册,第8章 这是一篇博客文章,讨论如何实现用于密码加密的自定义用户详细信息服务:示例用法

希望这有帮助

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


答案 2

你绝对需要写你自己的.在主体对象中,有用户,在 中还有一个 Details 对象,您可以存储其他登录信息的 Map(字符串,字符串)。UserDetailServiceAuthenticationToken

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);
}

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

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

删除用户时(如注销时),此信息将被删除。


推荐