SpringSecurity过滤器之SecurityContextPersistenceFilter

SecurityContextPersistenceFilter在请求之前从配置的SecurityContextRepository获得的信息填充SecurityContextHolder,并在请求完成并清除上下文holder后将其存储回存储库。默认情况下,它使用HttpSessionSecurityContextRepository。

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	// ensure that filter is only applied once per request
	if (request.getAttribute(FILTER_APPLIED) != null) {
		chain.doFilter(request, response);
		return;
	}
	request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
	if (this.forceEagerSessionCreation) {
		HttpSession session = request.getSession();
		if (this.logger.isDebugEnabled() && session.isNew()) {
			this.logger.debug(LogMessage.format("Created session %s eagerly", session.getId()));
		}
	}
	HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
	SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder);
	try {
		SecurityContextHolder.setContext(contextBeforeChainExecution);
		if (contextBeforeChainExecution.getAuthentication() == null) {
			logger.debug("Set SecurityContextHolder to empty SecurityContext");
		}
		else {
			if (this.logger.isDebugEnabled()) {
				this.logger
						.debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution));
			}
		}
		chain.doFilter(holder.getRequest(), holder.getResponse());
	}
	finally {
		SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
		// Crucial removal of SecurityContextHolder contents before anything else.
		SecurityContextHolder.clearContext();
		this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
		request.removeAttribute(FILTER_APPLIED);
		this.logger.debug("Cleared SecurityContextHolder to complete request");
	}
}

在请求执行之前调用repo.loadContext加载SecurityContext并设置到SecurityContextHolder,之后可以通过SecurityContextHolder获取到SecurityContext,SecurityContext包装了鉴权对象(User对象和权限)。执行完后SecurityContextHolder清除SecurityContext,并保存SecurityContext,默认是保存到Session中。

posted @   shigp1  阅读(175)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
点击右上角即可分享
微信分享提示