2016-11-15 15 views
1

私はマルチテナントアプリケーションを正常にセットアップしました。 今のところ、私はユーザーを認証し、トークンを使用して他のリソースにアクセスすることができます。 (Microsoft Graph & Microsoft AD Graph)マルチテナントアプリケーションでのB2Bアクセス

今、私はB2Bを稼働させたいと思っています。 電流の流れ: - におけるユーザー兆し - AuthorizationCodeReceivedは($ commonAuthorityエンドポイントを経由して)トークンを取得を取得し - とき$ tenantAuthority広告グラフのトークンを要求するとき、私は$ tenantAuthorityに

を使用しています。これは完璧に動作します

しかし、私は別のテナントから(実際のテナントに信頼を置いて)ログインし、$ tenantAuthority = trusted authorityを使用すると、私は常に次のエラーが表示されます。 リフレッシュトークンに失敗しました: AADSTS65001:ユーザーまたは管理者は、

$ tenantAuthorityを、ユーザーが作成された「ソース」テナント機関に変更すると、すべて正常に動作します。

ご協力いただければ幸いです。

更新:コードサンプル

のAppは2つのテナント(tenantAエンtenantB)を持っており、私は、このユーザーに信頼与えtenantAでtenantBからユーザーを使用します。

AuthorizationCodeReceived = async context => 
        { 
         TenantContext.TenantId = "someguid"; 
         var tenantId = 
          TenantContext.TenantId; 

         // get token cache via func, because the userid is only known at runtime 
         var getTokenCache = container.Resolve<Func<string, TokenCache>>(); 
         var userId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.ObjectIdentifier).Value; 
         var tokenCache = getTokenCache(userId); 
         var authenticationContext = new AuthenticationContext($"{configuration.Authority}", 
          tokenCache); 

         await authenticationContext.AcquireTokenByAuthorizationCodeAsync(
          context.Code, 
          new Uri(context.Request.Uri.GetLeftPart(UriPartial.Authority)), 
          new ClientCredential(configuration.ClientId, configuration.ClientSecret), 
          configuration.GraphResourceId); 
        } 

このコードは完全に機能します。両方のテナントからのユーザーとのログインは完全に機能します。

しかし、私はグラフサービスクライアントまたはActiveDirectoryClientが必要なときに、特定のテナントのAPIに対処できるようにアクセストークンを取得する必要があります。私は2つのクライアントSDK年代のひとつで要求を行うと

public IGraphServiceClient CreateGraphServiceClient() 
    { 
     var client = new GraphServiceClient(
      new DelegateAuthenticationProvider(
       async requestMessage => 
       { 
        Logger.Debug("Retrieving authentication token to use in Microsoft Graph."); 

        string token; 
        var currentUserHomeTenantId = TenantContext.TenantId; 
        var currentUserObjectId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.ObjectIdentifier).Value; 
        var authenticationContext = 
         new AuthenticationContext($"{_configuration.TenantAuthorityPrefix}{currentUserHomeTenantId}", 
          _tokenCacheFactoryMethod(currentUserObjectId)); 
        var clientCredential = new ClientCredential(_configuration.ClientId, _configuration.ClientSecret); 

        try 
        { 
         token = await GetTokenSilently(authenticationContext, _configuration.GraphResourceId, currentUserObjectId); 
        } 
        catch (AdalSilentTokenAcquisitionException e) 
        { 
         Logger.Error("Failed to retrieve authentication token silently, trying to refresh the token.", e); 
         var result = await authenticationContext.AcquireTokenAsync(_configuration.GraphResourceId, clientCredential); 
         token = result.AccessToken; 
        } 

        requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationHeaderKeys.Bearer, token); 
       })); 

     return client; 
    } 


    public IActiveDirectoryClient CreateAdClient() 
    { 
     var currentUserHomeTenantId = TenantContext.TenantId; 
     var currentUserObjectId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.ObjectIdentifier).Value; 
     var graphServiceUrl = $"{_configuration.AdGraphResourceId}/{currentUserHomeTenantId}"; 
     var tokenCache = _tokenCacheFactoryMethod(currentUserObjectId); 

     var client = new ActiveDirectoryClient(new Uri(graphServiceUrl), 
      () => GetTokenSilently(
       new AuthenticationContext(
        $"{_configuration.TenantAuthorityPrefix}{ClaimsPrincipal.Current.FindFirst(ClaimTypes.TenantId).Value}", tokenCache 
       ), 
       _configuration.AdGraphResourceId, currentUserObjectId 
      )); 

     return client; 
    } 

、私は次のエラーを得た:AADSTS65001: は、リフレッシュトークンを失敗したユーザーまたは管理者は、に同意していない私はこのようなアクセストークンを取得しますIDを持つアプリケーションを使用します。

+0

あなたが同意ページを見ました他のテナントから?そうでない場合は、ログインについてどうすればよいでしょうか? –

答えて

0

がキャッチ方法を変更するトリックでした:あなたがアカウントを使ってログインしたとき

if(e.ErrorCode == "failed_to_acquire_token_silently") 
{ 
    HttpContext.Current.Response.Redirect(authenticationContext.GetAuthorizationRequestUrlAsync(resourceId, _configuration.ClientId, new Uri(currentUrl), 
         new UserIdentifier(currentUserId, UserIdentifierType.UniqueId), string.Empty); 
} 
0

私はそれについて言及していません:B2Bコラボレーションでは、まず他のテナントからユーザーを招待しなければなりません。手順は、そのようなものです:

  • を招待し、カンマ区切りの値をアップロードすることにより、外部ユーザーのセットを認可 -
  • 招待状が外部のユーザーに送信されますCSVファイル。
  • 招待されたユーザーは、Microsoft(Azure ADで管理)で既存の仕事用アカウントにサインインするか、Azure ADで新しい仕事用アカウントを取得します。
  • で署名した後、ユーザーは、私の場合には完璧に動作し、彼らと

を共有したアプリにリダイレクトされます。私が検出してきたいくつかの問題について

末尾「/」Active Directoryリソースの終わりに - これは問題を引き起こす可能性として、それを削除してみてください。 AzureのADにプロビジョニングさ

string aadTenant = WebServiceClientConfiguration.Settings.ActiveDirectoryTenant; 
string clientAppId = WebServiceClientConfiguration.Settings.ClientAppId; 
string clientKey = WebServiceClientConfiguration.Settings.ClientKey; 
string aadResource = WebServiceClientConfiguration.Settings.ActiveDirectoryResource; 

AuthenticationContext authenticationContext = new AuthenticationContext(aadTenant); 
ClientCredential clientCredential = new ClientCredential(clientAppId, clientKey); 
UserPasswordCredential upc = new UserPasswordCredential(WebServiceClientConfiguration.Settings.UserName, WebServiceClientConfiguration.Settings.Password); 

AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(aadResource, clientAppId, upc); 

return authenticationResult.CreateAuthorizationHeader(); 

アプリケーションは、デフォルトでのOAuth2暗黙の助成金を使用することが有効になっていません:あなたは、認証ヘッダを取得するためのいくつかのコードを見つけます怒鳴ります。明示的オプトインする必要があります - 詳細はここで見つけることができます:トークンを取得する際Azure AD OAuth2 implicit grant

+0

ちょっと考えて、Graph APIを使用してこの追加および招待操作を呼び出すことはできません。 – Rahul

+0

私は100%確実ではないと思います... –

+0

ユーザーの追加と招待は別々のものです。これはユーザーを招待しており、まだプレビュー中です。 https://graph.microsoft.io/en-us/docs/api-reference/beta/resources/invitation - Rest API – Rahul

関連する問題