springboot3 security 從始至終--02 PasswordEncoder

来源:https://www.cnblogs.com/zhouXX/archive/2023/02/08/17097114.html
-Advertisement-
Play Games

一、認證組件 簡介: 登錄認證的限制 認證組件是drf框架給我們提供的認證介面,它能夠在請求進入視圖函數/類前進驗證(例如:認證用戶是否登錄),對不符合認證的請求進行攔截並返回校驗失敗的信息 (1)、登錄介面 # 認證是基於登錄的介面上面操作的 所以前戲編寫一個簡單的登錄介面 models.py c ...


接下來幾個章節,將逐個介紹身份驗證流程中主要介面

介面 描述
UserDetails 代表SpringSecurity所看到的用戶
GrantedAuthority 定義應用程式目的範圍內允許用戶執行的操作(讀、寫、刪除等)
UserDetailsService 表示用於按用戶名檢索用戶詳細信息的對象
UserDetailsManager 一個較為特殊的UserDetailsService介面。除了按用戶名檢索用戶外,它還可以用於更改用戶集合或特定用戶
PasswordEncoder 指定如何對密碼進行加密或哈希化,以及檢查給定的已編碼字元串是由與明文密碼匹配

本文將一起學習相對獨立的PasswordEncoder。

一、先看看定義

package org.springframework.security.crypto.password;

/**
 * Service interface for encoding passwords.
 *
 * The preferred implementation is {@code BCryptPasswordEncoder}.
 *
 * @author Keith Donald
 */
public interface PasswordEncoder {

	/**
	 * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or
	 * greater hash combined with an 8-byte or greater randomly generated salt.
	 */
	String encode(CharSequence rawPassword);

	/**
	 * Verify the encoded password obtained from storage matches the submitted raw
	 * password after it too is encoded. Returns true if the passwords match, false if
	 * they do not. The stored password itself is never decoded.
	 * @param rawPassword the raw password to encode and match
	 * @param encodedPassword the encoded password from storage to compare with
	 * @return true if the raw password, after encoding, matches the encoded password from
	 * storage
	 */
	boolean matches(CharSequence rawPassword, String encodedPassword);

	/**
	 * Returns true if the encoded password should be encoded again for better security,
	 * else false. The default implementation always returns false.
	 * @param encodedPassword the encoded password to check
	 * @return true if the encoded password should be encoded again for better security,
	 * else false.
	 */
	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}

}

該介面定義了兩個抽象方法,其中幾個具有預設實現。在處理PasswordEncoder實現時,最常見的是抽象的encode()和matches()方法。

encode(CharSequence rawPassword)方法的目的是返回所提供字元串的轉換。就SpringSecurity功能而言,它用於為指定密碼提供加密或哈希化。

之後可以使用matches(CharSequence rawPassword, String encodedPassword)方法檢查已編碼的字元串是否與演示密碼匹配。可以在身份驗證過程中使用matches()方法根據一組已知憑據來檢驗所提供的的密碼。

第三個方法被稱為upgradeEncoding(String encodedPassword),在介面中預設設置為false。如果重寫它以返回true,那麼為了更好的安全性,將重新對已編碼的密碼進行編碼(不推薦這種方式)。

二、介面的作用

一般而言,系統並不以明文形式管理密碼,因此密碼通常要經過某種轉換,這使得讀取和竊取密碼變得較為困難。為此,SpringSecurity定義了一個單獨的介面。

實現這個介面是為了告知SpringSecurity如何驗證用戶的密碼。在身份驗證過程中,PasswordEncoder會判定密碼是否有效。每個系統都會存儲以某種方式編碼過的密碼。最好把密碼哈希化存儲起來,這樣別人就不會讀到明文密碼了。PasswordEncoder還可以對密碼進行編碼。介面聲明的encode()和matches()方式實際上是對其職責的定義。這兩個方法都是同一介面的一部分,因此它們緊密相連。應用程式對密碼進行編碼的方式與驗證密碼的方式相關。

三、實現PasswordEncoder

3.1 使用預設的PasswordEncoder

在 Spring Security 5.0 之前,PasswordEncoder 預設值是 NoOpPasswordEncoder,這需要純文本密碼。 但現在您可能期望現在的預設值類似於BCryptPasswordEncoder。但是,這忽略了三個現實世界的問題:

  • 許多應用程式使用無法輕鬆遷移的舊密碼編碼。
  • 密碼存儲的最佳做法將再次更改。
  • 作為一個框架,Spring 安全性不能經常進行重大更改。

