志宇-springSecurty
springSecurty啟動(dòng)流程
首先EnableWebSecurity 注解導(dǎo)入了WebSecurityConfiguration配置類(lèi) @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 {}
首先看這個(gè)類(lèi)org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration
代碼如下
代碼分析
上面代碼會(huì)創(chuàng)建一個(gè) AutowireBeanFactoryObjectPostProcessor的代理類(lèi) WebSecurity
WebSecurity這個(gè)類(lèi)可以向spring容器添加對(duì)象,同時(shí)還維護(hù)著一個(gè)LinkedHashMap用來(lái)存儲(chǔ)所有的WebSecurityConfigurerAdapter,WebSecurityConfigurerAdapter是配置springSecurity要繼承的類(lèi)
接下來(lái)看這個(gè)類(lèi)org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration
代碼如下
代碼分析
上面代碼會(huì)通過(guò)AutowireBeanFactoryObjectPostProcessor向spring容器注冊(cè)一個(gè)對(duì)象WebSecurityConfigurerAdapter,然后將WebSecurityConfigurerAdapter存儲(chǔ)到webSecurity中,
然后調(diào)用webSecurity的build方法,執(zhí)行代碼如下
接下來(lái)依次分析 init()、beforeConfigure()、configure()、performBuild()方法,WebSecurityConfigurerAdapter中
此部分代碼比較多分部分析,代碼如下
public void init(final WebSecurity web) throws Exception {//創(chuàng)建一個(gè)HttpSecurityfinal HttpSecurity http = getHttp();web.addSecurityFilterChainBuilder(http).postBuildAction(() -> {FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);//給WebSecurity設(shè)置一個(gè)攔截器web.securityInterceptor(securityInterceptor);});protected final HttpSecurity getHttp() throws Exception {//首先創(chuàng)建DefaultAuthenticationEventPublisher對(duì)象然后將這個(gè)對(duì)象添加到spring容器中//此對(duì)象維護(hù)著一個(gè)exceptionMappings對(duì)象,存儲(chǔ)異常和ApplicationEventDefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor.postProcess(new DefaultAuthenticationEventPublisher());//將eventPublisher給localConfigureAuthenticationBldr代理//localConfigureAuthenticationBldr 也就是 AuthenticationManagerBuilder對(duì)象localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);AuthenticationManager authenticationManager = authenticationManager();authenticationBuilder.parentAuthenticationManager(authenticationManager);authenticationBuilder.authenticationEventPublisher(eventPublisher);Map<Class<?>, Object> sharedObjects = createSharedObjects();//創(chuàng)建http對(duì)象,其中FilterComparator中存儲(chǔ)了32個(gè)過(guò)濾器 http = new HttpSecurity(objectPostProcessor, authenticationBuilder,sharedObjects);if (!disableDefaults) {// 往HttpSecurity添加一些列的 配置類(lèi)//CsrfConfigurer//ExceptionHandlingConfigurer//HeadersConfigurer//SessionManagementConfigurer//SecurityContextConfigurer//RequestCacheConfigurer//AnonymousConfigurer//ServletApiConfigurer//DefaultLoginPageConfigurer//LogoutConfigurerhttp.csrf().and().addFilter(new WebAsyncManagerIntegrationFilter()).exceptionHandling().and().headers().and().sessionManagement().and().securityContext().and().requestCache().and().anonymous().and().servletApi().and().apply(new DefaultLoginPageConfigurer<>()).and().logout();ClassLoader classLoader = this.context.getClassLoader();//添加一些默認(rèn)配置List<AbstractHttpConfigurer> defaultHttpConfigurers =SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);//添加一些默認(rèn)配置for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {http.apply(configurer);}}//調(diào)用自己配置的 configure方法,添加一些Configurerconfigure(http);return http;}protected AuthenticationManager authenticationManager() throws Exception {//這里僅僅用一個(gè)標(biāo)志位不用鎖 也不會(huì)線程不安全//因?yàn)閎uild 方法中通過(guò) //if(AtomicBoolean.compareAndSet(false, true)){}if (!authenticationManagerInitialized) {//調(diào)用配置的configure方法//方法中我們給 provider的 UserDetailsService,passwordEncoder 成員變量賦值//同時(shí)添加DaoAuthenticationConfigurer 對(duì)象configure(localConfigureAuthenticationBldr);if (disableLocalConfigureAuthenticationBldr) {//如果我們沒(méi)有重寫(xiě)configure方法則調(diào)用這里邏輯authenticationManager = authenticationConfiguration.getAuthenticationManager();}else {//localConfigureAuthenticationBldr 也就是 AuthenticationManagerBuilder對(duì)象//AuthenticationManagerBuilder中的configurers中只有一個(gè)對(duì)象DaoAuthenticationConfigurer//調(diào)用 DaoAuthenticationConfigurer 的doBuild方法//方法中會(huì)通過(guò)包裝創(chuàng)建一個(gè)ProviderManagerauthenticationManager = localConfigureAuthenticationBldr.build();}authenticationManagerInitialized = true;}return authenticationManager;}private void configure() throws Exception {Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();//循環(huán)調(diào)用所有配置類(lèi)的方法//有的configurer中的configure方法會(huì)添加攔截器for (SecurityConfigurer<O, B> configurer : configurers) {configurer.configure((B) this);}}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<SecurityFilterChain> securityFilterChains = new ArrayList<>(chainSize);for (RequestMatcher ignoredRequest : ignoredRequests) {securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));}//securityFilterChainBuilder中存儲(chǔ)所有的 HttpSecurityfor (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {//在方法中循環(huán)遍歷所有HttpSecurity中configurers //configurers 是webSecurity中存儲(chǔ)WebSecurityConfigurerAdapter的LinkedHashMap//調(diào)用所有配置類(lèi)的configurer 的 init configure 方法//securityFilterChains.add(securityFilterChainBuilder.build());}//通過(guò)FilterChainProxy對(duì)securityFilterChains進(jìn)行包裝FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);if (httpFirewall != null) {filterChainProxy.setFirewall(httpFirewall);}filterChainProxy.afterPropertiesSet();Filter result = filterChainProxy;postBuildAction.run();return result;} }上面代碼通過(guò)CsrfConfigurer、ExceptionHandlingConfigurer、HeadersConfigurer、SessionManagementConfigurer、SecurityContextConfigurer、RequestCacheConfigurer、AnonymousConfigurer 、ServletApiConfigurer、DefaultLoginPageConfigurer、LogoutConfigurer 等對(duì)象的 configure 方法 添加過(guò)濾器,我們配置對(duì)應(yīng)的Configurer對(duì)象就能修改過(guò)濾器要攔截的內(nèi)容,過(guò)濾器如下
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
MyTokenFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
總結(jié)
以上是生活随笔為你收集整理的志宇-springSecurty的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: areas ajax路由,Areas(区
- 下一篇: Ubuntu18.04 分屏显示问题解决