日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

志宇-springSecurty

發(fā)布時(shí)間:2024/3/26 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 志宇-springSecurty 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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
代碼如下

@Autowired(required = false)public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)throws Exception {//通過(guò)AutowireBeanFactoryObjectPostProcessor將WebSecurity注入到spring容器中//WebSecurity是AutowireBeanFactoryObjectPostProcessor的代理對(duì)象webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));//從spring容器中獲得所有配置的WebSecurityConfigurerAdapter的類(lèi)//WebSecurityConfigurerAdapter是我們配置的springSecurity要繼承的類(lèi)//調(diào)用他的apply方法for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {//將WebSecurityConfigurerAdapter放到一個(gè)集合LinkedHashMap中webSecurity.apply(webSecurityConfigurer);}this.webSecurityConfigurers = webSecurityConfigurers;}

代碼分析
上面代碼會(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
代碼如下

@Bean(name = "springSecurityFilterChain") public Filter springSecurityFilterChain() throws Exception {boolean hasConfigurers = webSecurityConfigurers != null&& !webSecurityConfigurers.isEmpty();if (!hasConfigurers) {//通過(guò)AutowireBeanFactoryObjectPostProcessor向spring容器注冊(cè)WebSecurityConfigurerAdapterWebSecurityConfigurerAdapter adapter = objectObjectPostProcessor.postProcess(new WebSecurityConfigurerAdapter() {});webSecurity.apply(adapter);}//調(diào)用return webSecurity.build(); }

代碼分析
上面代碼會(huì)通過(guò)AutowireBeanFactoryObjectPostProcessor向spring容器注冊(cè)一個(gè)對(duì)象WebSecurityConfigurerAdapter,然后將WebSecurityConfigurerAdapter存儲(chǔ)到webSecurity中,
然后調(diào)用webSecurity的build方法,執(zhí)行代碼如下

protected final O doBuild() throws Exception {//configurers 是webSecurity中存儲(chǔ)WebSecurityConfigurerAdapter的LinkedHashMapsynchronized (configurers) {//通過(guò)枚舉修改狀態(tài)buildState = BuildState.INITIALIZING;//空方法 用于擴(kuò)展beforeInit();//調(diào)用configurers集合中所有對(duì)象的init方法//當(dāng)前集合中只有一個(gè)對(duì)象 WebSecurityConfigurerAdapterinit();buildState = BuildState.CONFIGURING;beforeConfigure();//調(diào)用configurers集合中所有對(duì)象的configure方法configure();buildState = BuildState.BUILDING;O result = performBuild();buildState = BuildState.BUILT;return result;} }

接下來(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ì)線(xiàn)程不安全//因?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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。