当前位置:   article > 正文

SpringSecurity源码解析--SecurityContextPersistenceFilter_securitycontextpersistencefilter替换 securitycontext

securitycontextpersistencefilter替换 securitycontextrepository

概述

SecurityContextPersistenceFilter有两个主要任务:

  1. 在请求到达时处理之前,从SecurityContextRepository中获取安全上下文信息填充到SecurityContextHolder;
  2. 在请求处理结束后返回响应时,将SecurityContextHolder中的安全上下文信息保存回SecurityContextRepository,并清空SecurityContextHolder。

通过SecurityContextPersistenceFilter的这种机制,在整个请求处理过程中,开发人员都可以通过使用SecurityContextHolder获取当前访问用户的安全上下文信息。

缺省情况下,SecurityContextPersistenceFilter使用的SecurityContextRepository是HttpSessionSecurityContextRepository,也就是将安全上下文的信息保存在用户的会话中。

为了解决不同Serlvet容器上,尤其是weblogic上的兼容性问题,此Filter必须在整个request处理过程中被调用最多一次。

该Filter也必须在任何认证机制逻辑发生之前被调用。因为这些认证机制都依赖于SecurityContextHolder所包含的安全上下文对象。

public class SecurityContextPersistenceFilter extends GenericFilterBean {

	// 确保该Filter在一个request处理过程中最多被调到用一次的机制:
	// 一旦该Fitler被调用过,他会在当前request增加该属性值为true,利用此标记
	// 可以避免Filter被调用二次。
	static final String FILTER_APPLIED = "__spring_security_scpf_applied";

	// 安全上下文存储库
	private SecurityContextRepository repo;

	private boolean forceEagerSessionCreation = false;

	public SecurityContextPersistenceFilter() {
		// 缺省使用http session 作为安全上下文对象存储
		this(new HttpSessionSecurityContextRepository());
	}

	public SecurityContextPersistenceFilter(SecurityContextRepository repo) {
		this.repo = repo;
	}

	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) {
			// ensure that filter is only applied once per request
			// 检查调用标志,如果request上已经存在属性FILTER_APPLIED,
			// 表明该Filter在该request的处理过程中已经被调用过
			chain.doFilter(request, response);
			return;
		}

		final boolean debug = logger.isDebugEnabled();

		// 设置该Filter已经被调用的标记
		request.setAttribute(FILTER_APPLIED, Boolean.TRUE);

		if (forceEagerSessionCreation) {
			HttpSession session = request.getSession();

			if (debug && session.isNew()) {
				logger.debug("Eagerly created session: " + session.getId());
			}
		}

		HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
				response);
		// 从安全上下文存储库(缺省是http session)中读取安全上下文对象		
		SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

		try {
			// 设置安全上下文对象到SecurityContextHolder然后才继续Filter chain的调用
			SecurityContextHolder.setContext(contextBeforeChainExecution);

			chain.doFilter(holder.getRequest(), holder.getResponse());

		}
		finally {
			SecurityContext contextAfterChainExecution = SecurityContextHolder
					.getContext();
			// Crucial removal of SecurityContextHolder contents - do this before anything
			// else.
			// 当前请求已经被处理完成了,清除SecurityContextHolder并将最新的
			// 安全上下文对象保存回安全上下文存储库(缺省是http session)
			SecurityContextHolder.clearContext();
			repo.saveContext(contextAfterChainExecution, holder.getRequest(),
					holder.getResponse());
			request.removeAttribute(FILTER_APPLIED);

			if (debug) {
				logger.debug("SecurityContextHolder now cleared, as request processing completed");
			}
		}
	}

	public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
		this.forceEagerSessionCreation = forceEagerSessionCreation;
	}
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

其他过滤器总和

SpringSecurity过滤器清单

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/68890
推荐阅读
相关标签
  

闽ICP备14008679号