真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

SecurityConfigurer怎么配置

本篇內(nèi)容介紹了“SecurityConfigurer怎么配置”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

南木林網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,南木林網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為南木林上1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個售后服務(wù)好的南木林做網(wǎng)站的公司定做!

1. SecurityConfigurer

SecurityConfigurer 本身是一個接口,我們來看下:

public interface SecurityConfigurer> {

 void init(B builder) throws Exception;

 void configure(B builder) throws Exception;
}
 

可以看到,SecurityConfigurer 中主要是兩個方法,init 和 configure。

init 就是一個初始化方法。而 configure 則是一個配置方法。這里只是規(guī)范了方法的定義,具體的實(shí)現(xiàn)則在不同的實(shí)現(xiàn)類中。

需要注意的是這兩個方法的參數(shù)類型都是一個泛型 B,也就是 SecurityBuilder 的子類,關(guān)于 SecurityBuilder ,它是用來構(gòu)建過濾器鏈的。

SecurityConfigurer 有三個實(shí)現(xiàn)類:

  • SecurityConfigurerAdapter
  • GlobalAuthenticationConfigurerAdapter
  • WebSecurityConfigurer

我們分別來看。

 

1.1 SecurityConfigurerAdapter

SecurityConfigurerAdapter 實(shí)現(xiàn)了 SecurityConfigurer 接口,我們所使用的大部分的 xxxConfigurer 也都是 SecurityConfigurerAdapter 的子類。

SecurityConfigurerAdapter 在 SecurityConfigurer 的基礎(chǔ)上,還擴(kuò)展出來了幾個非常好用的方法,我們一起來看下:

public abstract class SecurityConfigurerAdapter>
  implements SecurityConfigurer {
 private B securityBuilder;

 private CompositeObjectPostProcessor objectPostProcessor = new CompositeObjectPostProcessor();

 public void init(B builder) throws Exception {
 }

 public void configure(B builder) throws Exception {
 }

 public B and() {
  return getBuilder();
 }
 protected final B getBuilder() {
  if (securityBuilder == null) {
   throw new IllegalStateException("securityBuilder cannot be null");
  }
  return securityBuilder;
 }
 @SuppressWarnings("unchecked")
 protected  T postProcess(T object) {
  return (T) this.objectPostProcessor.postProcess(object);
 }
 public void addObjectPostProcessor(ObjectPostProcessor objectPostProcessor) {
  this.objectPostProcessor.addObjectPostProcessor(objectPostProcessor);
 }
 public void setBuilder(B builder) {
  this.securityBuilder = builder;
 }
 private static final class CompositeObjectPostProcessor implements
   ObjectPostProcessor {
  private List> postProcessors = new ArrayList<>();

  @SuppressWarnings({ "rawtypes", "unchecked" })
  public Object postProcess(Object object) {
   for (ObjectPostProcessor opp : postProcessors) {
    Class oppClass = opp.getClass();
    Class oppType = GenericTypeResolver.resolveTypeArgument(oppClass,
      ObjectPostProcessor.class);
    if (oppType == null || oppType.isAssignableFrom(object.getClass())) {
     object = opp.postProcess(object);
    }
   }
   return object;
  }
  private boolean addObjectPostProcessor(
    ObjectPostProcessor objectPostProcessor) {
   boolean result = this.postProcessors.add(objectPostProcessor);
   postProcessors.sort(AnnotationAwareOrderComparator.INSTANCE);
   return result;
  }
 }
}
 
  1. CompositeObjectPostProcessor 首先一開始聲明了一個 CompositeObjectPostProcessor 實(shí)例,CompositeObjectPostProcessor 是 ObjectPostProcessor 的一個實(shí)現(xiàn),ObjectPostProcessor 本身是一個后置處理器,該后置處理器默認(rèn)有兩個實(shí)現(xiàn),AutowireBeanFactoryObjectPostProcessor 和 CompositeObjectPostProcessor。其中 AutowireBeanFactoryObjectPostProcessor 主要是利用了 AutowireCapableBeanFactory 對 Bean 進(jìn)行手動注冊,因?yàn)樵?Spring Security 中,很多對象都是手動 new 出來的,這些 new 出來的對象和容器沒有任何關(guān)系,利用 AutowireCapableBeanFactory 可以將這些手動 new 出來的對象注入到容器中,而 AutowireBeanFactoryObjectPostProcessor 的主要作用就是完成這件事;CompositeObjectPostProcessor 則是一個復(fù)合的對象處理器,里邊維護(hù)了一個 List 集合,這個 List 集合中,大部分情況下只存儲一條數(shù)據(jù),那就是 AutowireBeanFactoryObjectPostProcessor,用來完成對象注入到容器的操作,如果用戶自己手動調(diào)用了 addObjectPostProcessor 方法,那么 CompositeObjectPostProcessor 集合中維護(hù)的數(shù)據(jù)就會多出來一條,在 CompositeObjectPostProcessor#postProcess 方法中,會遍歷集合中的所有 ObjectPostProcessor,挨個調(diào)用其 postProcess 方法對對象進(jìn)行后置處理。
  2. and 方法,該方法返回值是一個 securityBuilder,securityBuilder 實(shí)際上就是 HttpSecurity,我們在 HttpSecurity 中去配置不同的過濾器時,可以使用 and 方法進(jìn)行鏈?zhǔn)脚渲茫褪且驗(yàn)檫@里定義了 and 方法并返回了 securityBuilder 實(shí)例。

