我的Web应用程序是使用Spring MVC(4.2.9.RELEASE)和Spring Security(3.2.5.RELEASE)构建的。我使用loadUserByUsername
方法从数据库中查找用户。
public class MyUserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
//how to get the HttpSession from within this methd?
}
....
}
如何从此方法中获取HttpSession?
在applicationContext.xml
文件中,出于安全性考虑,我具有以下要求:
<http create-session="always" use-expressions="true" request-matcher="regex" entry-point-ref="authenticationEntryPoint" >
....
</http>
答案 0 :(得分:1)
有一种方法可以获取当前请求: 从RequestHolderContext中获取请求对象,并从该对象中获取会话:
public Optional<HttpServletRequest> getCurrentHttpRequest() {
return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
.filter(requestAttributes -> ServletRequestAttributes.class.isAssignableFrom(requestAttributes.getClass()))
.map(requestAttributes -> ((ServletRequestAttributes) requestAttributes))
.map(ServletRequestAttributes::getRequest);
}
像这样使用它:
Optional<HttpServletRequest> request = getCurrentHttpRequest();
HttpServletRequest currentRequest = request.get();
希望这对您有帮助
答案 1 :(得分:1)
在http://mukharsamvad.com/wp-content/uploads/2019/10/nitish-kumar-11-1.jpg/的较新版本(例如,5.1.5)中,您的问题确实存在答案。简而言之:
如何从UserDetailsService访问HttpSession?
您不能这样做,因为UserDetailsService不了解Servlet API。
@Atul的答案可能是一个很好的解决方法,但是请注意RequestContextHolder
内部依赖于当前线程,因此如果从另一个线程调用该会话,则可能会丢失会话。
答案 2 :(得分:0)
在发布我的文章之前,我已经有一个解决方案,并且似乎可以正常工作,但是不确定我的解决方案是否没有错误,或者Spring是否已经有一个更优雅的解决方案。这是我的解决方案:
我建立了如下过滤器:
public class MyFilter implements Filter {
...
public void doFilter(ServletRequest request, ServletResponse response, FilterChain
chain) throws IOException, ServletException {
//create a thread-safe object and record the request object
}
}
然后,在loadUserByUsername
方法中,从线程安全对象获取请求对象(因此为HTTP会话)。
评论?请随时让我知道这种方法是否有问题。
更新
MyFilter与Spring Security的DelegatingFilterProxy一起在web.xml中声明。