SpringSecurity 初始化流程源码

SpringSecurity 初始化流程源码


SpringSecurity 初始化流程源码

本篇主要讲解 SpringSecurity初始化流程的源码部分,包括核心的 springSecurityFilterChain 是如何创建的,以及在介绍哪里可以扩展个性化的配置,SpringSecurity源码其实是蛮难得 各种Builder Configure 看得真的头疼!


 1.简单介绍


 SpringSecurity 的核心功能主要包括:

 认证 (你是谁) 授权 (你能干什么) 攻击防护 (防止伪造身份)

 其核心就是一组过滤器链,项目启动后将会自动配置,本篇也会涉及过滤器链是如何自动初始化的。


SpringSecurity 初始化流程源码


SecurityContextPersistenceFilter
是最前面的一个filter 请求到它时候会去检查 根据sessionId找到session 判断session 中是否存在 SecurityContext 在 则将 SecurityContext 存入当前的线程中去 响应的时候,看当前线程是否有SecurityContext ,如果有 放入到session中去 这样不同的请求都能拿到相同的 用户认证信息。


UsernamePasswordAuthenticationFilter
该过滤器是处理表单登录的,通过表单登录提交的认证都会经过它处理


SocialAuthenticationFilter
比如这个就是社交登录使用的Filter 详细可以看我另外一篇 SpringSocial 实现第三方QQ登录
https://www.askajohnny.com/#/blog/123

绿色的过滤器都是可配置的,其他颜色的都不行!


 2.SecurityAutoConfiguration


 如果是SpringBoot项目只要你依赖了SpringSecurity相关依赖依然会有自动配置类

SecurityAutoConfiguration 生效 它会导入
WebSecurityEnableConfiguration

SpringSecurity 初始化流程源码

 @EnableWebSecurity将会是我们本篇的主要切入点

SpringSecurity 初始化流程源码


 3.@EnableWebSecurity注解介绍

 该注解 它是初始化Spring Security的入口 .

 打开@EnableWebSecurity注解

<code>    

@Retention

(value = java.lang.annotation.RetentionPolicy.RUNTIME)

@Target

(value = { java.lang.annotation.ElementType.TYPE })

@Documented

@Import

({ WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, OAuth2ImportSelector.class })

@EnableGlobalAuthentication

@Configuration

public

@interface

EnableWebSecurity {/<code>
<code>    /**
     * Controls debugging support 

for

Spring Security. Default is

false

. * @

return

if

true

, enables

debug

support with Spring Security */ boolean

debug

() default

false

; } /<code>

 该注解类通过@Configuration和@Import配合使用引入了一个配置类(WebSecurityConfiguration)和两个ImportSelector(


SpringWebMvcImportSelector,OAuth2ImportSelector),我们重点关注下WebSecurityConfiguration,它是Spring Security的核心

 4.springSecurityFilterChain初始化流程及源码

 打开WebSecurityConfiguration 它是一个配置类,主要看 springSecurityFilterChain()方法,它就是初始化springSecurityFilterChain的核心方法

