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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

9 客户端认证方式 之 PKCE

發布時間:2024/1/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 9 客户端认证方式 之 PKCE 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開講之前需要先補充點預備知識:客戶端的類型 https://oauth.net/2/client-types

OAuth2 定義了兩種類型的客戶端:機密客戶端(confidential clients)和公共客戶端(public clients)。

  • 機密客戶端(confidential clients) 指的是能夠安全地保存其 client_secret 的應用程序。例如我們的后臺服務,將 client_secret 保存在配置中,和授權服務器交互都是后臺操作,最終給到前端的只是 token,這樣client_secret是安全的。
  • 公共客戶端(public clients) 指的是無法安全地保存 client_secret 的應用程序。例如運行在瀏覽器的純前端的應用程序,無論如何,將client_secret暴露在瀏覽器,都是不安全的。

ok,鋪墊完了,開講。

none

由于公共客戶端沒法安全的保存 client_secret,所以在實際應用中,公共客戶端 連 client_secret 都沒必要存了,所以SpringAuthorizationServer定義一個 none 方式來表示這種情況。那這意味著公共客戶端就不用認證了嗎?答案是否定的!OAuth2 引入了另一個驗證的機制 PKCE(Proof Key for Code Exchange)。

PKCE(Proof Key for Code Exchange)

https://oauth.net/2/pkce/

PKCE 是授權碼流程的擴展,用于防止 CSRF 和授權碼(code)注入攻擊。 所以 PKCE 一般都伴隨著授權碼模式使用,可稱之為 增強版授權碼流程,又稱 Authorization Code with PKCE Flow。

原來的授權碼流程 如下:
\1. 客戶端發起授權請求 -> 2. 用戶授權 -> 3. 客戶端拿到code -> 4. 客戶端通過code獲取token

授權碼 + PKCE 流程 對原來流程做了如下增強:

  • 對于客戶端而言
    • 步驟1的改造:客戶端隨機生成一個字符串(稱之為明文),通過摘要算法生成一個密文,發起授權請求時,攜帶該密文摘要算法
    • 步驟4的改造:客戶端通過code獲取token時,需要攜帶上述明文
  • 對于授權服務器而言
    • 步驟1的改造:授權服務器需要記錄客戶端此次請求的密文摘要算法
    • 步驟4的改造:授權服務器收到客戶端的明文,使用同樣的摘要算法生成一個密文,和步驟1密文做對比,如果相同,才算通過驗證。

一圖勝千言:

整個示例吧,再說可能都要暈了。

示例

  • 步驟1(發起授權)多傳的pkce參數:
    code_challenge client生成的密文
    code_challenge_method:摘要算法,固定值 S256
  • 步驟4(獲取Token)多傳的pkce參數:
    code_verifier:明文
    client_id:客戶端id

環境準備

授權服務器

同樣的,基于 快速搭建一個授權服務器 文章中的示例,修改 SecurityConfiguration 中 registeredClientRepository() 方法,如下:

@Beanpublic RegisteredClientRepository registeredClientRepository() {RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()).clientId("client1")// 公共客戶端,不需要密鑰 // .clientSecret("01234567890123456789012345678912").clientAuthenticationMethod(ClientAuthenticationMethod.NONE).clientSettings(ClientSettings.builder()// 公共客戶端(NONE方式認證)必須開啟 PKCE 流程.requireProofKey(true)// 授權碼模式需要用戶手動授權!false表示默認通過.requireAuthorizationConsent(true).build()).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).redirectUri("https://cn.bing.com").scope("read").build();return new InMemoryRegisteredClientRepository(registeredClient);}

測試

  • 客戶端生成密文(這里為了便于測試,我直接將明文固定為 xx123,真正在項目用的時候得隨機生成才安全!)
  • public class ClientPkceTest {public static void main(String[] args) throws Exception {// 明文String code_verifier = "xx123";// 摘要算法String code_challenge_method = "SHA-256";// 密文String code_challenge = calc(code_verifier, code_challenge_method);System.out.println(code_challenge); // 3P6kopgvD5SwlNXyxCW-1DnPGJSNGGYn3H0vos0Xu4o}/*** 明文 + 摘要算法,生成 密文* @see CodeVerifierAuthenticator#codeVerifierValid(java.lang.String, java.lang.String, java.lang.String)*/private static String calc(String code_verifier, String code_challenge_method) throws Exception {byte[] bytes = code_verifier.getBytes(StandardCharsets.US_ASCII);MessageDigest md = MessageDigest.getInstance(code_challenge_method);byte[] digest = md.digest(bytes);String code_challenge = Base64.getUrlEncoder().withoutPadding().encodeToString(digest);return code_challenge;}}
  • 發起授權請求,瀏覽器訪問如下地址(相比于原生請求,pkce多加了 code_challenge、code_challenge_method 參數)
  • http://localhost:9000/oauth2/authorize?response_type=code&client_id=client1&redirect_uri=https%3A%2F%2Fcn.bing.com&scope=read&code_challenge=3P6kopgvD5SwlNXyxCW-1DnPGJSNGGYn3H0vos0Xu4o&code_challenge_method=S256
  • 用戶授權后,我們可以得到code
  • 發起code獲取token請求(相比于原生請求,pkce多加了 code_verifier 參數)

    綜上,便是 授權碼+PKCE 的流程。
  • 源碼分析

    這里涉及到有兩處代碼,一個授權請求是需要記錄 密文和摘要算法,一個是獲取token請求,計算明文和原來密文做驗證。

    授權請求的處理類 OAuth2AuthorizationCodeRequestAuthenticationProvider

    雖然經過層層包裝,但最終的效果就是 code_challenge、code_challenge_method 參數會被記錄起來,并和 授權碼(code)關聯(后續通過code才能取回密文和摘要算法做驗證)。暫時不用深究其他細節。

    獲取Token請求

    獲取token請求,才是真正做校驗的地方。會涉及如下關鍵類:

    PublicClientAuthenticationConverter

    校驗 code_verifier 參數是否存在,若不存在則報錯。

    PublicClientAuthenticationProvider

    核心邏輯就是:取出授權請求保存下來的code_challenge(密文)、code_challenge_method(摘要算法),和 code_verifier(明文)做校驗。其入口代碼如下:

    委托給 CodeVerifierAuthenticator 處理

    核心驗證邏輯就是用相同的摘要算法計算明文,生成一個密文和 原來的密文對比。

    以上,便是 pkce 整個流程。其他細節,讀者可自行擴展了解啦啦啦~


    end

    總結

    以上是生活随笔為你收集整理的9 客户端认证方式 之 PKCE的全部內容,希望文章能夠幫你解決所遇到的問題。

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