2017-07-11 2 views
0

EDIT 10/24 Je pense que tout cela était une erreur d'utilisateur probable - voir ma réponse ci-dessous pour remédier avant d'obtenir trop profondément dans cette questionEn utilisant un client AutoRest C# pour accéder à une API Web avec un jeton porteur - TokenCredentials ne fonctionne pas

TL; DR: Pour mon OAuth 2.0 flux de code ...

Pourquoi mon TokenCredentials fonctionne pas avec mon client AutoRest? Je reçois aucun jeton porteur appliqué à la demande/sans en-tête d'autorisation définie

Je sais que mon pipeline fonctionne déjà ..

En utilisant le code de this azure sample, ce qui est un client AutoRest, je peut obtenir avec succès mon access_token et peut obtenir JSON de mon projet Web API protégé .. donc j'ai exclue tous les trucs .. condition sine qua non, je sais que mon pipelinière

configuration mon AutoRest ..

1.) Téléchargé de GitHub this AutoRest repo v1.1.0

2.) Téléchargé mon fanfaronnades JSON sur le disque, enregistré en tant que swagger.json

3.) cette commande-Ran en ligne pour générer des fichiers C#:

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

4.) classes générées Copié dans mon .NET 4.6.2 site web

5.) Ce sont mes 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" 

Voici ce qui ne fonctionne pas:

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); 

J'ai variations essayé de ce qui précède, en utilisant différentes années ctor de TokenCredentials, mais peu importe, je peux mettre mon point d'arrêt dans MyAzureTracingHandler et voir le demande n'a pas en-têtes d'autorisation appliquée .. donc j'obtenir la réponse 401 Unauthorized attendue.

Si je modifie MyAzureTracingHandler pour accepter mon instance de TokenCredentials, je peux forcer la requête à appliquer le jeton support approprié.

Cela fonctionne, mais se sent hack-ish:

J'ai changé mon original extrait de l'instanciation client de ceci:

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

à ceci:

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

Et à l'intérieur du SendAsync méthode de MyAzureTracingHander Je fais ceci:

await svcClientCreds.ProcessHttpRequestAsync(request, cancellationToken); 

Est-ce que je fais quelque chose de mal? Je ne pense pas que je devrais avoir à passer le ServiceClientCredentials dans deux fois en instanciant mon client.

Annexe A - Obtenir le jeton d'accès via 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; 
    } 

Répondre

0

Même si je crois que je courais mon commandement autorest avec --add-credentials il est possible que je l'ai utilisé la syntaxe plus ... --AddCredentials true

I également n'a pas exécuté autorest --reset comme les documents vous recommandent de le faire

L'un d'eux est le coupable, parce que maintenant mon 1.1.0 autore L'installation st génère tout correctement.