<code>     
     (name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    

public

Filter

springSecurityFilterChain

()

throws

Exception

{

boolean

hasConfigurers = webSecurityConfigurers !=

null

&& !webSecurityConfigurers.isEmpty();

if

(!hasConfigurers) { WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor .postProcess(

new

WebSecurityConfigurerAdapter() { }); webSecurity.apply(adapter); }

return

webSecurity.build(); }/<code>

@Bean注解name属性值
AbstractSecurityWebApplicationInitializer.DEFAULTFILTERNAME就是XML中定义的springSecurityFilterChain

 从源码中知道过滤器通过最后的 webSecurity.build()创建,webSecurity的类型为:WebSecurity,它在
setFilterChainProxySecurityConfigurer方法中优先被创建了:


<code>     (required = 

false

)

public

void

setFilterChainProxySecurityConfigurer

( ObjectPostProcessor objectPostProcessor, @Value(

"#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}"

)

List> webSecurityConfigurers)

throws

Exception

{ webSecurity = objectPostProcessor .postProcess(

new

WebSecurity(objectPostProcessor));

if

(debugEnabled !=

null

) { webSecurity.debug(debugEnabled); }/<code>
<code>        

webSecurityConfigurers

.sort

(

AnnotationAwareOrderComparator

.INSTANCE

);/<code>
<code>        Integer previousOrder = 

null

; Object previousConfig =

null

;

for

(SecurityConfigurer config : webSecurityConfigurers) { Integer order = AnnotationAwareOrderComparator.lookupOrder(config);

if

(previousOrder !=

null

&& previousOrder.

equals

(order)) {

throw

new

IllegalStateException(

"@Order on WebSecurityConfigurers must be unique. Order of "

+ order +

" was already used on "

+ previousConfig +

", so it cannot be used on "

+ config +

" too."

); } previousOrder = order; previousConfig = config; }

for

(SecurityConfigurer webSecurityConfigurer : webSecurityConfigurers) { webSecurity.apply(webSecurityConfigurer); }

this

.webSecurityConfigurers = webSecurityConfigurers; }/<code>

 从代码中可以看到,它是直接被new出来的:

<code>    webSecurity = objectPostProcessor
                .postProcess(

new

WebSecurity(objectPostProcessor)); /<code>


setFilterChainProxySecurityConfigurer 该方法的webSecurityConfigurers 参数是通过@Value注入的

<code>    @Value(

"

#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}

"

) /<code>

 **
AutowiredWebSecurityConfigurersIgnoreParents的 getWebSecurityConfigurers() 如下,就是获取所有的 WebSecurityConfigurer的类型的配置类 而通常 我们通过继承
WebSecurityConfigurerAdapter 来自定义WebSecurityConfigurer**


<code>    

public

List> getWebSecurityConfigurers() { List> webSecurityConfigurers =

new

ArrayList<>(); Map beansOfType = beanFactory .getBeansOfType(WebSecurityConfigurer

.

class

)

;

for

(Entry entry : beansOfType.entrySet()) { webSecurityConfigurers.add(entry.getValue()); }

return

webSecurityConfigurers; } /<code>

再回到
setFilterChainProxySecurityConfigurer方法 下面有一段这样的代码 ,对于上面获取的所有的WebSecurityConfigurer类型 循环执行 webSecurity的apply方法

<code>    

for

(SecurityConfigurer

webSecurityConfigurer

: webSecurityConfigurers) {

webSecurity

.apply

(webSecurityConfigurer); } /<code>

webSecurity集成
AbstractConfiguredSecurityBuilder 它提供apply方法 再其内部调用add方法

<code>    

public

>

C

apply

(

C configurer

) throws Exception

{

add

(configurer);

return

configurer; } /<code>

 **add(configurer),主要就是将其传入的WebSecurityConfigurer存入到 LinkedHashMap configures中,主要代码 this.configurers.put(clazz, configs);**

<code>    

private

>

void

add

(C configurer)

{ Assert.notNull(configurer,

"configurer cannot be null"

);/<code>
<code>        Class extends SecurityConfigurer> clazz = (Class extends SecurityConfigurer>) configurer
                .getClass();
        synchronized (configurers) {
            

if

(buildState.isConfigured()) {

throw

new

IllegalStateException(

"Cannot apply "

+ configurer +

" to already built object"

); } List> configs = allowConfigurersOfSameType ?

this

.configurers .

get

(clazz) :

null

;

if

(configs ==

null

) { configs =

new

ArrayList<>(

1

); } configs.

add

(configurer);

this

.configurers.put(clazz, configs);

if

(buildState.isInitializing()) {

this

.configurersAddedInInitializing.

add

(configurer); } } }/<code>

当所有的 WebSecurityConfigurer 类型的配置 全部应用到 WebSecurity中去后
setFilterChainProxySecurityConfigurer方法也就结束了


回到创建过滤器链的方法 springSecurityFilterChain()

 它会判断我们刚刚的webSecurityConfigurers是否存在,不存在就新建一个,然后执行 webSecurity.build() 重要!

<code>     (name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    

public

Filter

springSecurityFilterChain

()

throws

Exception

{

boolean

hasConfigurers = webSecurityConfigurers !=

null

&& !webSecurityConfigurers.isEmpty();

if

(!hasConfigurers) { WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor .postProcess(

new

WebSecurityConfigurerAdapter() { }); webSecurity.apply(adapter); }

return

webSecurity.build(); } /<code>

最终内部会有下面这段代码, 主要关注 init() configure() 和 performBuild() 这三个方法

<code>     
    

protected

final

O

doBuild

()

throws

Exception

{

synchronized

(configurers) { buildState = BuildState.INITIALIZING;/<code>
<code>            

beforeInit

();

init

();/<code>
<code>            

buildState

= BuildState.CONFIGURING;/<code>
<code>            

beforeConfigure

();

configure

();/<code>
<code>            

buildState

= BuildState.BUILDING;/<code>
<code>            

O

result = performBuild();/<code>
<code>            

buildState

= BuildState.BUILT;/<code>
<code>            

return

result; } }/<code>

init() 内部循环遍历 所有的 WebSecurityConfigurer ,它会执行到
WebSecurityConfigurerAdapter的

<code>    

private

void

init

()

throws

Exception

{ Collection> configurers = getConfigurers();/<code>
<code>        

for

(SecurityConfigurer configurer : configurers) { configurer.

init

((B)

this

); }/<code>
<code>        

for

(SecurityConfigurer configurer : configurersAddedInInitializing) { configurer.

init

((B)

this

); } }/<code>

configurer.init((B) this)

它只要完成两件重要的事情

初始化HttpSecurity对象(注意它和WebSecurity不一样 );

设置HttpSecurity对象添加至WebSecurity的
securityFilterChainBuilders列表中;


<code>    

public

void

init

(

final

WebSecurity web)

throws

Exception

{

final

HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { FilterSecurityInterceptor securityInterceptor = http .getSharedObject(FilterSecurityInterceptor

.

class

)

; web.securityInterceptor(securityInterceptor); }); } 初始化HttpSecurity对象在getHttp()方法中实现:/<code>
<code>    

protected

final

HttpSecurity

getHttp

()

throws

Exception

{

if

(http !=

null

) {

return

http; }/<code>
<code>        DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor
                .postProcess(

new

DefaultAuthenticationEventPublisher()); localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);/<code>
<code>        AuthenticationManager authenticationManager = authenticationManager();
        authenticationBuilder.parentAuthenticationManager(authenticationManager);
        authenticationBuilder.authenticationEventPublisher(eventPublisher);
        

Map

,

Object

> sharedObjects = createSharedObjects();/<code>
<code>        http = 

new

HttpSecurity(objectPostProcessor, authenticationBuilder, sharedObjects);

if

(!disableDefaults) {

//

@formatter:

off

http .csrf().

and

() .addFilter(

new

WebAsyncManagerIntegrationFilter()) .exceptionHandling().

and

() .headers().

and

() .sessionManagement().

and

() .securityContext().

and

() .requestCache().

and

() .anonymous().

and

() .servletApi().

and

() .apply(

new

DefaultLoginPageConfigurer<>()).

and

() .logout();

//

@formatter:

on

ClassLoader classLoader =

this

.context.getClassLoader(); List defaultHttpConfigurers = SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer

.

class

,

classLoader

);

/<code>
<code>            

for

(AbstractHttpConfigurer

configurer

: defaultHttpConfigurers) {

http

.apply

(configurer); } }

