2016-05-13 15 views
11

Sto tentando di accedere a un'API REST online Dynamics CRM con Azure AD oAuth 2 Authentication. Per fare ciò ho seguito questi passaggi:

- Ho registrato un'applicazione Web e/o web api in Azure
- Configurate le autorizzazioni per Dynamics CRM per disporre delle autorizzazioni delegate "Accesso a CRM Online come utente dell'organizzazione"
- E ha creato una chiave con una scadenza di 1 anno e ha mantenuto l'ID cliente generato.

Dopo l'applicazione web è stato configurato su Azure Ho creato un'applicazione console in .NET/C# che utilizza ADAL per fare una semplice richiesta, in questo caso per recuperare un elenco di account:

401- Autenticazione non autorizzata mediante l'API REST Dynamics CRM con Azure AD

class Program 
{ 
    private static string ApiBaseUrl = "https://xxxxx.api.crm4.dynamics.com/"; 
    private static string ApiUrl = "https://xxxxx.api.crm4.dynamics.com/api/data/v8.1/"; 
    private static string ClientId = "2a5dcdaf-2036-4391-a3e5-9d0852ffe3f2"; 
    private static string AppKey = "symCaAYpYqhiMK2Gh+E1LUlfxbMy5X1sJ0/ugzM+ur0="; 

    static void Main(string[] args) 
    { 
     AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(new Uri(ApiUrl)).Result; 

     var clientCredential = new ClientCredential(ClientId, AppKey); 

     var authenticationContext = new AuthenticationContext(ap.Authority); 
     var authenticationResult = authenticationContext.AcquireToken(ApiBaseUrl, clientCredential); 

     var httpClient = new HttpClient(); 
     httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken); 

     var result = httpClient.GetAsync(Path.Combine(ApiUrl, "accounts")).Result;   
    } 
} 

Recupero un token di accesso con successo ma quando provo a fare un httprequest a CRM ottengo sempre un 401 - Codice di stato non autorizzato. Cosa mi manca?

+0

credo che le sue autorizzazioni non corrette sul token. Quello che stai facendo è usare le credenziali dell'applicazione per ottenere contenuti. Le autorizzazioni che hai selezionato quando hai aggiunto CRM erano PErmissions delegate. Entrambe sono cose diverse. Cosa succede se si utilizzano i crediti utente di un utente nella stessa directory per l'autenticazione e l'accesso? –

+0

Ho già creato un'applicazione client nativa, con la quale sono stato integrato con successo con CRM, ma ho dovuto fornire le credenziali dell'utente per ottenere un token da Azure. Il mio obiettivo è evitare di utilizzare le credenziali dell'utente. A tale scopo sto cercando di ottenere un token attraverso lo scambio di chiavi (il metodo che ho spiegato nel post) o attraverso il certificato. – AndreCavaca

+0

Hai controllato? https://msdn.microsoft.com/en-us/library/gg327838.aspx –

risposta

3

1 anno e 2 mesi più tardi, questo stesso codice funziona perfettamente. Come molti hanno affermato, Dynamics 365 ha iniziato a supportare l'autenticazione Server-to-Server (S2S) nel frattempo. L'unico passo che dovevo fare non era quello di creare un utente dell'applicazione. Per ulteriori informazioni su come effettuare questo controllo il lavoro di autenticazione questo sito: https://msdn.microsoft.com/en-us/library/mt790170.aspx

+0

Puoi per favore condividere qualche dettaglio in più su come hai fatto a farlo funzionare? Sono nella stessa barca e sto provando ad usare il tipo di concessione client_credentials per accedere a d365 web apis? –

0

tuo ClientId, AppKey da Azure, così ap.Authority dovrebbe essere https://login.microsoftonline.com/tenantid in var authenticationContext = new AuthenticationContext(ap.Authority);

+0

Ho provato a utilizzare l'URL che hai proposto ma sto ancora ricevendo Non autorizzato. Il messaggio richiesto generato era questo, dove il token è stato sostituito da TOKEN: {Metodo: GET, RequestUri: 'https://xxxxx.api.crm4.dynamics.com/api/data/v8.1/accounts' , Versione: 1.1, Content: , intestazioni: { Autorizzazione: al portatore GETTONE }} – AndreCavaca

+0

hai provato a scaricare manifesto e aprire il file JSON e individuare la riga: "oauth2AllowImplicitFlow": false, e cambiare falso true e caricare il file. –

+0

Sì, ho provato anche questo .. = ( – AndreCavaca

0

Non credo che sarete in grado di aggirare fornire le credenziali utente ad almeno una sorta di "conto di integrazione". È possibile evitare un pop-up più tradizionale/reindirizzare il flusso di OAuth con il seguente:

using Microsoft.IdentityModel.Clients.ActiveDirectory; 
using System; 
using System.IO; 
using System.Net; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     private static string API_BASE_URL = "https://<CRM DOMAIN>/"; 
     private static string API_URL = "https://<CRM DOMAIN>/api/data/v8.1/"; 
     private static string CLIENT_ID = "<CLIENT ID>"; 

     static void Main(string[] args) 
     { 
      var userCredential = new UserCredential("<USERNAME>", "<PASSWORD>"); 
      var authContext = new AuthenticationContext("https://login.windows.net/common", false); 
      var result = authContext.AcquireToken(API_BASE_URL, CLIENT_ID, userCredential); 

      var httpClient = HttpWebRequest.CreateHttp(Path.Combine(API_URL, "accounts")); 
      httpClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer:" + result.AccessToken); 
      using (var sr = new StreamReader(httpClient.GetResponse().GetResponseStream())) 
      { 
       Console.WriteLine(sr.ReadToEnd()); 
      } 

      Console.ReadLine(); 
     } 
    } 
} 

