pig4cloud框架系列六:WebSecurity和HttpSecurity的关系

前言:本篇是自己通过看代码及网上的一些博客,总结整理的记录,供大家参考。

一,HttpSecurity的本质

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {return http.antMatcher("/**").authorizeRequests(authorize -> authorize.anyRequest().authenticated()).build();
}

其实就能够知道HttpSecurity是用来构建包含了一系列过滤器链的过滤器SecurityFilterChain,平常我们的配置就是围绕构建SecurityFilterChain进行,看下面这张老图:

 从上面这个图中可以看出构建好的还要交给FilterChainProxy来代理,是不是有点多此一举?

二,WebSecurity的本质

在有些情况下这种确实多此一举, 不过更多时候我们可能需要配置多个SecurityFilterChain来实现对多种访问控制策略。

 

 

为了精细化的管理多个SecurityFilterChain的生命周期,搞一个统一管理这些SecurityFilterChain的代理就十分必要了,这就是WebSecurity的意义。下面是WebSecuritybuild方法的底层逻辑:

@Override
protected Filter performBuild() throws Exception {Assert.state(!this.securityFilterChainBuilders.isEmpty(),() -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "+ "Typically this is done by exposing a SecurityFilterChain bean "+ "or by adding a @Configuration that extends WebSecurityConfigurerAdapter. "+ "More advanced users can invoke " + WebSecurity.class.getSimpleName()+ ".addSecurityFilterChainBuilder directly");// 被忽略请求的个数 和 httpscurity的个数 构成了过滤器链集合的大小int chainSize = this.ignoredRequests.size() + this.securityFilterChainBuilders.size();List<SecurityFilterChain> securityFilterChains = new ArrayList<>(chainSize);// 初始化过滤器链集合中的 忽略请求过滤器链    for (RequestMatcher ignoredRequest : this.ignoredRequests) {securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));}// 初始化过滤器链集合中的 httpsecurity定义的过滤器链for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : this.securityFilterChainBuilders) {securityFilterChains.add(securityFilterChainBuilder.build());}FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);if (this.httpFirewall != null) {// 请求防火墙filterChainProxy.setFirewall(this.httpFirewall);}if (this.requestRejectedHandler != null) {// 请求拒绝处理器filterChainProxy.setRequestRejectedHandler(this.requestRejectedHandler);}filterChainProxy.afterPropertiesSet();Filter result = filterChainProxy;if (this.debugEnabled) {this.logger.warn("\n\n" + "********************************************************************\n"+ "**********        Security debugging is enabled.       *************\n"+ "**********    This may include sensitive information.  *************\n"+ "**********      Do not use in a production system!     *************\n"+ "********************************************************************\n\n");result = new DebugFilter(filterChainProxy);}this.postBuildAction.run();return result;
}

从上面中的源码可以看出,WebSecurity用来构建一个名为springSecurityFilterChain的Spring BeanFilterChainProxy 。它的作用是来定义哪些请求忽略安全控制,哪些请求必须安全控制,在合适的时候清除SecurityContext以避免内存泄漏,同时也可以用来定义请求防火墙和请求拒绝处理器,另外我们开启Spring Seuciry Debug模式也是这里配置的。

同时还有一个作用可能是其它文章没有提及的,FilterChainProxy是Spring Security对Spring framework应用的唯一出口,然后通过它与一个Servlet在Spring的桥接代理DelegatingFilterProxy结合构成Spring对Servlet体系的唯一出口。这样就将Spring Security、Spring framework、Servlet API三者隔离了起来。

我们事实上可以认为,WebSecurity是Spring Security对外的唯一出口,而HttpSecurity只是内部安全策略的定义方式;

WebSecurity主要构建FilterChainProxy,而HttpSecurity则构建SecurityFilterChain,另外它们的父类都是AbstractConfiguredSecurityBuilder

posted on 2023-10-07 19:39  MrQuan  阅读(127)  评论(0编辑  收藏  举报