Java 检索用户所需的最低SpringSecurity配置
我有一个现有的SpringMVC应用程序,目前没有使用SpringSecurity。我为Hibernate审计日志编写了一个AuditInterceptor,它需要一种获取当前登录用户的方法。从网上我可以找到,最好的方法是通过SpringSecurity的SecurityContextHolder。然而,目前我并不真正需要任何其他SpringSecurity功能,我也不想重写应用程序当前如何进行身份验证或授权 基本上,我要寻找的是将登录用户存储到SecurityContextHolder中所需的最低配置量,并将其重新放回我的AudientReceptor中。Java 检索用户所需的最低SpringSecurity配置,java,spring,spring-security,Java,Spring,Spring Security,我有一个现有的SpringMVC应用程序,目前没有使用SpringSecurity。我为Hibernate审计日志编写了一个AuditInterceptor,它需要一种获取当前登录用户的方法。从网上我可以找到,最好的方法是通过SpringSecurity的SecurityContextHolder。然而,目前我并不真正需要任何其他SpringSecurity功能,我也不想重写应用程序当前如何进行身份验证或授权 基本上,我要寻找的是将登录用户存储到SecurityContextHolder中所需的
我的第一次尝试是将以下行添加到当前存在的登录页面:
Authentication auth = new UsernamePasswordAuthenticationToken(u.getName(), u.getPassword());
SecurityContextHolder.getContext().setAuthentication(auth);
并将以下内容添加到拦截器中:
SecurityContext secureContext = SecurityContextHolder.getContext();
Authentication auth = secureContext.getAuthentication();
Object principal = auth.getPrincipal();
String userName = null;
if (principal instanceof UserDetails) {
UserDetails userDetails = (UserDetails) principal;
userName = userDetails.getUsername();
} else {
userName = principal.toString();
}
这是成功的,但不幸的是不是线程安全的。有人有其他想法吗?我不知道你怎么称呼它为非线程安全。您的实现看起来非常好。只要您每次按照您实现的方式检索上下文,它就是线程安全的。 SecurityContextHolder是ThreadLocalSecurityContextHolderStrategy的一个实例,它将SecurityContext存储在ThreadLocal中。从您的评论中 我有一个现有的SpringMVC应用程序,目前没有使用SpringSecurity。。。这需要一种获取当前登录用户的方法 你能不能不直接使用 返回一个java.security.Principal对象,该对象包含当前经过身份验证的用户的名称。如果用户尚未通过身份验证,则该方法返回null
最后,您对线程安全性的评论似乎有点可疑,因为安全上下文对象和主对象是不可变的,默认情况下存储在ThreadLocal存储中,这使它们完全是线程安全的。谢谢您的帮助,谢谢大家。我可以从中找到以下解释: 进一步挖掘揭示了我问题的核心——我遗漏了一个关键的bean定义:
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
SecurityContextPersistenceFilter确保在需要时适当清除所有内容
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>