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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

志宇-springSecurty

發布時間:2024/3/26 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 志宇-springSecurty 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

springSecurty啟動流程


首先EnableWebSecurity 注解導入了WebSecurityConfiguration配置類

@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 {}

首先看這個類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 {//通過AutowireBeanFactoryObjectPostProcessor將WebSecurity注入到spring容器中//WebSecurity是AutowireBeanFactoryObjectPostProcessor的代理對象webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));//從spring容器中獲得所有配置的WebSecurityConfigurerAdapter的類//WebSecurityConfigurerAdapter是我們配置的springSecurity要繼承的類//調用他的apply方法for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {//將WebSecurityConfigurerAdapter放到一個集合LinkedHashMap中webSecurity.apply(webSecurityConfigurer);}this.webSecurityConfigurers = webSecurityConfigurers;}

代碼分析
上面代碼會創建一個 AutowireBeanFactoryObjectPostProcessor的代理類 WebSecurity
WebSecurity這個類可以向spring容器添加對象,同時還維護著一個LinkedHashMap用來存儲所有的WebSecurityConfigurerAdapter,WebSecurityConfigurerAdapter是配置springSecurity要繼承的類

接下來看這個類org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration
代碼如下

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

代碼分析
上面代碼會通過AutowireBeanFactoryObjectPostProcessor向spring容器注冊一個對象WebSecurityConfigurerAdapter,然后將WebSecurityConfigurerAdapter存儲到webSecurity中,
然后調用webSecurity的build方法,執行代碼如下

protected final O doBuild() throws Exception {//configurers 是webSecurity中存儲WebSecurityConfigurerAdapter的LinkedHashMapsynchronized (configurers) {//通過枚舉修改狀態buildState = BuildState.INITIALIZING;//空方法 用于擴展beforeInit();//調用configurers集合中所有對象的init方法//當前集合中只有一個對象 WebSecurityConfigurerAdapterinit();buildState = BuildState.CONFIGURING;beforeConfigure();//調用configurers集合中所有對象的configure方法configure();buildState = BuildState.BUILDING;O result = performBuild();buildState = BuildState.BUILT;return result;} }

接下來依次分析 init()、beforeConfigure()、configure()、performBuild()方法,WebSecurityConfigurerAdapter中

此部分代碼比較多分部分析,代碼如下

public void init(final WebSecurity web) throws Exception {//創建一個HttpSecurityfinal HttpSecurity http = getHttp();web.addSecurityFilterChainBuilder(http).postBuildAction(() -> {FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);//給WebSecurity設置一個攔截器web.securityInterceptor(securityInterceptor);});protected final HttpSecurity getHttp() throws Exception {//首先創建DefaultAuthenticationEventPublisher對象然后將這個對象添加到spring容器中//此對象維護著一個exceptionMappings對象,存儲異常和ApplicationEventDefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor.postProcess(new DefaultAuthenticationEventPublisher());//將eventPublisher給localConfigureAuthenticationBldr代理//localConfigureAuthenticationBldr 也就是 AuthenticationManagerBuilder對象localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);AuthenticationManager authenticationManager = authenticationManager();authenticationBuilder.parentAuthenticationManager(authenticationManager);authenticationBuilder.authenticationEventPublisher(eventPublisher);Map<Class<?>, Object> sharedObjects = createSharedObjects();//創建http對象,其中FilterComparator中存儲了32個過濾器 http = new HttpSecurity(objectPostProcessor, authenticationBuilder,sharedObjects);if (!disableDefaults) {// 往HttpSecurity添加一些列的 配置類//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();//添加一些默認配置List<AbstractHttpConfigurer> defaultHttpConfigurers =SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);//添加一些默認配置for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {http.apply(configurer);}}//調用自己配置的 configure方法,添加一些Configurerconfigure(http);return http;}protected AuthenticationManager authenticationManager() throws Exception {//這里僅僅用一個標志位不用鎖 也不會線程不安全//因為build 方法中通過 //if(AtomicBoolean.compareAndSet(false, true)){}if (!authenticationManagerInitialized) {//調用配置的configure方法//方法中我們給 provider的 UserDetailsService,passwordEncoder 成員變量賦值//同時添加DaoAuthenticationConfigurer 對象configure(localConfigureAuthenticationBldr);if (disableLocalConfigureAuthenticationBldr) {//如果我們沒有重寫configure方法則調用這里邏輯authenticationManager = authenticationConfiguration.getAuthenticationManager();}else {//localConfigureAuthenticationBldr 也就是 AuthenticationManagerBuilder對象//AuthenticationManagerBuilder中的configurers中只有一個對象DaoAuthenticationConfigurer//調用 DaoAuthenticationConfigurer 的doBuild方法//方法中會通過包裝創建一個ProviderManagerauthenticationManager = localConfigureAuthenticationBldr.build();}authenticationManagerInitialized = true;}return authenticationManager;}private void configure() throws Exception {Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();//循環調用所有配置類的方法//有的configurer中的configure方法會添加攔截器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中存儲所有的 HttpSecurityfor (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {//在方法中循環遍歷所有HttpSecurity中configurers //configurers 是webSecurity中存儲WebSecurityConfigurerAdapter的LinkedHashMap//調用所有配置類的configurer 的 init configure 方法//securityFilterChains.add(securityFilterChainBuilder.build());}//通過FilterChainProxy對securityFilterChains進行包裝FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);if (httpFirewall != null) {filterChainProxy.setFirewall(httpFirewall);}filterChainProxy.afterPropertiesSet();Filter result = filterChainProxy;postBuildAction.run();return result;} }

上面代碼通過CsrfConfigurer、ExceptionHandlingConfigurer、HeadersConfigurer、SessionManagementConfigurer、SecurityContextConfigurer、RequestCacheConfigurer、AnonymousConfigurer 、ServletApiConfigurer、DefaultLoginPageConfigurer、LogoutConfigurer 等對象的 configure 方法 添加過濾器,我們配置對應的Configurer對象就能修改過濾器要攔截的內容,過濾器如下

WebAsyncManagerIntegrationFilter

SecurityContextPersistenceFilter

HeaderWriterFilter

CsrfFilter

LogoutFilter

MyTokenFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

DefaultLogoutPageGeneratingFilter

RequestCacheAwareFilter

SecurityContextHolderAwareRequestFilter

AnonymousAuthenticationFilter

SessionManagementFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

總結

以上是生活随笔為你收集整理的志宇-springSecurty的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。