2

EDIT 10/24 これはすべてユーザーエラーの可能性が高いと思います-この質問に深く入り込む前に、以下の私の回答を参照してください

TL;DR: 私の OAuth 2.0 コード フローでは...

TokenCredentialsAutoRest クライアントで動作しないのはなぜですか? リクエストにベアラー トークンが適用されていない / Authorization ヘッダーが設定されていない

私は私のパイプラインがすでに機能していることを知っています..

AutoRest クライアントではないこの azure サンプルのコードを使用するaccess_tokenと、保護された Web API プロジェクトから JSON を正常に取得できます。したがって、すべての前提条件を除外しました。

私のAutoRestセットアップ..

1.) GitHub からこの AutoRest リポジトリv1.1.0をダウンロード

2.) Swagger JSON をディスクにダウンロードし、次のように保存しました。swagger.json

3.) 次のコマンドラインを実行して、C# ファイルを生成しました。

autorest --input-file=swagger.json --csharp --output-folder=MyCorp_ApiClient_Tsl --namespace='MyCorp.ApiClient' --add-credentials

4.) 生成されたクラスを .NET 4.6.2 Web サイトにコピーしました

5.) これらは私の NuGets です:

- Microsoft.Rest.ClientRuntime version="2.3.8" 
- Microsoft.Rest.ClientRuntime.Azure.Authentication version="2.3.1" 
- Microsoft.IdentityModel.Clients.ActiveDirectory version="2.28.3" 

機能していないものは次のとおりです。

   AdalTokenHelper tokenHelper = new AdalTokenHelper();//helper code further below

    string token = await tokenHelper.GetTokenString();
    var svcClientCreds = new TokenCredentials(token, "Bearer");

    client = new MyCorp.ApiClient(new Uri(apiRsrcUrl), svcClientCreds, 
    new DelegatingHandler[] { new MyAzureTracingHandler() });

    //make call to OData controller...        
    MyCorp.ApiClient.Models.ODataResponseListStatus statusList = await client.Status.GetStatusAsync(expand: "StatusType",cancellationToken: defaultCancelThreadToken);

    return View(statusList.Value);

のさまざまな ctor を使用して、上記のバリエーションを試しましたがTokenCredentials、ブレークポイントをMyAzureTracingHandler挿入して、リクエストに Authorization ヘッダーが適用されていないことを確認できます..したがって、期待される401 Unauthorized応答が得られます。

MyAzureTracingHandlerのインスタンスを受け入れるように変更するTokenCredentialsと、要求に適切なベアラー トークンが適用されるように強制できます。

これは機能しますが、ハックっぽい感じがします:

元のクライアントのインスタンス化スニペットを次から変更しました。

 client = new ApiClient(new Uri(apiRsrcUrl), svcClientCreds, 
 new DelegatingHandler[] { new MyAzureTracingHandler() });

これに:

 client = new ApiClient(new Uri(apiRsrcUrl), svcClientCreds, 
 new DelegatingHandler[] { new MyAzureTracingHandler(svcClientCreds) });

そして、IのSendAsyncメソッド内でMyAzureTracingHanderこれを行います:

await svcClientCreds.ProcessHttpRequestAsync(request, cancellationToken);

私は何か間違ったことをしていますか?ServiceClientCredentialsクライアントをインスタンス化するときに を 2 回渡す必要はないと思います。

付録 A - ADAL 経由でアクセス トークンを取得する:

    private string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
    private string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
    private string tslResourceID = ConfigurationManager.AppSettings["ross:TslWebApiResourceId"];
    private static string loginRedirectUri = ConfigurationManager.AppSettings["ross:LoginRedirectUri"];

    private AuthenticationContext authContext;
    private AuthenticationResult authenticationResult;

    public async Task<string> GetTokenString()
    {
        string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
        string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
        string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

        try
        {
            // get a token for the Graph without triggering any user interaction (from the cache, via multi-resource refresh token, etc)
            ClientCredential clientcred = new ClientCredential(clientId, appKey);

            // initialize AuthenticationContext with the token cache of the currently signed in user, as kept in the app's database
            authContext = new AuthenticationContext(Startup.Authority, new ADALTokenCache(userObjectID));


            UserIdentifier userIdentifier = new UserIdentifier(userObjectID, UserIdentifierType.UniqueId);

            authenticationResult = await authContext.AcquireTokenSilentAsync(tslResourceID, clientcred, userIdentifier);
        }
        catch(AdalException ex)
        {
            throw ex;
        }
        return authenticationResult.AccessToken;
    }
4

1 に答える 1