在Azure AD中,當我們撥打諸如AuthenticationContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(_clientId, _cert))
之類的電話時,不清楚究竟發生了什麼。在使用客戶端證書進行AcquireTokenAsync調用期間會發生什麼?
證書的哪部分被交換(如果有)?
是否有挑戰/響應發生?
客戶端是否需要私鑰作爲其中的一部分?
在Azure AD中,當我們撥打諸如AuthenticationContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(_clientId, _cert))
之類的電話時,不清楚究竟發生了什麼。在使用客戶端證書進行AcquireTokenAsync調用期間會發生什麼?
證書的哪部分被交換(如果有)?
是否有挑戰/響應發生?
客戶端是否需要私鑰作爲其中的一部分?
有兩種方法可以找到你的問題的答案。其中一種方法是查看.NET的的Microsoft Active Directory認證庫(ADAL),因爲這是開源的。另一個(我們將在這裏執行)是查看AcquireTokenAsync(String, ClientAssertion)
生成的網絡請求,並從那裏開始向後工作。
使用Fiddler(或任何其他流量分析器),我們可以看到類似以下(格式爲便於閱讀):
POST https://login.microsoftonline.com/{tenant-id}/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&resource=https%3A%2F%2Fgraph.windows.net
&client_id={app-id}
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ
其分解:
grant_type=client_credentials
告訴我們,這是一個令牌請求使用OAuth 2.0 Client Credentials Grant流程。resource=https%3A%2F%2Fgraph.windows.net
給出客戶端正在請求訪問令牌的資源的URI。在這種情況下,它適用於Azure AD Graph API。client_id={app-id}
是client identifier。在Azure AD中,這是已註冊應用程序的應用程序ID。client_assertion_type
存在和client_assertion
是指示該客戶端使用assertion來驗證:
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
說,所使用的客戶端斷言是有符號JSON Web Token(JWT)。client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ
是上述簽名的JWT令牌。授權服務器(例如Azure AD)將驗證內容,並檢查令牌是否確實由相關客戶授權的證書籤名。那麼,什麼ADAL做的是:
在AcquireTokenAsync
期間,只提供了證書的指紋(它包含在JWT頭中以幫助授權服務器查找相應的公鑰)。 JWT的簽名證明了客戶擁有私鑰。然而,之前AcquireTokenAsync(String, ClientAssertion)
可成功使用,客戶端所有者(即,您)需要爲Azure AD提供證書的公鑰。
這裏沒有挑戰/反應發生。令牌是在客戶端發起的單個請求中獲得的。
對於更多的細節,你可以查看標準,這一切器物:
(注意ADAL有一個緩存我上面描述的所有東西都會發生只有ADAL沒有在令牌緩存中找到有效的訪問令牌。您可以使用AuthenticationContext.TokenCache.Clear()
來清除緩存以進行實驗。)
謝謝你寫這篇精彩的文章,Philippe! –