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);
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值