Nota: sto usando una vecchia versione di ADAL (2.19.208020213) come appare il parametro password è stata presa dal costruttore UserCredential .

MODIFICA: CRM ora supporta Server to Server Authentication che consente di creare un utente dell'applicazione.

-1

Il servizio Web CRM 365 non sembra consentire l'accesso a un token per app.

Evidenza n. 1: non sono disponibili "Autorizzazioni applicazione" per l'API Dynamics CRM Online in Azure.

(see screenshot)

Evidence # 2: Per le istruzioni di MSDN per il collegamento a Microsoft Dynamics 365 servizi Web utilizzando OAuth - "L'autorizzazione viene approvata quando una valida OAuth 2.0 accesso (utente) di token, rilasciato da Microsoft Azure Active Directory, viene fornito nelle intestazioni delle richieste di messaggi. "

Ciò significa che sarà necessario fornire le credenziali per un account utente con accesso appropriato a CRM, solo per le app non verrà eseguito. Vedi this CRM Online community thread per maggiori informazioni su come farlo.

+0

Qualche spiegazione per il voto negativo?Con ogni mezzo, dimostrami che ho torto. – Tracy

3

Ti consiglio di dare un'occhiata all'autenticazione Server-to-Server (S2S), che è stata aggiunta a Dynamics 365 nell'ultima versione.

Utilizzando S2S non è necessaria una licenza Dynamics 365 a pagamento. Anziché le credenziali dell'utente, l'applicazione viene autenticata in base a un'entità servizio identificata da un valore ID oggetto di Azure AD archiviato nel record utente dell'applicazione Dynamics 365.

Maggiori informazioni possono essere trovate qui: https://msdn.microsoft.com/en-us/library/mt790168.aspx https://msdn.microsoft.com/en-us/library/mt790170.aspx

0

potrebbe essere necessario un set-up applicazione utente all'interno di CRM da abbinare con la vostra applicazione Azure: https://msdn.microsoft.com/en-us/library/mt790170.aspx

Mentre è possibile ottenere il portatore Configurazione del token in C#, la richiesta web alla risorsa CRM potrebbe non riuscire a causa delle autorizzazioni di livello CRM.

+0

Ho configurato un utente dell'applicazione con lo stesso ID app e il ruolo di sicurezza appropriato. Posso creare un token al portatore usando la concessione di credenziali client oauth ma quando cerco di usarlo ottengo un 401 non autorizzato. Non sono assolutamente sicuro di cosa sto sbagliando. –

2

Grazie a tutti per le vostre risposte. Sono finalmente riuscito ad accedere Dynamics CRM OData API utilizzando ADAL 3.

Dal momento che molte persone sono ancora avendo problemi facendo questo, vedere i seguenti passaggi:

registrazione App

  1. Accedere portal.azure.com usare i tuoi Utente amministratore di Office 365 del tuo abbonamento Dynamics CRM.

  2. Vai Azure Direttore Attivo \ App registrazioni e aggiungere nuove registrazioni di applicazione

  3. Inserire "Nome" e "Sign-on URL", l'URL potrebbe essere qualsiasi cosa (https://localhost per esempio)

  4. Seleziona l'app registrata appena creata, vai su Impostazioni \ Chiavi

  5. Inserisci una descrizione chiave, fai clic su Salva e copia il valore (e mantienilo poiché ne avrai bisogno in seguito). Copia anche l'ID dell'applicazione dell'app registrata.

  6. Andare a "Autorizzazioni necessarie", fare clic su Aggiungi, selezionare "Dynamics CRM Online", quindi selezionare "Accesso a CRM Online come utenti dell'organizzazione".

Questi passaggi consentono un'applicazione client per accedere a Dynamics CRM utilizzando l'ID applicazione e il segreto cliente creato nel passaggio 5. l'applicazione client è ora in grado di essere autenticato contro l'AD Azure con il permesso di accedi a CRM online. Tuttavia, CRM Online non conosce questa "applicazione client" o "utente". API CRM risponderà a 401 se si tenta di accedervi.

utente dell'applicazione Add CRM

Per far CRM sa della "applicazione client" o "utente", è necessario aggiungere un utente dell'applicazione.

  1. Vai a ruoli CRM \ Security, creare un nuovo ruolo di sicurezza o semplicemente copiare il ruolo "amministratore di sistema"

  2. Vai a CRM \ Impostazioni \ Security \ Utenti, creare un nuovo utente, modificare il modulo per "Utente dell'applicazione"

  3. Immettere i campi richiesti con l'ID applicazione presente nel passaggio precedente. Una volta salvato, CRM popolerà automaticamente l'ID oggetto di Azure AD e l'URI.

  4. Aggiungere l'utente al ruolo di sicurezza creato dal passaggio precedente.

Ora si dovrebbe essere in grado di accedere all'API CRM utilizzando HttpClient e ADAL utilizzando il codice di esempio:

var ap = await AuthenticationParameters.CreateFromResourceUrlAsync(
       new Uri("https://*****.api.crm6.dynamics.com/api/data/v9.0/")); 

String authorityUrl = ap.Authority; 
String resourceUrl = ap.Resource; 

var authContext = new AuthenticationContext(authorityUrl); 
var clientCred = new ClientCredential("Application ID", "Client Secret"); 
var test = await authContext.AcquireTokenAsync(resourceUrl, clientCred); 

Console.WriteLine(test.AccessToken); 

using (var client = new HttpClient()) 
{ 
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", test.AccessToken); 

    var response = await client.GetAsync("https://*****.api.crm6.dynamics.com/api/data/v9.0/contacts"); 
    var contacts = await response.Content.ReadAsStringAsync(); 

    Console.WriteLine(contacts); 
} 
Problemi correlati