亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring Security保護用戶密碼常用方法詳解

 更新時間:2020年09月07日 09:59:09   作者:碼農(nóng)小胖哥  
這篇文章主要介紹了Spring Security保護用戶密碼常用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

1. 前言

本節(jié)將對 Spring Security 中的密碼編碼進行一些探討。

2. 不推薦使用md5

首先md5 不是加密算法,是哈希摘要。以前通常使用其作為密碼哈希來保護密碼。由于彩虹表的出現(xiàn),md5 和sha1之類的摘要算法都已經(jīng)不安全了。如果有不相信的同學(xué) 可以到一些解密網(wǎng)站 如 cmd5 網(wǎng)站嘗試解密 你會發(fā)現(xiàn) md5 和 sha1 是真的非常容易被破解。

3. Spring Security中的密碼算法

ObjectProvider<PasswordEncoder>參數(shù)。這里的PasswordEncoder`就是我們對密碼進行編碼的工具接口。該接口只有兩個功能:一個是匹配驗證。另一個是密碼編碼。

上圖就是Spring Security 提供的org.springframework.security.crypto.password.PasswordEncoder一些實現(xiàn),有的已經(jīng)過時。其中我們注意到一個叫委托密碼編碼器的實現(xiàn) 。

3.1 委托密碼編碼器 DelegatingPasswordEncoder

什么是委托(Delegate)?就是甲方交給乙方的活。乙方呢手里又很多的渠道,但是乙方光想賺差價又不想干活。所以乙方根據(jù)一些規(guī)則又把活委托給了別人,讓別人來干。這里的乙方就是DelegatingPasswordEncoder 。該類維護了以下清單:

  • final String idForEncode 通過id來匹配編碼器,該id不能是{} 包括的。DelegatingPasswordEncoder 初始化傳入,用來提供默認的密碼編碼器。
  • final PasswordEncoder passwordEncoderForEncode 通過上面idForEncode所匹配到的PasswordEncoder 用來對密碼進行編碼。
  • final Map&lt;String, PasswordEncoder&gt; idToPasswordEncoder 用來維護多個idForEncode與具體PasswordEncoder的映射關(guān)系。DelegatingPasswordEncoder 初始化時裝載進去,會在初始化時進行一些規(guī)則校驗。
  • PasswordEncoder defaultPasswordEncoderForMatches = new UnmappedIdPasswordEncoder() 默認的密碼匹配器,上面的Map中都不存在就用它來執(zhí)行matches方法進行匹配驗證。這是一個內(nèi)部類實現(xiàn)。

DelegatingPasswordEncoder 編碼方法:

  @Override
  public String encode(CharSequence rawPassword) {
    return PREFIX + this.idForEncode + SUFFIX + this.passwordEncoderForEncode.encode(rawPassword);
  }

從上面源碼可以看出來通過DelegatingPasswordEncoder 編碼后的密碼是遵循一定的規(guī)則的,遵循{idForEncode}encodePassword 。也就是前綴{} 包含了編碼的方式再拼接上該方式編碼后的密碼串。

DelegatingPasswordEncoder 密碼匹配方法:

  @Override
  public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) {
    if (rawPassword == null && prefixEncodedPassword == null) {
      return true;
    }
    String id = extractId(prefixEncodedPassword);
    PasswordEncoder delegate = this.idToPasswordEncoder.get(id);
    if (delegate == null) {
      return this.defaultPasswordEncoderForMatches
        .matches(rawPassword, prefixEncodedPassword);
    }
    String encodedPassword = extractEncodedPassword(prefixEncodedPassword);
    return delegate.matches(rawPassword, encodedPassword);
  }

密碼匹配通過傳入原始密碼和遵循{idForEncode}encodePassword規(guī)則的密碼編碼串。通過獲取編碼方式id (idForEncode) 來從 DelegatingPasswordEncoder中的映射集合idToPasswordEncoder中獲取具體的PasswordEncoder進行匹配校驗。找不到就使用UnmappedIdPasswordEncoder 。

這就是 DelegatingPasswordEncoder 的工作流程。那么DelegatingPasswordEncoder 在哪里實例化呢?

3.2 密碼器靜態(tài)工廠PasswordEncoderFactories

從名字上就看得出來這是個工廠啊,專門制造 PasswordEncoder 。而且還是個靜態(tài)工廠只提供了初始化DelegatingPasswordEncoder的方法:

  @SuppressWarnings("deprecation")
  public static PasswordEncoder createDelegatingPasswordEncoder() {
    String encodingId = "bcrypt";
    Map<String, PasswordEncoder> encoders = new HashMap<>();
    encoders.put(encodingId, new BCryptPasswordEncoder());
    encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
    encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
    encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
    encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
    encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
    encoders.put("scrypt", new SCryptPasswordEncoder());
    encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
    encoders.put("SHA-256", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
    encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());

    return new DelegatingPasswordEncoder(encodingId, encoders);
  }

從上面可以非常具體地看出來DelegatingPasswordEncoder提供的密碼編碼方式。默認采用了bcrypt 進行編碼。我們可終于明白了為什么上一文中我們使用 {noop12345} 能和我們前臺輸入的12345匹配上。這么搞有什么好處呢?這可以實現(xiàn)一個場景,如果有一天我們對密碼編碼規(guī)則進行替換或者輪轉(zhuǎn)?,F(xiàn)有的用戶不會受到影響。 那么Spring Security 是如何配置密碼編碼器PasswordEncoder 呢?

4. Spring Security 加載 PasswordEncoder 的規(guī)則

我們在Spring Security配置適配器WebSecurityConfigurerAdapter(該類我以后的文章會仔細分析 可通過https://felord.cn 來及時獲取相關(guān)信息)找到了引用PasswordEncoderFactories的地方,一個內(nèi)部 PasswordEncoder實現(xiàn) LazyPasswordEncoder。從源碼上看該類是懶加載的只有用到了才去實例化。在該類的內(nèi)部方法中發(fā)現(xiàn)了 PasswordEncoder 的規(guī)則。

    // 獲取最終干活的PasswordEncoder
    private PasswordEncoder getPasswordEncoder() {
      if (this.passwordEncoder != null) {
        return this.passwordEncoder;
      }
      PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
      if (passwordEncoder == null) {
        passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
      }
      this.passwordEncoder = passwordEncoder;
      return passwordEncoder;
    }
    // 從Spring IoC容器中獲取Bean 有可能獲取不到
    private <T> T getBeanOrNull(Class<T> type) {
      try {
        return this.applicationContext.getBean(type);
      } catch(NoSuchBeanDefinitionException notFound) {
        return null;
      }
    }

上面的兩個方法總結(jié):如果能從從Spring IoC容器中獲取PasswordEncoder的Bean就用該Bean作為編碼器,沒有就使用DelegatingPasswordEncoder 。默認是 bcrypt 方式。文中多次提到該算法。而且還是Spring Security默認的。那么它到底是什么呢?

5. bcrypt 編碼算法

這里簡單提一下bcrypt, bcrypt使用的是布魯斯·施內(nèi)爾在1993年發(fā)布的 Blowfish 加密算法。bcrypt 算法將salt隨機并混入最終加密后的密碼,驗證時也無需單獨提供之前的salt,從而無需單獨處理salt問題。加密后的格式一般為:

$2a$10$/bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.6oCa
其中:$是分割符,無意義;2a是bcrypt加密版本號;10是cost的值;而后的前22位是salt值;再然后的字符串就是密碼的密文了。

5.1 bcrypt 特點

bcrypt有個特點就是非常慢。這大大提高了使用彩虹表進行破解的難度。也就是說該類型的密碼暗文擁有讓破解者無法忍受的時間成本。同時對于開發(fā)者來說也需要注意該時長是否能超出系統(tǒng)忍受范圍內(nèi)。通常是MD5的數(shù)千倍。
同樣的密碼每次使用bcrypt編碼,密碼暗文都是不一樣的。 也就是說你有兩個網(wǎng)站如果都使用了bcrypt 它們的暗文是不一樣的,這不會因為一個網(wǎng)站泄露密碼暗文而使另一個網(wǎng)站也泄露密碼暗文。
所以從bcrypt的特點上來看,其安全強度還是非常有保證的。

6. 總結(jié)

今天我們對Spring Security中的密碼編碼進行分析。發(fā)現(xiàn)了默認情況下使用bcrypt進行編碼。而密碼驗證匹配則通過密碼暗文前綴中的加密方式id控制。你也可以向Spring IoC容器注入一個PasswordEncoder類型的Bean 來達到自定義的目的。我們還對bcrypt算法進行一些簡單了解,對其特點進行了總結(jié)。后面我們會Spring Security進行進一步學(xué)習(xí)。關(guān)于上一篇文章的demo我也已經(jīng)替換成了數(shù)據(jù)庫管理用戶。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java 中Buffer源碼的分析

    java 中Buffer源碼的分析

    這篇文章主要介紹了java 中Buffer源碼的分析的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java獲取支付寶OpenID的實現(xiàn)方法

    Java獲取支付寶OpenID的實現(xiàn)方法

    在Java中,通過支付寶開放平臺API可以獲取用戶的OpenID,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • 解析SpringBoot @EnableAutoConfiguration的使用

    解析SpringBoot @EnableAutoConfiguration的使用

    這篇文章主要介紹了解析SpringBoot @EnableAutoConfiguration的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • SpringBoot中實現(xiàn)Redis緩存預(yù)熱

    SpringBoot中實現(xiàn)Redis緩存預(yù)熱

    緩存預(yù)熱是一種在系統(tǒng)啟動后,但在實際使用前將數(shù)據(jù)加載到緩存中的技術(shù),本文主要來和大家一起探討如何在Spring Boot應(yīng)用程序中實現(xiàn)Redis緩存預(yù)熱,以確保系統(tǒng)在處理請求前就已經(jīng)處于最佳狀態(tài),感興趣的可以了解下
    2023-11-11
  • java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實例

    java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實例

    這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • maven的生命周期及常用命令介紹

    maven的生命周期及常用命令介紹

    maven是一個項目構(gòu)建和管理的工具,提供了幫助管理 構(gòu)建、文檔、報告、依賴、scms、發(fā)布、分發(fā)的方法。下面通過本文給大家分享maven的生命周期及常用命令介紹,需要的朋友參考下吧
    2017-11-11
  • java實現(xiàn)五子棋大戰(zhàn)

    java實現(xiàn)五子棋大戰(zhàn)

    這篇文章主要為大家詳細介紹了java實現(xiàn)五子棋大戰(zhàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java中的布隆過濾器你真的懂了嗎

    Java中的布隆過濾器你真的懂了嗎

    經(jīng)常會聽到大家說起布隆過濾器,但是很多人都只是聽過名字,卻并不知道其是怎么實現(xiàn)的。下面將詳細介紹一下布隆過濾器,并且使用簡單的代碼演示
    2023-04-04
  • spring 和 spring boot 中的屬性配置方式

    spring 和 spring boot 中的屬性配置方式

    這篇文章主要介紹了spring 和 spring boot 中的屬性配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java結(jié)構(gòu)型設(shè)計模式之適配器模式詳解

    Java結(jié)構(gòu)型設(shè)計模式之適配器模式詳解

    適配器模式,即將某個類的接口轉(zhuǎn)換成客戶端期望的另一個接口的表示,主要目的是實現(xiàn)兼容性,讓原本因為接口不匹配,沒辦法一起工作的兩個類,可以協(xié)同工作。本文將通過示例詳細介紹適配器模式,需要的可以參考一下
    2022-09-09

最新評論