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中共享。