configure

(http);

return

http

; } /<code>

 从代码中可以了解,HttpSecurity是直接被new出来的,在创建HttpSecurity之前,首先初始化了
AuthenticationManagerBuilder对象,这里有段代码很重要就是: AuthenticationManager authenticationManager = authenticationManager();,它创建AuthenticationManager实例,打开authenticationManager()方法:

 默认实现是在
WebSecurityConfigurerAdapter 中

<code>    

protected

void

configure

(AuthenticationManagerBuilder auth)

throws

Exception

{

this

.disableLocalConfigureAuthenticationBldr =

true

; }/<code>

1、个性化配置入口之configure(
AuthenticationManagerBuilder auth)

 我们可以通过继承
WebSecurityConfigurerAdapter并重写该方法来个性化配置
AuthenticationManagerBuilder。

SpringSecurity 初始化流程源码

如下是自己继承
WebSecurityConfigurerAdapter 重写 configure(
AuthenticationManagerBuilder auth),实现个性化的第一个配置入口

<code>     
    

@Configuration

@Slf4j

public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { /<code>
<code>     
    

protected

void

configure

(AuthenticationManagerBuilder auth)

throws

Exception

{

super

.configure(auth); log.info(

"【测试 定制化入口 configure(AuthenticationManagerBuilder auth) 的执行 】"

); } }/<code>

 构建完HttpSecurity实例后,默认情况下会添加默认的拦截其配置:

<code>            

http

.csrf

()

.and

()

.addFilter

(

new

WebAsyncManagerIntegrationFilter

())

