EDIT 10/24 これはすべてユーザーエラーの可能性が高いと思います-この質問に深く入り込む前に、以下の私の回答を参照してください
TL;DR: 私の OAuth 2.0 コード フローでは...
TokenCredentials
AutoRest クライアントで動作しないのはなぜですか? リクエストにベアラー トークンが適用されていない / 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;
}