我正在使用MSAL獲取ID令牌,然後用它來訪問Web API應用程序。我有幾個問題,我想知道是否有人可以幫助我理解發生了什麼。MSAL和Azure AD:當我只想獲取用戶ID時,應傳遞哪些範圍?
讓我從客戶端的身份驗證過程開始。在這種情況下,我構建了一個Windows窗體應用程序,該應用程序使用以下代碼來驗證當前用戶(即,爲了獲得用於在用戶訪問Web時驗證用戶的ID令牌API應用程序):
//constructor code
_clientApp = new PublicClientApplication(ClientId,
Authority, //which url here?
TokenCacheHelper.GetUserCache());
_scopes = new []{ "user.read" }; //what to put here?
//inside a helper method
try {
return await _clientApp.AcquireTokenSilentAsync(_scopes, _clientApp.Users.FirstOrDefault());
}
catch (MsalUiRequiredException ex) {
try {
return await _clientApp.AcquireTokenAsync(_scopes);
}
catch (MsalException ex) {
return null;
}
}
我想清除的第一件事是應該用於權限參數的值。在這種情況下,我使用窗體上的網址:
https://login.microsoftonline.com/{Tenant}/oauth2/v2.0/token
不過,我的印象是,我也可以用這樣的僥倖:
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
它似乎一個端點是特定於我的Azure AD,而另一個看起來像一般(全部捕獲)URL ...我在哪裏可以找到關於這些端點的更多信息以及每個端點的目的...
另一件事我無法把握的是範圍。我對查詢MS Graph(或任何其他Azure相關服務)並不感興趣。在以前版本的MSAL庫中,可以引用其中一個默認的作用域。但是,似乎這是不可能的(至少,我試過並得到一個異常,說我不應該通過默認範圍......)。
傳遞一個空集合(例如:new List<string>()
)或null
也會導致錯誤。所以,在這種情況下,我已經結束了通過user.read
範圍(如果我沒有弄錯的話,它被MS Graph API使用了。這顯然不是必須的,但它是我設法獲得身份驗證的唯一方法當你只需要一個ID令牌時,如何進行呼叫的任何線索?我應該調用一個不同的方法嗎?
移動到服務器端,我有一個Web API應用程序,它的訪問權限是僅限於在認證頭(承載)傳遞一個ID令牌調用根據這一sample,我應該使用這樣的:現在
private void ConfigureAuth(IAppBuilder app) {
var authority = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
app.UseOAuthBearerAuthentication(
new OAuthBearerAuthenticationOptions {
AccessTokenFormat = new JwtFormat(GetTokenValidationParameters(),
new OpenIdConnectCachingSecurityTokenProvider(authority)),
Provider = new OAuthBearerAuthenticationProvider {
OnValidateIdentity = ValidateIdentity
}
});
}
,這樣做的工作,它會返回401的所有請求其不要沒有VA蓋子ID令牌。有一個問題:有沒有一種方法可以從票證的身份中指定用於識別用戶名(控制器的User.Identity.Name
)的聲明?在這種情況下,我已經結束處理OnValidateIdentity
爲了做到這一點的代碼看起來像這樣:
private Task ValidateIdentity(OAuthValidateIdentityContext arg) {
//username not getting correctly filled
//so, i'm handling this event in order to set it up
//from the preferred_username claim
if (!arg.HasError && arg.IsValidated) {
var identity = arg.Ticket.Identity;
var username = identity.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value ?? "";
if (!string.IsNullOrEmpty(username)) {
identity.AddClaim(new Claim(ClaimTypes.Name, username));
}
}
return Task.CompletedTask;
}
正如你所看到的,我在尋找從ID令牌preferred_username要求(這是由客戶獲得)並使用其值設置Name聲明。有沒有任何選項可以讓我自動執行此操作?我在OAuthBearerAuthenticationMiddleware
的配置中錯過了什麼嗎?
Hello Mohit。 1幫助。 2,不是真的。例如,其中一些範圍是默認發送的,正如我所說的,您不能在範圍集合中重複使用它們。關於3,我找到了一個答案:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/f10a045459e7cb07548806561a47ecdb3471f5f6/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L413 –