SecurityContextHolderAwareRequestFilter:使HttpServletRequestWrapper能够感知SecurityContextHolder的过滤器。
1.1 功能概述:
1.1.1 SecurityContextHolderAwareRequestFilter通过Wrapper/Decorator模式对HttpServletRequest进行包装,使其具备访问SecurityContextHolder中安全上下文的能力。这样,接口HttpServletRequest上定义的安全相关方法(如getUserPrincipal)才能访问到相应的安全信息。
1.2 核心功能:
1.2.1 请求包装:
--- SecurityContextHolderAwareRequestFilter使用HttpServlet3RequestFactory(针对Servlet 3.0及以上版本)或相应的工厂类来创建SecurityContextHolderAwareRequestWrapper实例。
--- SecurityContextHolderAwareRequestWrapper扩展了HttpServletRequest,并添加了访问安全上下文的方法。
1.2.2 安全上下文访问:
--- 包装后的请求可以通过getUserPrincipal、getRemoteUser等方法访问安全上下文中的用户信息。
--- 这些方法从SecurityContextHolder中获取当前认证的用户信息。
1.2.3 过滤器链执行:
--- 在doFilter方法中,SecurityContextHolderAwareRequestFilter使用包装后的请求继续过滤器链的执行。
--- 这样可以确保后续的过滤器或控制器能够访问到安全上下文中的用户信息。
1.3 核心代码分析:
public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
// 角色名称前缀,默认为"ROLE_"
private String rolePrefix = "ROLE_";
// 用于封装HttpServletRequest的工厂类
private HttpServletRequestFactory requestFactory;
// 其他安全相关的属性,如authenticationEntryPoint、authenticationManager等
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// 使用requestFactory创建包装后的请求,并继续过滤器链的执行
chain.doFilter(this.requestFactory.create((HttpServletRequest) req, (HttpServletResponse) res), res);
}
@Override
public void afterPropertiesSet() throws ServletException {
super.afterPropertiesSet();
// 初始化requestFactory
updateFactory();
}
private void updateFactory() {
// 创建HttpServlet3RequestFactory实例,并设置相关属性
this.requestFactory = createServlet3Factory(rolePrefix);
}
private HttpServletRequestFactory createServlet3Factory(String rolePrefix) {
HttpServlet3RequestFactory factory = new HttpServlet3RequestFactory(rolePrefix);
// 设置信任解析器、认证入口点、认证管理器、注销处理器等
factory.setTrustResolver(this.trustResolver);
factory.setAuthenticationEntryPoint(this.authenticationEntryPoint);
factory.setAuthenticationManager(this.authenticationManager);
factory.setLogoutHandlers(this.logoutHandlers);
return factory;
}
}
1.4 使用场景:
1.4.1 控制器方法参数解析:当控制器方法的参数类型为Principal时,Spring MVC的ServletRequestMethodArgumentResolver会调用request#getUserPrincipal()来获取用户信息。
1.4.2 Token获取:在OAuth2或JWT等认证机制中,获取token的请求可能需要访问用户信息。SecurityContextHolderAwareRequestFilter可以确保这些请求能够访问到安全上下文中的用户信息。
1.5 总结:
SecurityContextHolderAwareRequestFilter是Spring Security框架中的一个重要组件,它通过包装HttpServletRequest请求,使其能够访问SecurityContextHolder中的安全上下文。这样,后续的过滤器、控制器或其他组件就可以方便地访问用户信息和其他安全相关的数据。