2015-09-09 17 views
6

WebAppとWebApiの両方で認証メカニズムを実装するためのGitHubサンプルを以下に示します。UseWindowsAzureActiveDirectoryBearerAuthenticationはトークンの検証にどのように機能しますか?

https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet

私は「https://abc.onmicrosoft.com/App」のアクセストークンを取得し、WEBAPIにそれを渡す、WebAppのとWEBAPIの両方のための単一のアプリケーション登録を使用しています。 "Bearer"という名前のHTTPSヘッダーにトークンを添付します。 WebApi Owin Startupクラスで、オーディエンスとテナントのトークンを検証するには以下のようにしますが、実際に期待通りにトークンを検証するわけではありません。

質問のいくつか: 1.テナントとオーディエンスのトークンを検証するために、以下のハンドラがトリガされますか? Controllerクラスの[Authorize]属性ですか? 2.ハンドラを実行するトークンをどこから見つけるか? 3. SaveSigninTokenをtrueに設定すると、トークンが保存されます。このトークンからトークンを取得するにはどうしたらいいですか?

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
       new WindowsAzureActiveDirectoryBearerAuthenticationOptions 
       { 
        Tenant = "abc.onmicrosoft.com", 

        TokenValidationParameters = new TokenValidationParameters 
        { 
         ValidAudience = "https://abc.onmicrosoft.com/App", 
         SaveSigninToken = true, 
        } 
       }); 

助言してください。前もって感謝します!

答えて

0

コントローラ内の[Authorize]デコレーションまたは指定したいずれかの方法で、Owinセキュリティハンドラがトークンを検証してクレームを生成します。

+0

トークンを検証するたびに紺に接続しますか? – Jaanus

+1

私はJaanusと同じ質問をしています –

+0

@Jaanusトークンには、それを検証するために必要な情報が含まれています。 – Alexander

1

以下のハンドラは、テナントとオーディエンスのトークンを検証するようにトリガされますか?

ミドルウェアはデフォルトでActiveモードで実行されるため、すべての要求でトークンを見つけようとします。見つかった場合は、それを検証しようとします。有効であると判断された場合は、ClaimsPrincipalが作成され、これはさらにOWINミドルウェアおよびWeb APIコンポーネントでアクセス可能です。

また、Azure ADからアプリ起動時にトークンシグネチャをチェックするための公開鍵をダウンロードします。あなたがFiddlerのようなツールを使用すると、これを見ることができます。

ハンドラを実行するトークンはどのようにして見つけられますか?

私はこの質問を理解しているかどうかはわかりませんが、私は上記の私の答えがプロセスを明確にすることを願っています。

SaveSigninTokenをtrueに設定すると、トークンが保存されます。このトークンからトークンを取得するにはどうしたらいいですか?

あなたがしようとしているのは、on-behalf-ofフローを使用してAPIを呼び出すことです。ここにサンプルアプリがあります:https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof。具体的には、この部分はあなたに興味があるはずです:https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/master/TodoListService/Controllers/TodoListController.cs#L133

 ClientCredential clientCred = new ClientCredential(clientId, appKey); 
     var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext; 
     string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value; 
     string userAccessToken = bootstrapContext.Token; 
     UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName); 

     string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant); 
     string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; 
     AuthenticationContext authContext = new AuthenticationContext(authority, new DbTokenCache(userId)); 

     // In the case of a transient error, retry once after 1 second, then abandon. 
     // Retrying is optional. It may be better, for your application, to return an error immediately to the user and have the user initiate the retry. 
     bool retry = false; 
     int retryCount = 0; 

     do 
     { 
      retry = false; 
      try 
      { 
       result = await authContext.AcquireTokenAsync(graphResourceId, clientCred, userAssertion); 
       accessToken = result.AccessToken; 
      } 
      catch (AdalException ex) 
      { 
       if (ex.ErrorCode == "temporarily_unavailable") 
       { 
        // Transient error, OK to retry. 
        retry = true; 
        retryCount++; 
        Thread.Sleep(1000); 
       } 
      } 
     } while ((retry == true) && (retryCount < 1));