2016-11-03 3 views
1

マルチテナントアプリケーションを設定していて、GraphServiceClientを作成する際に問題が発生しています。認証コンテキストから受け取ったトークンが有効でない

私はAuthorizationCodeReceivedを次のようにあります

AuthorizationCodeReceived = async context => 
        { 
         var tenantId = 
          context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value; 

         var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/"+ tenantId); 
         await authenticationContext.AcquireTokenByAuthorizationCodeAsync(
          context.Code, 
          new Uri("http://localhost:21925"), 
          new ClientCredential(ClientId, ClientSecret), 
          "https://graph.microsoft.com"); 
        } 

これは、ユーザーを認証するために完璧に動作します。私はシオマネキを使用しています、と私は新しいベアラトークンがlogin.microsoftonline.com/{tenantid}/oauth2/token

新しいグラフサービスクライアントを作成するときに、私は以下のファクトリメソッドを使用することによって与えられたことを参照してください。

public IGraphServiceClient CreateGraphServiceClient() 
    { 
     var client = new GraphServiceClient(
      new DelegateAuthenticationProvider(
       async requestMessage => 
       { 
        string token; 
        var currentUserId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value; 
        var currentUserHomeTenantId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value; 
        var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/" + currentUserHomeTenantId + "/"); 
        var clientCredential = new ClientCredential(_configuration.ClientId, _configuration.ClientSecret); 

        try 
        { 
         var authenticationResult = await authenticationContext.AcquireTokenSilentAsync(
          GraphResourceId, 
          clientCredential, 
          new UserIdentifier(currentUserId, UserIdentifierType.UniqueId)); 

         token = authenticationResult.AccessToken; 
        } 
        catch (AdalSilentTokenAcquisitionException e) 
        { 
         var result = await authenticationContext.AcquireTokenAsync(GraphResourceId, clientCredential); 
          token = result.AccessToken; 
        } 

        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token); 
       })); 

     return client; 
    } 

このメソッドは常にAdalSilentAcquisitionExceptionをスローし、AcquireTokenAsyncは新しいトークンを取得します。

このトークンを使用して、グラフに「Me」をリクエストすることはできません。 次の例外が発生します。message =リソース 'some guid'が存在しないか、または照会された参照プロパティオブジェクトの1つが存在しません。

しかし、私がデバッグしていて、トークンがヘッダーに渡される前にトークンを変更した場合、以前にログインした直後のトークンの値が変更されます(login.microsoftonline.com/{tenantid}/oauth2から受信しました)。/token)、API呼び出しが機能します。

誰かが私が間違っていることを知っていますか?彼は、私が取得することはできますか?

更新:コードサンプルを更新しました。カスタムキャッシュを削除したところ、すべてが機能しているようです。

httpセッションに基づいてカスタムキャッシュを作成し、AcquireTokenSilentlyが動作することを確認するにはどうすればよいですか。

トークンキャッシュを働いていないのプレビュー:

public class WebTokenCache : TokenCache 
{ 
    private readonly HttpContext _httpContext; 
    private readonly string _cacheKey; 
    public WebTokenCache() 
    { 
     _httpContext = HttpContext.Current; 
     var claimsPrincipal = (ClaimsPrincipal) HttpContext.Current.User; 
     _cacheKey = BuildCacheKey(claimsPrincipal); 

     AfterAccess = AfterAccessNotification; 

     LoadFromCache(); 
    } 

    private string BuildCacheKey(ClaimsPrincipal claimsPrincipal) 
    { 
     var clientId = claimsPrincipal.FindFirst("aud").Value; 
     return $"{claimsPrincipal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value}_TokenCache"; 
    } 

    private void LoadFromCache() 
    { 
     var token = _httpContext.Cache[_cacheKey]; 
     if (token == null) return; 

     Deserialize((byte[]) token); 
    } 

    private void AfterAccessNotification(TokenCacheNotificationArgs args) 
    { 
     if (!HasStateChanged) return; 

     if (Count > 0) 
     { 
      _httpContext.Cache[_cacheKey] = Serialize(); 
     } 
     else 
     { 
      _httpContext.Cache.Remove(_cacheKey); 
     } 

     HasStateChanged = false; 
    } 
} 

答えて

1

私は上記のコードを使用しようとしていますし、それは私を形成うまく動作します。

GraphResourceIdがresrouceに基づいてキャッシュからトークンを取得しようとする方法AcquireTokenSilentAsyncので、(このリソースは、スタートアップクラスで初めて要求されている)https://graph.microsoft.comであることを確認してください。

+0

Fei Wue、あなたの返信ありがとう、私の更新された質問を参照してください。今のところ私はカスタムトークンキャッシュを削除して、すべてがうまくいくようです。カスタムTokenCacheをどのように動作させることができるか考えていますか? (プロダクションWebアプリケーションでは、そのままのTokenCacheを使用することはお勧めしません) – Identity

+0

カスタムキャッシュを機能させるには、「AuthenticationContext」を構築するたびにそれを使用する必要があります。このシナリオでは、OAuthコードを使用してトークンを取得するときに、スタートアップクラスのキャッシュも使用する必要があります。 –

+0

それは私のためのトリックでした。お返事をありがとうございます。もう1つの質問ですが、私はAdalSilentTokenAcquisitionExceptionがスローされたときに正しいことをしていますか?なぜなら、AcquireTokenAsyncでトークンを取得すると、トークンは常に無効であるように見えるので、アイデアはありますか? – Identity

関連する問題