2

编辑 10/24 我认为这很可能是用户错误 - 在深入探讨这个问题之前,请参阅下面的答案以获得补救

TL;DR: 对于我的 OAuth 2.0 代码流...

为什么TokenCredentials我的 AutoRest 客户端无法使用?我没有将不记名令牌应用于请求/没有授权标头集

我知道我的管道已经工作了..

使用此 azure sample中的代码(不是 AutoRest 客户端),我可以成功获取我的access_token并且可以从受保护的 Web API 项目中获取 JSON..所以我已经排除了所有先决条件..我知道我的管道有效

我的 AutoRest 设置..

1.) 从 GitHub 下载这个 AutoRest repo 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 网站中

5.) 这些是我的 NuGet:

- 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并查看请求没有应用授权标头..所以我得到了预期的401 Unauthorized响应。

如果我修改MyAzureTracingHandler为接受我的实例,TokenCredentials那么我可以强制请求应用适当的不记名令牌。

这行得通,但是感觉很hack-ish:

我从这里更改了我的原始客户端实例化片段:

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

对此:

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

在我这样做的SendAsync方法中:MyAzureTracingHander

await svcClientCreds.ProcessHttpRequestAsync(request, cancellationToken);

难道我做错了什么?我认为在实例化我的客户端时我不应该传入ServiceClientCredentials两次。

附录 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

2

虽然我相信我运行了我的autorest命令,--add-credentials但我可能使用了较旧的语法......--AddCredentials true

我也没有autorest --reset按照文档建议的那样运行

其中之一是罪魁祸首,因为现在我的 1.1.0 autorest 安装正在正确生成所有内容。

于 2017-07-17T13:22:33.800 回答