這便是 SecurityConfigurerAdapter 的主要功能,后面大部分的 xxxConfigurer 都是基于此類來實(shí)現(xiàn)的。

 

1.2 GlobalAuthenticationConfigurerAdapter

GlobalAuthenticationConfigurerAdapter 看名字就知道是一個跟全局配置有關(guān)的東西,它本身實(shí)現(xiàn)了 SecurityConfigurerAdapter 接口,但是并未對方法做具體的實(shí)現(xiàn),只是將泛型具體化了:

@Order(100)
public abstract class GlobalAuthenticationConfigurerAdapter implements
  SecurityConfigurer {

 public void init(AuthenticationManagerBuilder auth) throws Exception {
 }

 public void configure(AuthenticationManagerBuilder auth) throws Exception {
 }
}
 

可以看到,SecurityConfigurer 中的泛型,現(xiàn)在明確成了 AuthenticationManager 和 AuthenticationManagerBuilder。所以 GlobalAuthenticationConfigurerAdapter 的實(shí)現(xiàn)類將來主要是和配置 AuthenticationManager 有關(guān)。當(dāng)然也包括默認(rèn)的用戶名密碼也是由它的實(shí)現(xiàn)類來進(jìn)行配置的。

我們在 Spring Security 中使用的 AuthenticationManager 其實(shí)可以分為兩種,一種是局部的,另一種是全局的,這里主要是全局的配置。

 

1.3 WebSecurityConfigurer

還有一個實(shí)現(xiàn)類就是 WebSecurityConfigurer,這個可能有的小伙伴比較陌生,其實(shí)他就是我們天天用的 WebSecurityConfigurerAdapter 的父接口。

所以 WebSecurityConfigurer 的作用就很明確了,用戶擴(kuò)展用戶自定義的配置。

SecurityConfigurer 默認(rèn)主要是這三個實(shí)現(xiàn),考慮到大多數(shù)的過濾器配置都是通過 SecurityConfigurerAdapter 進(jìn)行擴(kuò)展的,因此我們今天就通過這條線進(jìn)行展開。

 

2. SecurityConfigurerAdapter

SecurityConfigurerAdapter 的實(shí)現(xiàn)主要也是三大類:

  • UserDetailsAwareConfigurer
  • AbstractHttpConfigurer
  • LdapAuthenticationProviderConfigurer

考慮到 LDAP 現(xiàn)在使用很少,所以這里我來和大家重點(diǎn)介紹下前兩個。

 

2.1 UserDetailsAwareConfigurer

這個配置類看名字大概就知道這是用來配置用戶類的。

SecurityConfigurer怎么配置  

AbstractDaoAuthenticationConfigurer

AbstractDaoAuthenticationConfigurer 中所做的事情比較簡單,主要是構(gòu)造了一個默認(rèn)的 DaoAuthenticationProvider,并為其配置 PasswordEncoder 和 UserDetailsService。

UserDetailsServiceConfigurer

