OAuth2客戶端按照它們與授權服務器進行安全認證的能力可以分為機密型別(Confidential)和公共型別(Public),
機密型別的自身會有個密碼憑據,比如Web服務器后端程式;而公共型別則沒有密碼憑據,純瀏覽器前端應用或者移動客戶端應用大都屬于這一種型別,不管是哪一種,它們都有客戶端ID(client_id),
OAuth2客戶端認證
客戶端在執行OAuth2授權的敏感流程中(相關的流程有令牌請求、令牌自省請求、令牌撤銷請求)必須使用授權服務器進行客戶端身份驗證,確保客戶端中途不會被調包,
客戶端認證方式
目前客戶端認證的方式有以下幾種:

前面Gitee的DEMO使用的是過時的POST方式;微信DEMO使用的是非OAuth2標準的方式;Spring Authorization Server目前相關的DEMO使用的是client_secret_basic方式,剩下的方式中client_secret_jwt和private_key_jwt用的比較多,這兩種方式可以很好地保護客戶端的認證資訊,安全性更高,Spring Security和Spring Authorization Server目前已經支持這兩種方式,
client_secret_jwt
client_secret_jwt方式是OAuth2客戶端將自己的密鑰作為HmacSHA256演算法的key生成SecretKey:
byte[] pin = clientSecret.getBytes(StandardCharsets.UTF_8);
SecretKeySpec secretKey = new SecretKeySpec(pin,"HmacSHA256");
然后通過SecretKey生成一個攜帶OAuth2客戶端資訊的JWT,在授權碼請求Token環節攜帶該JWT以便授權服務器進行客戶端認證,請求的報文為:
POST /oauth2/token HTTP/1.1
Host: oauth2_client.felord.cn
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&
client_assertion=你的JWT
授權服務器收到請求后通過OAuth2客戶端的client_secret對JWT進行解碼校驗以認證客戶端,這種方式能很好的保護client_secret在非HTTPS環境下的傳輸,
這里OAuth2客戶端的密鑰(client_secret)位元長度必須大于等于256,
private_key_jwt
private_key_jwt和client_secret_jwt唯一的區別就是生成JWT的方式不同,通過這種方式,OAuth2客戶端已經不需要client_secret,只需要配置一對RSA或者EC密鑰,通過密鑰來生成JWT,另外還需要向授權服務器提供公鑰,通常是一個jwkSetUrl,該方式的細節已經在OAuth2專欄中JOSE規范一文中進行過詳細說明了,這里不再贅述,這種方式讓客戶端的認證資訊更加安全的傳輸,是我個人比較喜歡的方式,
tls_client_auth
這個比較高級,嵌入了TLS安全層,在HTTP協議級別來認證OAuth2客戶端,它涉及的證書來自可信任的CA,這種方式基本脫離了應用層,是一種無侵入的方式,
self_signed_tls_client_auth
這個同樣也是在TLS安全層,不過它使用了自簽名的X.509證書,
總結
市面上的教程大多只會提到過時的POST方式以及client_secret_basic和client_secret_post方式,對后面的五種則很少涉及,胖哥已經對private_key_jwt和client_secret_jwt進行了實作,詳細請訂閱我的Spring Security OAuth2專欄,這些OAuth2客戶端認證方式在不同的場景有不同的優勢,你可以根據不同的安全級別選擇不同的OAuth2客戶端認證方式,
關注公眾號:Felordcn 獲取更多資訊
個人博客:https://felord.cn
|
博主:碼農小胖哥 出處:felord.cn 本文著作權歸原作者所有,不可商用,轉載需要宣告出處,否則保留追究法律責任的權利,如果文中有什么錯誤,歡迎指出,以免更多的人被誤導, |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/451222.html
標籤:Java
