web如何取得用户信息
Spring Security 中获取用户信息的原理与实践
在 Web 应用中,Spring Security 能够在每次请求时识别用户身份并验证权限,核心在于 SecurityContextPersistenceFilter 对 SecurityContext 的管理。本文结合源码解析这一机制的实现原理,并介绍在实际开发中获取用户信息的常用方式。
SecurityContext 的生命周期管理
SecurityContext 是存储用户认证信息的容器,其生命周期由 SecurityContextPersistenceFilter 全程管理,确保每个请求都能获取到当前用户的身份信息。
1. 核心流程:请求到来时加载上下文
当一个请求进入应用时,SecurityContextPersistenceFilter 会执行以下操作:
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) {
chain.doFilter(request, response);
return;
}
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
HttpRequest// 1. 从 Session 中加载 SecurityContext
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
try {
// 2. 将上下文存入 SecurityContextHolder(ThreadLocal 存储)
SecurityContextHolder.setContext(contextBeforeChainExecution);
// 3. 执行后续过滤器链(包括权限校验等)
chain.doFilter(holder.getRequest(), holder.getResponse());
} finally {
// 4. 请求结束:清除 ThreadLocal 中的上下文
SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
SecurityContextHolder.clearContext();
// 5. 将上下文保存回 Session
repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
request.removeAttribute(FILTER_APPLIED);
}
}