Azure

OAUTH / OIDC - 使用簽名的 JWT 而不是秘密的客戶端身份驗證

  • October 11, 2019

我在用盡搜尋努力後發出信號彈。我覺得我真的很接近讓這個工作,但碰壁了。下面詳細介紹了我正在嘗試完成的工作以及到目前為止所採取的步驟的範例。請指出錯誤並在可能的情況下提出建議。


我有一個在 Azure 中註冊的 OAUTH/OPENID/OIDC 應用程序,並且想要使用證書而不是客戶端密碼來驗證我的客戶端。


我生成了一個證書,將公共部分導出並上傳到配置的“證書和機密”部分。指紋:3BC87980310C490A62AA5F6343D4C55DF8EBBA85

帶有修改值的清單…

“keyCredentials”:[ { “customKeyIdentifier”:“3BC87980310C490A62AA5F6343D4C55DF8EBBA85”,“endDate”:“2020-10-10T19:45:00Z”,“keyId”:“ff3ce8e8-7268-4b46-88be-d3a191a0695e”,“ “2019-10-10T19:45:00Z”、“type”:“AsymmetricX509Cert”、“usage”:“驗證”、“value”:“LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0….”、“displayName”:“L=mycity,E =myemail@email.com,CN=jarred-test-oauth,OU=Federation,O=12345"


身份驗證非常簡單,並且能夠獲得授權碼。我用私有證書籤署了我的客戶斷言 JWT:

標題:{“alg”:“RS256”,“typ”:“JWT”}

有效載荷:{“iss”:“2f877daa-b6f5-42a3-8430-acf238b234e1”,“sub”:“2f877daa-b6f5-42a3-8430-acf238b234e1”,“nbf”:1570803651,“exp”:1570807251,“iat” :1570803651,“jti”:“3BC87980310C490A62AA5F6343D4C55DF8EBBA85”,“典型”:“JWT”}

“iss”和“sub”是我在 Azure 中的應用程序的 client_id。


我嘗試在 Postman 中使用以下程式碼測試令牌的程式碼交換:

發布:https ://login.microsoftonline.com/my-tenant/oauth2/v2.0/token

標頭:Content-Type = application/x-www-form-urlencoded

正文:grant_type = authorization_code

程式碼 = 獲得的程式碼

client_assertion_type = urn:ietf:params:oauth:client-assertion-type:jwt-bearer

client_assertion = eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIyZjg3N2RhYS1iNmY1LTQyYTMtODQzMC1hY2YyMzhiMjM0ZTEiLCJzdWIiOiIyZjg3N2RhYS1iNmY1LTQyYTMtODQzMC1hY2YyMzhiMjM0ZTEiLCJuYmYiOjE1NzA4MDM2NTEsImV4cCI6MTU3MDgwNzI1MSwiaWF0IjoxNTcwODAzNjUxLCJqdGkiOiIzQkM4Nzk4MDMxMEM0OTBBNjJBQTVGNjM0M0Q0QzU1REY4RUJCQTg1IiwidHlwIjoiSldUIn0.t8lArFodXkHO9Ps9O3q7VH55pRl6NtcIkEbSz-hDL0V6I7iWi4N-1VBNM_nFUHkNhBoGaskV0eQtqMXYildb7oEr75KgbcjacZy2OI319uPwztHp9jVxjsBhB_rKXND4M6URr23IWkLwFb2008vq_fY4trLUZR9ILZOE0Dr_MdaQmrt8fU9mYNkSEnRsiXKuqcS97oBfo6-9MuDbkcNuAOxZnsmbYvutk1LeabFywbc4qO3dgb8PtfqMAiYxgYTzg72tAw-ncq6uRXgG5XoxJVOExCyn5CXV9lSsE33_oekOEfRU5CyC0IvtSLhSoZ7LKtSMJ22ZXiyFqvddenJC8w


發送請求會從 Azure(在郵遞員中)產生以下錯誤:

{ “error”: “invalid_request”, “error_description”: “AADSTS5002723: 無效的 JWT 令牌。令牌頭中沒有指定證書指紋和 keyId。\r\n跟踪 ID: 89f69560-9ae7-482f-803c-9faa71d44100\r\n相關 ID : e2ebab72-8b4d-47a6-85be-14893158dd5e\r\n時間戳: 2019-10-11 14:23:32Z”, “error_codes”:

$$ 5002723 $$,“時間戳”:“2019-10-11 14:23:32Z”,“trace_id”:“89f69560-9ae7-482f-803c-9faa71d44100”,“correlation_id”:“e2ebab72-8b4d-47a6-85be-14893158dd5e”} 我假設標題應該包含一個 KID 或“指紋”值。我沒有 KID,因為我沒有為此目的設置面向公眾的 JWKS,並且不確定要輸入什麼作為指紋欄位。


非常感謝有人能指出我正確的方向。我已經看到了對其他發布問題的人的所有引用。我真的可以使用了解下一步該嘗試什麼的人。


以下是一些讓我走到這一步的工具和文件:

JWT 簽名工具 - http://kjur.github.io/jsjws/tool_jwt.html

Oauth 客戶端身份驗證說明 - https://medium.com/@darutk/oauth-2-0-client-authentication-4b5f929305d4

RFC 7523 OAuth JWT 斷言配置文件 - https://www.rfc-editor.org/rfc/rfc7523#section-2.2

微軟部落格 - https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2 -客戶端憑據流/

JSON Web 令牌 (JWT) - 聲明和簽名 draft-jones-json-web-token-01 - https://tools.ietf.org/id/draft-jones-json-web-token-01.html

用於客戶端身份驗證的 KB - https://kb.authlete.com/en/s/oauth-and-openid-connect/a/client-secret-jwt

謝謝!

——震動

在找到答案之前不得不驚慌失措。5天的搜尋,這是我的發現,以防其他人發現這個問題並需要幫助。

快速步驟:

  1. 生成您的私鑰(以下使用 PowerShell)
  2. 生成您的公共證書
  3. 將您的公共證書和私鑰轉換為 PEM 格式
  4. 將您的公共證書上傳到“證書和機密”下的應用程序配置中
  5. 在 Base64 中獲取證書的指紋(在創建證書時抓取或從密鑰庫或其他位置查找)
$cert=New-SelfSignedCertificate -Subject "CN=$ApplicationName" -CertStoreLocation "Cert:\CurrentUser\My"  -NotAfter (Get-Date).AddMonths(24) -KeyExportPolicy Exportable -KeySpec Signature
$bin = $cert.RawData
$base64Value = [System.Convert]::ToBase64String($bin)
$bin = $cert.GetCertHash()
$base64Thumbprint = [System.Convert]::ToBase64String($bin)
  1. 建構您的 JWT(我使用了https://jwt.io/

標題

{
 "alg": "RS256",
 "typ": "JWT",
 "x5t": "<Base64 Thumbprint>"
}

有效載荷

{
 "iss": "<clientid>",
 "sub": "<clientid>",
 "exp": 1570838377 (expiration time),
 "jti": "<random unique identifier>",
 "aud": "https://<token-endpoint>"
}

將您的私鑰 (PEM) 放入底部驗證器,這將在“編碼”視窗中籤署您的 JWT。

  1. 獲取您的授權碼
  2. 製作您的代幣請求

標題

Content-Type: application/x-www-form-urlencoded

身體

grant_type=authorization_code
code=OAQABAAIAAACQN9QBR.... (your authorization code)
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
client_assertion=eyJhbGciOiJSUzI1NiIsInR5.... (your signed JWT)
state=state (optional)
redirect_uri=https%3A%2F%2Fblackhole.com (The callback URI)
  1. POST 到您的令牌端點。如果一切按計劃進行,您應該會收到您的代幣。

引用自:https://serverfault.com/questions/987660