SessionManagementFilter
介绍
该Filter的主要作用是,当请求经过过滤器是 ,判断缓存中是否有同一session id的请求,如果不存在则从上下文中获取身份认证信息,并使用SessionAuthenticationStrategy对身份认证信息执行必要的操作,比如重新生成session id来防止session-fixation攻击。过滤器中有2个比较重要的全局变量,分别是SessionAuthenticationStrategy、SecurityContextRepository。SessionAuthenticationStrategy实例的实现是CompositeSessionAuthenticationStrategy,是一个复合型的会话认证策略,默认情况下仅包含一个ChangeSessionIdAuthenticationStrategy,用于改变session的id,可以防止session fixation攻击(建议百度)。SecurityContextRepository用户将SecurityContext上下文保存到session中,但是默认情况SecurityContextRepository的实现是NullSecurityContextRepository,可以通过修改配置为SessionCreationPolicy.IF_REQUIRED,进而给Filter注入HttpSessionSecurityContextRepository的实现,具体如何进行配置以及配置注入的代码分析可以参照SecurityContextPersistenceFilter这篇文章。
代码分析
步骤1
当请求经过SessionManagementFilter时,需要判断缓存中是否已经存在了同一session id的请求了,只有不存在时,才从上下文中取身份认证信息,并通过SessionAuthenticationStrategy对authentication进行认证操作,认证成功后写入到缓存中,代码如下:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//过滤器已经应用过了,直接可以进入下个过滤器
if (request.getAttribute(FILTER_APPLIED) != null) {
chain.doFilter(request, response);
return;
}
//防止重复进入验证代码,先打个标识
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
//判断repo中是否未存储过同一session id请求
if (!securityContextRepository.containsContext(request)) {
//从上下文中或身份认证信息
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
//身份认证信息非空,并且不是匿名认证
if (authentication != null && !trustResolver.isAnonymous(authentication)) {

本文深入解析SessionManagementFilter的工作原理,包括防止session-fixation攻击的机制,以及如何通过配置SessionCreationPolicy来控制session的创建。文章详细分析了代码执行流程,探讨了SessionAuthenticationStrategy和SecurityContextRepository的作用。
最低0.47元/天 解锁文章
5万+

被折叠的 条评论
为什么被折叠?