.exceptionHandling

()

.and

()

.headers

()

.and

()

.sessionManagement

()

.and

()

.securityContext

()

.and

()

.requestCache

()

.and

()

.anonymous

()

.and

()

.servletApi

()

.and

()

.apply

(

new

DefaultLoginPageConfigurer

<>())

.and

()

.logout

();/<code>

 我挑一个默认的方法展开看一下比如 会话管理的sessionManagement(),内部就是去创建
SessionManagementConfigurer并应用它

<code>    

public

SessionManagementConfigurer

sessionManagement

()

throws

Exception

{

return

getOrApply(

new

SessionManagementConfigurer<>()); }/<code>

 getOrApply 最有一句代码 return apply(configurer);

<code>    

private

>

C

getOrApply

( C configurer)

throws

Exception

{ C existingConfig = (C) getConfigurer(configurer.getClass());

if

(existingConfig !=

null

) {

return

existingConfig; }

return

apply(configurer); }/<code>

 apply(configurer) 注意这里的 configurer传入的是
SessionManagementConfigurer

<code>    

public

>

C

apply

(

C configurer

) throws Exception

{ configurer.addObjectPostProcessor(objectPostProcessor); configurer.setBuilder((B)

this

);

add

(configurer);

return

configurer; }/<code>

最终又调用了 add(configurer); 这不过这里是给 HttpSecurity的 configurers 配置初始的,上面是配置的WebSecurity的configurers, 不要混淆,最终这些configurers会被一个个创建成 对应的过滤器Filter的 详细在后面有说明

<code>    

private

>

void

add

(C configurer)

{ Assert.notNull(configurer,

"configurer cannot be null"

);/<code>
<code>        Class extends SecurityConfigurer> clazz = (Class extends SecurityConfigurer>) configurer
                .getClass();
        synchronized (configurers) {
            

if

(buildState.isConfigured()) {

throw

new

IllegalStateException(

"Cannot apply "

+ configurer +

" to already built object"

); } List> configs = allowConfigurersOfSameType ?

this

.configurers .

get

(clazz) :

null

;

if

(configs ==

null

) { configs =

new

ArrayList<>(

1

); } configs.

add

(configurer);

this

.configurers.put(clazz, configs);

if

(buildState.isInitializing()) {

this

.configurersAddedInInitializing.

add

(configurer); } } }  如下图:为HttpSecurity添加了很多默认的配置 ![Xnip20200118_205631.png](http: /<code>

 回到 getHttp()方法

 最后调用configure(http);,这又是一个可个性化的配置入口,它的默认实现是:
WebSecurityConfigurerAdapter提供的

 默认的配置是拦截所有的请求需要认证之后才能访问,如果没有认证,会自动生成一个认证表单要求输入用户名和密码。

<code>    

protected

void

configure

(HttpSecurity http)

throws

Exception

{ logger.debug(

"Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."

);/<code>
<code>        

http

.authorizeRequests

()

.anyRequest

()

.authenticated

()

.and

()

.formLogin

()

.and

()

.httpBasic

(); }/<code>

2、个性化配置入口之configure(HttpSecurity http) 我们可以通过继承
WebSecurityConfigurerAdapter并重写该方法来个性化配置HttpSecurity。

 OK,目前为止HttpSecurity已经被初始化,接下去需要设置HttpSecurity对象添加至WebSecurity的
securityFilterChainBuilders列表中:


<code>    

public

void

init

(

final

WebSecurity web)

throws

Exception

{

final

HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { FilterSecurityInterceptor securityInterceptor = http .getSharedObject(FilterSecurityInterceptor

.

class

)

; web.securityInterceptor(securityInterceptor); }); } /<code>

 当所有的WebSecurityConfigurer的init方法被调用之后,webSecurity.init()工作就结束了

 接下去调用了webSecurity.configure(),该方法同样是在
AbstractConfiguredSecurityBuilder中实现的:

<code>    

private

void

configure

()

throws

Exception

{ Collection> configurers = getConfigurers();/<code>
<code>        

for

(SecurityConfigurer

configurer

: configurers) {

configurer

.configure

((B) this); } } /<code>

 它的主要工作是迭代调用所有WebSecurityConfigurer的configurer方法,参数是WebSeucrity本身,这又是另外一个重要的个性化入口:

