Spring Security学习笔记之SessionManagementFilter

开始的时候不明白这个过滤器的作用是什么. 看源码:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
		throws IOException, ServletException {
	HttpServletRequest request = (HttpServletRequest) req;
	HttpServletResponse response = (HttpServletResponse) res;

	...

	if (!securityContextRepository.containsContext(request)) {
		// 这时这个authentication可能是RemembermeAuthentication, 或AnonymousAuthentication的实例
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

		if (authentication != null && !trustResolver.isAnonymous(authentication)) {
		 // The user has been authenticated during the current request, so call the session strategy
			try {
				sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
			} catch (SessionAuthenticationException e) {
				// The session strategy can reject the authentication
				logger.debug("SessionAuthenticationStrategy rejected the authentication object", e);
				SecurityContextHolder.clearContext();
				failureHandler.onAuthenticationFailure(request, response, e);

				return;
			}
			// Eagerly save the security context to make it available for any possible re-entrant
			// requests which may occur before the current request completes. SEC-1396.
			securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response);
		} else {
		 // No security context or authentication present. Check for a session timeout
			if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
				if(logger.isDebugEnabled()) {
					logger.debug("Requested session ID " + request.getRequestedSessionId() + " is invalid.");
				}

				if (invalidSessionStrategy != null) {
					invalidSessionStrategy.onInvalidSessionDetected(request, response);
					return;
				}
			}
		}
	}

	chain.doFilter(request, response);
}

当请求所在的session里没有设置"SPRING_SECURITY_CONTEXT"属性的时候, 才会被这个过滤器拦截. 否则跳到下一个过滤器. 但这个"SPRING_SECURITY_CONTEXT"属性是在用户登录验证完成后就放进session里的(具体参考AbstractAuthenticationProcessingFilter.successfulAuthentication()方法), 所以登录成功后的每一个请求, 它的session里都会有这个属性, 所以就不会被这个过滤器拦截.

后来发现有两种情况, 用户发出的请求会被这个过滤器拦截:

1. 当用户重启浏览器, 然后使用remember-me授权成功后, 再直接访问授权后的url. 这时, session里没有了"SPRING_SECURITY_CONTEXT"属性. 那么这个请求会被此过滤器拦截. 这时得到的authentication是RemembermeAuthentication的实例.)

2. 当session因过期而被容器自动销毁时, 若用户继续发出请求, 这个请求会放在一个新的session里, 新session里没有设置"SPRING_SECURITY_CONTEXT"属性, 那么这个请求也会被这个过滤器拦截. 这时得到的authentication是AnonymousAuthentication的实例.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值