UserDetailsServiceConfigurer 重寫了 AbstractDaoAuthenticationConfigurer 中的 configure 方法,在 configure 方法執(zhí)行之前加入了 initUserDetailsService 方法,以方便開發(fā)展按照自己的方式去初始化 UserDetailsService。不過這里的 initUserDetailsService 方法是空方法。

UserDetailsManagerConfigurer

UserDetailsManagerConfigurer 中實(shí)現(xiàn)了 UserDetailsServiceConfigurer 中定義的 initUserDetailsService 方法,具體的實(shí)現(xiàn)邏輯就是將 UserDetailsBuilder 所構(gòu)建出來的 UserDetails 以及提前準(zhǔn)備好的 UserDetails 中的用戶存儲到 UserDetailsService 中。

該類同時添加了 withUser 方法用來添加用戶,同時還增加了一個 UserDetailsBuilder 用來構(gòu)建用戶,這些邏輯都比較簡單,小伙伴們可以自行查看。

JdbcUserDetailsManagerConfigurer

JdbcUserDetailsManagerConfigurer 在父類的基礎(chǔ)上補(bǔ)充了 DataSource 對象,同時還提供了相應(yīng)的數(shù)據(jù)庫查詢方法。

InMemoryUserDetailsManagerConfigurer

InMemoryUserDetailsManagerConfigurer 在父類的基礎(chǔ)上重寫了構(gòu)造方法,將父類中的 UserDetailsService 實(shí)例定義為 InMemoryUserDetailsManager。

DaoAuthenticationConfigurer

DaoAuthenticationConfigurer 繼承自 AbstractDaoAuthenticationConfigurer,只是在構(gòu)造方法中修改了一下 userDetailsService 而已。

有小伙伴可能要問了,JdbcUserDetailsManagerConfigurer 或者 InMemoryUserDetailsManagerConfigurer,到底在哪里可以用到呀?

松哥給大家舉一個簡單的例子:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("javaboy")
                .password("{noop}123")
                .roles("admin");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                //省略
    }
}
 

當(dāng)你調(diào)用 auth.inMemoryAuthentication 進(jìn)行配置時,實(shí)際上調(diào)用的就是 InMemoryUserDetailsManagerConfigurer。

這下明白了吧!

 

2.2 AbstractHttpConfigurer

AbstractHttpConfigurer 這一派中的東西非常多,我們所有的過濾器配置,都是它的子類,我們來看下都有哪些類?

SecurityConfigurer怎么配置  

可以看到,它的實(shí)現(xiàn)類還是非常多的。

我們一個一個來看。

 
2.2.1 AbstractHttpConfigurer

AbstractHttpConfigurer 繼承自 SecurityConfigurerAdapter,并增加了兩個方法,disable 和 withObjectPostProcessor:

public abstract class AbstractHttpConfigurer, B extends HttpSecurityBuilder>
  extends SecurityConfigurerAdapter {

 /**
  * Disables the {@link AbstractHttpConfigurer} by removing it. After doing so a fresh
  * version of the configuration can be applied.
  *
  * @return the {@link HttpSecurityBuilder} for additional customizations
  */
 @SuppressWarnings("unchecked")
 public B disable() {
  getBuilder().removeConfigurer(getClass());
  return getBuilder();
 }

 @SuppressWarnings("unchecked")
 public T withObjectPostProcessor(ObjectPostProcessor objectPostProcessor) {
  addObjectPostProcessor(objectPostProcessor);
  return (T) this;
 }
}
 

這兩個方法松哥之前都有給大家介紹過,disable 基本上是大家的老熟人了,我們常用的 .csrf().disable() 就是出自這里,那么從這里我們也可以看到 disable 的實(shí)現(xiàn)原理,就是從 getBuilder 中移除相關(guān)的 xxxConfigurer,getBuilder 方法獲取到的實(shí)際上就是 HttpSecurity,所以移除掉 xxxConfigurer 實(shí)際上就是從過濾器鏈中移除掉某一個過濾器,例如 .csrf().disable() 就是移除掉處理 csrf 的過濾器。