相反,Spring Security 引入了 DelegatingPasswordEncoder,它通過以下方式解決了所有問題:

  • 確保使用當前密碼存儲建議對密碼進行編碼
  • 允許以現代和傳統格式驗證密碼
  • 允許將來升級編碼

您可以使用PasswordEncoderFactories輕鬆構造DelegatingPasswordEncoder 的實例:

PasswordEncoder passwordEncoder =  
   PasswordEncoderFactories.createDelegatingPasswordEncoder();

當然也可以選擇其它實例:

String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5());
encoders.put("pbkdf2@SpringSecurity_v5_8", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8());
encoders.put("scrypt", SCryptPasswordEncoder.defaultsForSpringSecurity_v4_1());
encoders.put("scrypt@SpringSecurity_v5_8", SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8());
encoders.put("argon2", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_2());
encoders.put("argon2@SpringSecurity_v5_8", Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8());
encoders.put("sha256", new StandardPasswordEncoder());

PasswordEncoder passwordEncoder =
    new DelegatingPasswordEncoder(idForEncode, encoders);

3.2 使用自定義的的PasswordEncoder

通常情況下,使用spring boot security自帶的password encoder已經足夠滿足使用場景了。筆者也不建議自己實現password encoder。

3.3 註入PasswordEncoder

在開發中,我們將 BCryptPasswordEncoder 的實例放入Spring容器即可

//密碼編碼器
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 使用須知 2017年下半年,微信6.5.21版本支持線上音視頻功能。開發者可以通過兩個音視頻組件 和 實現實時地線上直播、視頻通話、語音通話等功能。 上述功能需要用到兩個小程式媒體組件中的兩個: live-pusher 與 live-pl ...
  • 摘要:當協議、子功能變數名稱、主功能變數名稱、埠號中任意一個不相同時,都算作不同域。不同域之間相互請求資源,就算作“跨域”。 本文分享自華為雲社區《九種跨域方式實現原理咋回事》,作者:龍哥手記 一、什麼是跨域? 1.什麼是同源策略及其限制內容? 同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同 ...
  • 作者: 京東零售 陳震 一、 什麼是Backbone 在前端的發展道路中,前端框架元老之一jQuery對繁瑣的DOM操作進行了封裝,提供了鏈式調用、各類選擇器,屏蔽了不同瀏覽器寫法的差異性,但是前端開發過程中依然存在作用域污染、代碼復用度低、冗餘度高、數據和事件綁定煩瑣等痛點。 5年後,Backbo ...
  • 1.Api 自動導入 unplugin-auto-import自動引入 composition api,不需要再手動引入。(npm 地址) 下載 npm i -D unplugin-auto-import 配置 vite.config.ts import AutoImport from "unplu ...
  • 如果想實現chatGPT的網頁版,調用介面就可以了,但是如果需要聯繫上下文語境,就需要在傳遞的數據的時候進行下拼接 傳參的時候對所有的對話數據進行拼接,拼成下麵這樣 {"prompt":"(You:在嗎\n)這裡在哦,有什麼可以幫助你的嗎?(You:你這個系統多少錢\n)抱歉,您想知道什麼?這裡是客 ...
  • 摘要:jstat命令可以查看堆記憶體各部分的使用量,以及載入類的數量。 本文分享自華為雲社區《JVM之通過jstat命令進行查看堆記憶體使用情況》,作者:共飲一杯無 。 基本概念 jstat是JDK自帶的一個輕量級小工具。它位於java的bin目錄下,主要利用JVM內建的指令對Java應用程式的資源和性 ...
  • R2M分散式鎖原理可以理解為一條內容或者圖片+文字+鏈接的載體,常見的案例有鎖說明和分散式鎖選擇、r2m分散式鎖選擇、r2m分散式鎖原理,加鎖核心流程。 ...
  • 問題場景:當用戶量增大的時候,系統內的消息推送(比如 系統內簡訊推送,微信,釘釘,極光個推推送)將是我們常見業務場景。當系統中的用戶量逐漸增大時候,群發用戶消息的推送也將成為系統中致命的性能瓶頸。 消息推送緩衝隊列模型 意義: 構建大批量消息推送隊列,來解決大批量數據通過拉長時間隊列模式來換取性能提 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...