3、个性化配置入口之configure(WebSecurity web) 我们可以通过继承
WebSecurityConfigurerAdapter并重写该方法来个性化配置WebSecurity。

 至此,三个重要的个性化入口都已经被调用,即在实现
WebSecurityConfigurerAdapter经常需要重写的:

<code>    

1

configure

(AuthenticationManagerBuilder auth);/<code>
<code>    

2

configure

(WebSecurity web);/<code>
<code>    

3

configure

(HttpSecurity http);/<code>

 回到webSecurity构建过程,接下去重要的的调用:

<code>    

O

result = performBuild(); /<code>

performBuild() 非常重要!!


<code>    @Override
    protected Filter performBuild() throws Exception {
        Assert.state(
                !securityFilterChainBuilders.isEmpty(),
                

()

->

"At least one SecurityBuilder extends SecurityFilterChain> needs to be specified. "

+

"Typically this done by adding a @Configuration that extends WebSecurityConfigurerAdapter. "

+

"More advanced users can invoke "

+ WebSecurity

.

class

.

getSimpleName

()

+

".addSecurityFilterChainBuilder directly"

); int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size(); List securityFilterChains =

new

ArrayList<>( chainSize);

for

(RequestMatcher ignoredRequest : ignoredRequests) { securityFilterChains.add(

new

DefaultSecurityFilterChain(ignoredRequest)); }

for

(SecurityBuilder extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) { securityFilterChains.add(securityFilterChainBuilder.build()); } FilterChainProxy filterChainProxy =

new

FilterChainProxy(securityFilterChains);

if

(httpFirewall !=

null

) { filterChainProxy.setFirewall(httpFirewall); } filterChainProxy.afterPropertiesSet();/<code>
<code>

Filter result = filterChainProxy;

if (debugEnabled) {

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);

}

postBuildAction.run();

return result;

/<code>
<code>    }
/<code>

 首先计算出chainSize,也就是ignoredRequests.size() +
securityFilterChainBuilders.size();,如果你不配置ignoredRequests,那就是
securityFilterChainBuilders.size(),也就是HttpSecurity的个数,其本质上就是你一共配置几个
WebSecurityConfigurerAdapter,因为每个
WebSecurityConfigurerAdapter对应一个HttpSecurity
,而所谓的ignoredRequests就是FilterChainProxy的请求,默认是没有的,如果你需要条跳过某些请求不需要认证或授权,可以如下配置:

<code>     
    

public

void

configure

(WebSecurity web)

throws

Exception

{ web.ignoring().antMatchers(

"/statics/**"

); }  在上面配置中,所有以/statics开头请求都将被FilterChainProxy忽略。 /<code>

 securityFilterChains.add(
securityFilterChainBuilder.build()); 这一行就是初始化所有的过滤器,记得上面有段代码如下,将HttpSecurity设置到WebSecurity的
securityFilterChainBuilder中,上面就是调用HttpSecurity.build()方法,初始化所有的 HttpSecurity的过滤器链


<code>    

public

void

init

(

final

WebSecurity web)

throws

Exception

{

final

HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { FilterSecurityInterceptor securityInterceptor = http .getSharedObject(FilterSecurityInterceptor

.

class

)

; web.securityInterceptor(securityInterceptor); }); } /<code>

 依然来到 doBuild()方法,只不过这次是执行的 HttpSecurity的

<code>     
    

protected

final

O

doBuild

()

throws

Exception

{

synchronized

(configurers) { buildState = BuildState.INITIALIZING;/<code>
<code>            

beforeInit

();

init

();/<code>
<code>            

buildState

= BuildState.CONFIGURING;/<code>
<code>            

beforeConfigure

();

configure

();/<code>
<code>            

buildState

= BuildState.BUILDING;/<code>
<code>            

O

result = performBuild();/<code>
<code>            

buildState

= BuildState.BUILT;/<code>
<code>            

return

result; } }/<code>

 重点查看 configure()该方法 会调用对应的 过滤器配置的configure()如 再内部创建 SessionManagementFilter 最后添加到HttpSecurity中,也就是拿 HttpSecurity的configures 一个个创建出对应的过滤器

SpringSecurity 初始化流程源码

<code>     
    

public

void

configure

(H http)

