1. 程式人生 > >spring security java config 原始碼分析 parentAuthenticationManager

spring security java config 原始碼分析 parentAuthenticationManager

1 websecurity和httpsecurity的建立

java配置會使用2個註解

@Configuration
@EnableWebSecurity 這個註解又匯入了WebSecurityConfiguration

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = { java.lang.annotation.ElementType.TYPE })
@Documented
@Import({ WebSecurityConfiguration.class, ObjectPostProcessorConfiguration.class,
SpringWebMvcImportSelector.class }) @EnableGlobalAuthentication @Configuration public @interface EnableWebSecurity { /** * Controls debugging support for Spring Security. Default is false. * @return if true, enables debug support with Spring Security */ boolean debug() default false; }

websecurity的建立在WebSecurityConfiguration#setFilterChainProxySecurityConfigurer

然後在WebSecurityConfiguration#springSecurityFilterChain會呼叫webSecurity#build建立攔截器鏈


使用java配置的時候,會繼承一個WebSecurityConfigurerAdapter,這個WebSecurityConfigurerAdapter的init方法會在websecurity中加入httpsecurity。

2 httpsecurity配置

預設的配置是在WebSecurityConfigurerAdapter的configure方法

protected void configure(HttpSecurity http) throws Exception {
   logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
http
      .authorizeRequests()
         .anyRequest().authenticated()
         .and()
      .formLogin().and()
      .httpBasic();
}
authorizeRequests  新增一個配置ExpressionUrlAuthorizationConfigurer,然後返回這個ExpressionUrlAuthorizationConfigurer的成員(ExpressionInterceptUrlRegistry)。

anyRequest  新增訪問規則RequestMatcherANY_REQUEST,然後建立AuthorizedUrl返回,這個AuthorizedUrl是ExpressionUrlAuthorizationConfigurer的內部類。

authenticated 在REGISTRY新增UrlMapping authenticated。

3 spring boot相關工作

檢視spring boot 的factory.properties,security相關的有

org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\

SecurityAutoConfiguration建立了2個物件到spring容器。

DefaultAuthenticationEventPublisher(如果容器中沒有AuthenticationEventPublisher才會建立)

SecurityProperties(如果容器中沒有SecurityProperties才會建立)

SecurityAutoConfiguration又匯入了

@Import({ SpringBootWebSecurityConfiguration.class,
AuthenticationManagerConfiguration.class,
BootGlobalAuthenticationConfiguration.class, SecurityDataConfiguration.class })

SpringBootWebSecurityConfiguration

建立了IgnoredPathsWebSecurityConfigurerAdapter,同樣也是沒有IgnoredPathsWebSecurityConfigurerAdapter才會建立

4 WebSecurityConfigurerAdapter

這個類用來自定義配置

private AuthenticationConfiguration authenticationConfiguration;
private AuthenticationManagerBuilder authenticationBuilder;
private AuthenticationManagerBuilder localConfigureAuthenticationBldr;
private boolean disableLocalConfigureAuthenticationBldr;
private boolean authenticationManagerInitialized;
private AuthenticationManager authenticationManager;
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private HttpSecurity http;
private boolean disableDefaults;

authenticationConfiguration  是用來建立authenticationManager

authenticationManagerInitialized 表示authenticationManager有沒有初始化,true的話就直接在protected AuthenticationManager authenticationManager() throws Exception

方法返回這個authenticationManager,false的話就初始化,初始化的時候判斷disableLocalConfigureAuthenticationBldr是否禁用localConfigureAuthenticationBldr,禁用的

話就用authenticationConfiguration ,否則用localConfigureAuthenticationBldr,預設是用之前就設定了禁用,

如果你覆蓋了protected void configure(AuthenticationManagerBuilder auth) throws Exception方法,就會使用localConfigureAuthenticationBldr。

總之 httsecurity.getsharedobject方法獲取的是authenticationBuilder,

這個authenticationBuilder的parentAuthenticationManager可以是authenticationConfiguration.getAuthenticationManager()得到的,這是預設情況,authenticationConfiguration是容器注入的

也可以是localConfigureAuthenticationBldr.build()得到,這是自定義的,通過重寫configure方法才能使用它。

AuthenticationManagerBuilder有2個,authenticationBuilder有一個引用了一個authenticationManager的parentAuthenticationManager,這個parentAuthenticationManager是用protected AuthenticationManager authenticationManager() throws Exception方法建立的。然後把這個authenticationBuilder放到httpsecurity的sharedobject中共享。