OAuth2客戶端按照它們與授權伺服器進行安全認證的能力可以分為機密類型(Confidential)和公共類型(Public)。 機密類型的自身會有個密碼憑據,比如Web伺服器後端程式;而公共類型則沒有密碼憑據,純瀏覽器前端應用或者移動客戶端應用大都屬於這一種類型。不管是哪一種,它們都有客戶端ID( ...
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 獲取更多資訊
博主:碼農小胖哥 出處:felord.cn 本文版權歸原作者所有,不可商用,轉載需要聲明出處,否則保留追究法律責任的權利。如果文中有什麼錯誤,歡迎指出。以免更多的人被誤導。 |