{ SecurityContextRepository securityContextRepository = http .getSharedObject(SecurityContextRepository

.

class

)

; SessionManagementFilter sessionManagementFilter =

new

SessionManagementFilter( securityContextRepository, getSessionAuthenticationStrategy(http));

if

(

this

.sessionAuthenticationErrorUrl !=

null

) { sessionManagementFilter.setAuthenticationFailureHandler(

new

SimpleUrlAuthenticationFailureHandler(

this

.sessionAuthenticationErrorUrl)); } InvalidSessionStrategy strategy = getInvalidSessionStrategy();

if

(strategy !=

null

) { sessionManagementFilter.setInvalidSessionStrategy(strategy); } AuthenticationFailureHandler failureHandler = getSessionAuthenticationFailureHandler();

if

(failureHandler !=

null

) { sessionManagementFilter.setAuthenticationFailureHandler(failureHandler); } AuthenticationTrustResolver trustResolver = http .getSharedObject(AuthenticationTrustResolver

.

class

)

;

if

(trustResolver !=

null

) { sessionManagementFilter.setTrustResolver(trustResolver); } sessionManagementFilter = postProcess(sessionManagementFilter);/<code>
<code>        

http.addFilter(sessionManagementFilter);

if

(isConcurrentSessionControlEnabled()) {

ConcurrentSessionFilter

concurrentSessionFilter = createConcurrencyFilter(http);

/<code>
<code>            

concurrentSessionFilter

=

postProcess(concurrentSessionFilter);

http.addFilter(concurrentSessionFilter);

}

}

/<code>

 当doBuild()中的 configure();执行完毕后 的会得到如下HttpSecurity可以看到它内部的filters已经全部创建完毕

SpringSecurity 初始化流程源码

 回到doBuild()方法 该方中有 performBuild() 调用HttpSecurity的 performBuild(),默认实现如下,先对上面所有的过滤器进行排序,使用的是 FilterComparator() 进行排序的,这里不展开了,反正就是会排序成文章开始的那张图上面的顺序


<code>     
    

protected

DefaultSecurityFilterChain

performBuild

()

{ filters.sort(comparator);

return

new

DefaultSecurityFilterChain(requestMatcher, filters); }/<code>

 最后返回的是SecurityFilterChain的默认实现
DefaultSecurityFilterChain。

 构建完所有SecurityFilterChain后,创建最为重要的FilterChainProxy实例,

<code>    FilterChainProxy filterChainProxy = 

new

FilterChainProxy(securityFilterChains);/<code>
SpringSecurity 初始化流程源码

 至此Spring Security 初始化完成,包括springSecurityFilterChain初始化,我们通过继承
WebSecurityConfigurerAdapter来代达到个性化配置目的,文中提到了三个重要的个性化入口,并且


WebSecurityConfigurerAdapter是可以配置多个的,其对应的接口就是会存在多个SecurityFilterChain实例,但是它们人仍然在同一个FilterChainProxy中,通过RequestMatcher来匹配并传入到对应的SecurityFilterChain中执行请求。


 5.个性化入口配置(扩展WebSecurityConfigurerAdapter)

 重要的个性化入口都是哪里调用的 已经在上面初始化 springSecurityFilterChain 源码中讲解了,这里知识总结一下

1、个性化配置入口之configure(
AuthenticationManagerBuilder auth)

 我们可以通过继承
WebSecurityConfigurerAdapter并重写该方法来个性化配置
AuthenticationManagerBuilder。

2、个性化配置入口之configure(HttpSecurity http) 我们可以通过继承
WebSecurityConfigurerAdapter并重写该方法来个性化配置HttpSecurity。

3、个性化配置入口之configure(WebSecurity web) 我们可以通过继承
WebSecurityConfigurerAdapter并重写该方法来个性化配置WebSecurity。

 实现
WebSecurityConfigurerAdapter经常需要重写的:

<code>    

1

configure

(AuthenticationManagerBuilder auth);/<code>
<code>    

2

configure

(WebSecurity web);/<code>
<code>    

3

configure

(HttpSecurity http); /<code>

 6.总结

 **本篇主要讲解了 1.SpringBoot对于SpringSecurity的自动配置的支持类SecurityAutoConfiguration, 2.核心注解@EnableWebSecurity 3. SpringSecurity的核心过滤器链 springSecurityFilterChain 的初始化流程的源码源码部分还是定下心来多看 加油!**


个人博客网站
https://www.askajohnny.com 欢迎访问!

本文由博客一文多发平台 https://openwrite.cn?from=article_bottom 发布!


分享到:


相關文章: