2017-11-11 268 views
0

我正在使用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的配置中錯過了什麼嗎?

回答

0

關於你提到的第一個查詢 - 我在哪裏可以找到有關這些端點以及什麼是每個更多信息之目的...

回答 - https://login.microsoftonline.com/{租戶} /v2.0/.well-known/openid-configuration

{租戶}可以採取四個值之一:

  1. common - 擁有個人Microsoft帳戶和工作或學校帳戶的用戶f rom Azure Active Directory(Azure AD)可以登錄到應用程序。

  2. 組織 - 只有擁有來自Azure AD的工作或學校帳戶的用戶才能登錄該應用程序。

  3. 消費者 - 只有擁有個人Microsoft帳戶的用戶才能登錄該應用程序。

  4. 8eaef023-2b34-4da1-9baa-8bc8c9d6a490contoso.onmicrosoft.com - 與特定Azure的AD租戶單位或學校的帳戶的用戶纔可以登錄到應用程序。可以使用Azure AD租戶的友好域名或租戶的GUID標識符。

關於你質疑範圍 -

回答 - 請參閱本文件 - OpenID Connect scopes

關於你質疑索賠 -

答案 - 參考此GIT Hub示例 - active-directory-dotnet-webapp-roleclaims

+0

Hello Mohit。 1幫助。 2,不是真的。例如,其中一些範圍是默認發送的,正如我所說的,您不能在範圍集合中重複使用它們。關於3,我找到了一個答案:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/f10a045459e7cb07548806561a47ecdb3471f5f6/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L413 –