深入理解 HttpSecurity

HttpSecurity 也是 Spring Security 中的重要一环 。我们平时所做的大部分 Spring Security 配置也都是基于 HttpSecurity 来配置的 。因此我们有必要从源码的角度来理解下 HttpSecurity 到底干了啥?
1.抽丝剥茧首先我们来看下 HttpSecurity 的继承关系图:

深入理解 HttpSecurity

文章插图
 
可以看到,HttpSecurity 继承自 AbstractConfiguredSecurityBuilder,同时实现了 SecurityBuilder 和 HttpSecurityBuilder 两个接口 。
我们来看下 HttpSecurity 的定义:
public final class HttpSecurity extends  AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>  implements SecurityBuilder<DefaultSecurityFilterChain>,  HttpSecurityBuilder<HttpSecurity> {        //...}这里每一个类都带有泛型,看得人有点眼花缭乱 。
我把这个泛型类拿出来和大家讲一下,小伙伴们就明白了 。
泛型主要是两个,DefaultSecurityFilterChain 和 HttpSecurity,HttpSecurity 就不用说了,这是我们今天的主角,那么 DefaultSecurityFilterChain 是干嘛的?
【深入理解 HttpSecurity】这我们就得从 SecurityFilterChain 说起了 。
1.1 SecurityFilterChain先来看定义:
public interface SecurityFilterChain { boolean matches(HttpServletRequest request); List<Filter> getFilters();}SecurityFilterChain 其实就是我们平时所说的 Spring Security 中的过滤器链,它里边定义了两个方法,一个是 matches 方法用来匹配请求,另外一个 getFilters 方法返回一个 List 集合,集合中放着 Filter 对象,当一个请求到来时,用 matches 方法去比较请求是否和当前链吻合,如果吻合,就返回 getFilters 方法中的过滤器,那么当前请求会逐个经过 List 集合中的过滤器 。这一点,小伙伴们可以回忆前面【深入理解 FilterChainProxy【源码篇】】一文 。
SecurityFilterChain 接口只有一个实现类,那就是 DefaultSecurityFilterChain:
public final class DefaultSecurityFilterChain implements SecurityFilterChain { private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class); private final RequestMatcher requestMatcher; private final List<Filter> filters; public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {  this(requestMatcher, Arrays.asList(filters)); } public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {  logger.info("Creating filter chain: " + requestMatcher + ", " + filters);  this.requestMatcher = requestMatcher;  this.filters = new ArrayList<>(filters); } public RequestMatcher getRequestMatcher() {  return requestMatcher; } public List<Filter> getFilters() {  return filters; } public boolean matches(HttpServletRequest request) {  return requestMatcher.matches(request); } @Override public String toString() {  return "[ " + requestMatcher + ", " + filters + "]"; }}DefaultSecurityFilterChain 只是对 SecurityFilterChain 中的方法进行了实现,并没有特别值得说的地方,松哥也就不啰嗦了 。
那么从上面的介绍中,大家可以看到,DefaultSecurityFilterChain 其实就相当于是 Spring Security 中的过滤器链,一个 DefaultSecurityFilterChain 代表一个过滤器链,如果系统中存在多个过滤器链,则会存在多个 DefaultSecurityFilterChain 对象 。
接下来我们把 HttpSecurity 的这几个父类捋一捋 。
1.2 SecurityBuilderpublic interface SecurityBuilder<O> { O build() throws Exception;}SecurityBuilder 就是用来构建过滤器链的,在 HttpSecurity 实现 SecurityBuilder 时,传入的泛型就是 DefaultSecurityFilterChain,所以 SecurityBuilder#build 方法的功能很明确,就是用来构建一个过滤器链出来 。
1.3 HttpSecurityBuilderHttpSecurityBuilder 看名字就是用来构建 HttpSecurity 的 。不过它也只是一个接口,具体的实现在 HttpSecurity 中,接口定义如下:
public interface HttpSecurityBuilder<H extends HttpSecurityBuilder<H>> extends  SecurityBuilder<DefaultSecurityFilterChain> { <C extends SecurityConfigurer<DefaultSecurityFilterChain, H>> C getConfigurer(   Class<C> clazz); <C extends SecurityConfigurer<DefaultSecurityFilterChain, H>> C removeConfigurer(   Class<C> clazz); <C> void setSharedObject(Class<C> sharedType, C object); <C> C getSharedObject(Class<C> sharedType); H authenticationProvider(AuthenticationProvider authenticationProvider); H userDetailsService(UserDetailsService userDetailsService) throws Exception; H addFilterAfter(Filter filter, Class<? extends Filter> afterFilter); H addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter); H addFilter(Filter filter);}


推荐阅读