另一個增加的方法是 withObjectPostProcessor,這是為配置類添加手動添加后置處理器的。在 AbstractHttpConfigurer 的父類中其實(shí)有一個類似的方法就是 addObjectPostProcessor,但是 addObjectPostProcessor 只是一個添加方法,返回值為 void,而 withObjectPostProcessor 的返回值是當(dāng)前配置類,也就是 xxxConfigurer,所以如果使用 withObjectPostProcessor 的話,可以使用鏈?zhǔn)脚渲谩?/p> 

2.2.2 AbstractAuthenticationFilterConfigurer

AbstractAuthenticationFilterConfigurer 類的功能比較多,源碼也是相當(dāng)相當(dāng)長。不過我們只需要抓住兩點(diǎn)即可,init 方法和 configure 方法,因?yàn)檫@兩個方法是所有 xxxConfigurer 的靈魂。

@Override
public void init(B http) throws Exception {
 updateAuthenticationDefaults();
 updateAccessDefaults(http);
 registerDefaultAuthenticationEntryPoint(http);
}
 

init 方法主要干了三件事:

  1. updateAuthenticationDefaults 主要是配置了登錄處理地址,失敗跳轉(zhuǎn)地址,注銷成功跳轉(zhuǎn)地址。
  2. updateAccessDefaults 方法主要是對 loginPage、loginProcessingUrl、failureUrl 進(jìn)行 permitAll 設(shè)置(如果用戶配置了 permitAll 的話)。
  3. registerDefaultAuthenticationEntryPoint 則是注冊異常的處理器。

再來看 configure 方法:

@Override
public void configure(B http) throws Exception {
 PortMapper portMapper = http.getSharedObject(PortMapper.class);
 if (portMapper != null) {
  authenticationEntryPoint.setPortMapper(portMapper);
 }
 RequestCache requestCache = http.getSharedObject(RequestCache.class);
 if (requestCache != null) {
  this.defaultSuccessHandler.setRequestCache(requestCache);
 }
 authFilter.setAuthenticationManager(http
   .getSharedObject(AuthenticationManager.class));
 authFilter.setAuthenticationSuccessHandler(successHandler);
 authFilter.setAuthenticationFailureHandler(failureHandler);
 if (authenticationDetailsSource != null) {
  authFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
 }
 SessionAuthenticationStrategy sessionAuthenticationStrategy = http
   .getSharedObject(SessionAuthenticationStrategy.class);
 if (sessionAuthenticationStrategy != null) {
  authFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy);
 }
 RememberMeServices rememberMeServices = http
   .getSharedObject(RememberMeServices.class);
 if (rememberMeServices != null) {
  authFilter.setRememberMeServices(rememberMeServices);
 }
 F filter = postProcess(authFilter);
 http.addFilter(filter);
}
 

configure 中的邏輯就很簡答了,構(gòu)建各種各樣的回調(diào)函數(shù)設(shè)置給 authFilter,authFilter 再去 postProcess 中走一圈注冊到 Spring 容器中,最后再把 authFilter 添加到過濾器鏈中。

這便是 AbstractAuthenticationFilterConfigurer 的主要功能。需要提醒大家的是,我們?nèi)粘E渲玫?,如?/p>

  • loginPage
  • loginProcessingUrl
  • permitAll
  • defaultSuccessUrl
  • failureUrl
  • ...

等方法都是在這里定義的。

最后我們再來看看 FormLoginConfigurer。

 
2.2.3 FormLoginConfigurer

FormLoginConfigurer 在定義是,明確了 AbstractAuthenticationFilterConfigurer 中的泛型是 UsernamePasswordAuthenticationFilter,也就是我們這里最終要配置的過濾是 UsernamePasswordAuthenticationFilter。

FormLoginConfigurer 重寫了 init 方法,配置了一下默認(rèn)的登錄頁面。其他的基本上都是從父類來的,未做太多改變。

另外我們?nèi)粘E渲玫暮芏鄸|西也是來自這里:

SecurityConfigurer怎么配置  

好啦,這就是 FormLoginConfigurer 這個配置類,F(xiàn)ormLoginConfigurer 對應(yīng)的過濾器是 UsernamePasswordAuthenticationFilter,小伙伴們可以自行分析其他的 xxxConfigurer,每一個 xxxConfigurer 都對應(yīng)了一個 不同的 Filter。

“SecurityConfigurer怎么配置”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


分享文章:SecurityConfigurer怎么配置
新聞來源:http://weahome.cn/article/jdsehi.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部