SpringSecurity过滤器SecurityContextPersistenceFilter

SpringSecurity过滤器SecurityContextPersistenceFilter,第1张

SpringSecurity过滤器SecurityContextPersistenceFilter

SecurityContextPersistenceFilter是承接容器的session与spring security的重要filter,主要工作是从session中获取SecurityContext,然后放到上下文中,之后的filter大多依赖这个来获取登录态。其主要是通过HttpSessionSecurityContextRepository来存取的。

public class SecurityContextPersistenceFilter extends GenericFilterBean {

	static final String FILTER_APPLIED = "__spring_security_scpf_applied";

	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) {
		// 这个就是确保一个request只会走一次SecurityContextPersistenceFilter 
			chain.doFilter(request, response);
			return;
		}
       // 给request打标记,说明这个Filter已经执行过一次了。
		request.setAttribute(FILTER_APPLIED, Boolean.TRUE);

		if (forceEagerSessionCreation) {
		    // 要不要先创建session
			HttpSession session = request.getSession();
		}

		HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,response);
		// 通过SecurityContextRepository加载SecurityContext
		// 默认使用的是HttpSessionSecurityContxtReposity
		// 这个就是说,默认是从session中获取。如果session里面获取不到就创建一个新的SecurityContext
		SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

		try {
		    // 将 SecurityContext 丢入 SecurityContextHolder
			SecurityContextHolder.setContext(contextBeforeChainExecution);
			//执行其他拦截器
			chain.doFilter(holder.getRequest(), holder.getResponse());

		}
		finally {
		    // 在其他拦截器执行完后,再将SecurityContext 从 SecurityContextHolder中移除
			SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
			SecurityContextHolder.clearContext();
			// 保存经过其他拦截器 *** 作过后的SecurityContext到指定地方
			//repo的默认值是HttpSessionSecurityContxtReposity
			// 也就是保存到session中去
			repo.saveContext(contextAfterChainExecution, holder.getRequest(),holder.getResponse());
			request.removeAttribute(FILTER_APPLIED);
		}
	}
}

简述流程:

1.从SecurityContextRepository中获取SecurityContext

2.将SecurityContext存入SecurityContextHolder中

3.执行其他过滤器,对SecurityContext进行处理

4.在其他的执行完后,将SecurityContext从SecurityContextHolder中清除,并通过SecurityContextRepository进行回写。
Spring Security Web提供的类HttpSessionSecurityContextRepository是一个SecurityContextRepository接口的实现,用于在HttpSession中保存安全上下文(security context),这样属于同一个HttpSession的多个请求,就能够利用此机制访问同一安全上下文了。

public interface SecurityContextRepository {

	//获取所提供请求的安全上下文。对于未经身份验证的用户,应返回空上下文实现。此方法不应返回null。
	SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);

	//在请求完成时存储安全上下文。
	void saveContext(SecurityContext context, HttpServletRequest request,HttpServletResponse response);

	//允许查询存储库是否包含当前请求的安全上下文。
	boolean containsContext(HttpServletRequest request);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5697295.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存