Cómo hacer una petición directa a la WEB API de CRM para la versión Online mediante Azure AD.
Normalmente cuando queremos hacer una consulta a nuestra base de datos en CRM Dynamics utilizamos la SDK que Microsoft nos proporciona y escribimos un código donde instanciaremos el objeto OrganizationService desde el cual podremos ejecutar un RetrieveMultiple para obtener la información que deseemos de nuestro CRM.
Cuando disponemos de un CRM On Premise podemos también recurrir a la invocación de webservices con autenticación delegada o NTLM, cosa que no podemos hacer en el CRM Online.
Pero ¿qué ocurre si la aplicación que estamos desarrollando no está ideada en C#? En principio no podremos usar la SDK que nos proporciona Microsoft para integrarnos con el CRM. Una solución podría ser utilizar Xamarin para compilar nuestro código en otro lenguaje que necesitemos pero Xamarin no cubre todo el abanico de lenguajes. ¿Cómo podríamos integrarnos con un CRM Online si nuestra aplicación está hecha en PHP, NodeJS, Javascript, etc? ¿Podríamos conectar un CRM Online con otro CRM Online mediante Javascript y sin utilizar un Middleware?, ¿Un sistema tercero podría conectarse con nuestro CRM para enviar información sin necesidad de un Middleware? ¿Un JIRA podría integrarse con nuestro CRM directamente? La respuesta es que sí. Podemos realizar una petición a la API Rest de CRM directamente desde cualquier entorno utilizando el protocolo OAuth2 del Azure Active Directory.
Existe un modo genérico de integrarse con un CRM Online que podemos explotar desde cualquier lenguaje de programación que nos proporcione herramientas para ejecutar peticiones web.
El proceso es el siguiente: primero lanzamos una petición a Azure con nuestros credenciales y la URL del CRM sobre el que queremos ejecutar la query y será el propio Azure el que nos los validará. Si son correctos, Azure nos responderá a nuestra petición con un token. Este token es un «codigo de acceso temporal» a nuestro CRM. Podremos utilizar este código para hacer queries al CRM durante un tiempo limitado (normalmente 3600 segundos) y después caducará. Podremos entonces volver a pedir otro token y repetir el proceso.
Tenemos pues 2 peticiones web: obtener el token y realizar la query en CRM.
Vamos a ver cómo configurarlo paso a paso. Lo primero de todo que tenemos que tener en cuenta es que nuestro Dynamics 365 Online tendrá asociado siempre una cuenta de Azure.
Accedemos a nuestro CRM Online:
Una vez logados en nuestro CRM accedemos a Azure mediante el portal de acceso: https://portal.azure.com. El usuario con el que nos hará automáticamente el login será el mismo que nuestro CRM Online.
Accedemos a la sección Registro de aplicaciones mediante la barra de búsqueda superior.
Accedemos a Puntos de conexión en la parte superior.
Bajamos un poco y copiamos la URL del Punto de conexión de token de OAuth 2.0. La URL será del estilo: https://login.microsoftonline.com/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token
Bien, esta será la URL a la que tendremos que solicitar el token. Nos la guardamos para más adelante.
Volvemos a Registro de aplicaciones y creamos una nueva aplicación.
De nombre pondremos «Acceso API CRM», tipo de aplicación «Aplicación web o API» y URL de inicio de sesión podremos la URL de nuestro Dynamics:
Una vez creada la buscamos entre la lista y la abrimos. Vamos al apartado Propiedades y copiamos el código Id de aplicación. Este ID lo tendremos que incluir también en petición de token. Lo guardamos junto con la URL.
Vamos al apartado Claves:
Creamos una nueva Clave con descripción «Token» y que expire en 1 año (eres libre de seleccionar lo que más te convenga en este punto). Pulsamos «Guardar» y nos aparecerá el valor (denominado secreto). Debemos copiarlo y guardarlo en este instante pues no tendremos otra posibilidad de volver a conseguirlo:
Vamos al apartado Permisos necesarios y pulsamos en Agregar.
Como API seleccionamos Dynamics CRM Online.
Como permisos seleccionamos Access CRM Online as organization users.
Una vez agregado tenemos que pulsar «Conceder permisos» en la parte superior. Importante: si estás en un Azure de una compañía esta acción la tendrá que realizar un administrador.
Con esto ya tenemos configurado lo necesario en Azure.
Los datos que tendremos por el momento son los siguientes:
Dato | Valor | Descripción |
URL OAuth2.0 | https://login.microsoftonline.com/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token | La URL de petición de token |
URL CRM | https://micrm.crm4.dynamics.com/ | La URL de nuestro CRM |
Usuario CRM | ddiaz@micrm.onmicrosoft.com | Usuario de nuestro CRM |
Password CRM | MiPassw0rd! | El password de nuestro usuario |
Id Aplicación | b68b3b21-9f40-4923-85e1-7f8e3bc5b746 | Id de la aplicación creada en Azure |
Secreto | I/sRo1MyR6wRFUS9RgYnCJmCMWiIbq2IPx9evCm45Qc= | Disponible solo por 1 año |
Con esta información ya podemos ejecutar una query sobre nuestro CRM.
Peticiones web
Obtención de token
Los datos que tenemos que incluir en la petición de token son los siguientes
Nombre | Key | Value |
ID Cliente | client_id | b68b3b21-9f40-4923-85e1-7f8e3bc5b746 |
URL CRM* | resource | https://micrm.crm4.dynamics.com/ |
Usuario* | username | ddiaz@micrm.onmicrosoft.com |
Contraseña* | password | MiPassw0rd! |
Tipo acceso | grant_type | password |
Secreto | client_secret | I/sRo1MyR6wRFUS9RgYnCJmCMWiIbq2IPx9evCm45Qc= |
(*) Los valores tendrán que ser incluidos con encodeURIComponent, por ejemplo el usuario ddiaz@micrm.onmicrosoft.com quedaría como ddiaz%40micrm.onmicrosoft.com
La petición que tendremos que lanzar será
1 2 3 4 |
URL: https://login.windows.net/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token Method: post Headers: { "Content-Type": "application/x-www-form-urlencoded"} Datos: {la tabla de mas arriba concatenada del tipo "key1=value1&key2=value2&etc"}. |
Un ejemplo de petición con datos reales
1 2 3 4 |
URL: https://login.windows.net/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token Method: post Headers: { "Content-Type": "application/x-www-form-urlencoded"} Datos: { "client_id=b68b3b21-9f40-4923-85e1-7f8e3bc5b746&resource=https://micrm.crm4.dynamics.com/&username=ddiaz%40micrm.onmicrosoft.com&password=MiPassw0rd!&grant_type=password&client_secret=I/sRo1MyR6wRFUS9RgYnCJmCMWiIbq2IPx9evCm45Qc="}. |
La respuesta a la petición será como la siguiente:
1 2 3 4 5 6 7 8 9 10 11 |
{ access_token: "eyJ0eXA... ", expires_in: "3600", expires_on: "1497972545", ext_expires_in: "0", not_before: "1497968645", refresh_token: "apjks2...", resource: "https://micrm.crm4.dynamics.com/", scope: "user_impersonation", token_type: "Bearer" } |
Y el parámetro en cuestión que nos interesa es el access_token. Con esto ya tenemos el token.
Ejecución de query
Una vez que tenemos el token podemos acceder a la WEB API de CRM invocando cualquiera de sus métodos, siempre teniendo en cuenta el nivel de seguridad del usuario para el que hemos obtenido el token. Esto significa que si el usuario ddiaz@micrm.onmicrosoft.com no tiene permisos en CRM para editar contactos, no podrá ejecutar una petición de actualización de un contacto.
Otro punto importante es que mediante este método solo podremos acceder a la WEB API de tipo Rest de CRM y no podremos invocar peticiones directas al OrganizationService con SOAP.
La petición que hagamos tendrá que incluir en el header la propiedad «Authorization» con el valor «Bearer:» + token. Esto será suficiente para obtener acceso a la base de datos de CRM.
El ejemplo que vamos a mostrar es una petición a la API Rest para crear un contacto en CRM.
La petición sería:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
URL: https://micrm.crm4.dynamics.com/api/data/v8.2/contacts Method: post Headers: { "Authorization": "Bearer:" + token, "Content-Type":"application/json; charset=utf-8", "Accept": "application/json", "Prefer": "return=representation" } Datos: { "fullname": "Daniel Díaz", "emailaddress1": "dani@micorreo.com", "telephone1":"91333444" } |
La URL a donde enviaremos la petición es de la API Rest de CRM. En particular nos referimos a la entidad «Contacto». Como vemos, en el header incluimos el token con la palabra «Bearer:» antes. El método POST indica que queremos crear un registro de la entidad. Y en el objeto Data incluimos los logicalName de los campos de la entidad y sus correspondientes valores.
Para sacar partido a la WEB API de CRM existe mucha documentación oficial al respecto para ejecutar cualquier acción sobre nuestra base de datos.
Resultados
He implementado un pequeño código de ejemplo en Javascript para hacer la prueba. En particular he utilizado la librería Angular para realizar las peticiones http, pero podría implementarse sin Angular o con cualquier otro framework.
Los archivos que he utilizado son los siguientes:
El framework de Angular lo podéis descargar del sitio oficial. Los archivos indexOauth.html y js_api_rest_oauth.js los detallo a continuación:
indexOauth.html:
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Prueba OAuth CRM Dynamics</title> <script src="new_angular.js"></script> <script src="js_api_rest_oauth.js"></script> </head> <body> <script>RequestData();</script> </body> </html> |
js_api_rest_oauth.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
var injector = angular.injector(["ng"]); var $http = injector.get("$http"); var $q = injector.get("$q"); var urlToken = "https://login.windows.net/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token"; //Oauth para azure de mdcloud var userCRM = "ddiaz@micrm.onmicrosoft.com"; //usuario de CRM var passwordCRM = "MiPassw0rd!"; //password de CRM var urlCRM = "https://micrm.crm4.dynamics.com/"; //URL CRM var clientSecret = "I/sRo1MyR6wRFUS9RgYnCJmCMWiIbq2IPx9evCm45Qc="; //private key for application var applicationId = "b68b3b21-9f40-4923-85e1-7f8e3bc5b746"; //azure application function RequestData() { var reqstring = 'client_id=' + applicationId; reqstring+='&resource='+encodeURIComponent(urlCRM); reqstring+='&username='+encodeURIComponent(userCRM); reqstring+='&password='+encodeURIComponent(passwordCRM); reqstring += '&grant_type=password'; reqstring += '&client_secret=' + clientSecret; console.log(urlToken); var promise = GetPromise(urlToken, reqstring); promise.then(function (response) { var data = response.data; console.log(data); var token = data.access_token; var createContactRequest = $http({ method: 'POST', url: urlCRM + 'api/data/v8.2/contacts', headers: { 'Authorization': 'Bearer:' + token, "Content-Type":"application/json; charset=utf-8", "Accept": "application/json", "Prefer": "return=representation" }, data: { "firstname": "Daniel Díaz", "emailaddress1": "dani@micorreo.com", "telephone1":"91333444" }, }); return createContactRequest; }).then(function (response) { console.log(response); }); } function GetPromise(url, data) { var config = GetConfig(); var promise = $http.post(url, data, config); return promise; } function GetConfig() { var config = { headers: { 'Content-Type': 'application/x-www-form-urlencoded', } } return config; } |
El resultado de la ejecución del código anterior genera la siguiente respuesta:
Si lo ejecutáis desde vuestro PC en local es posible que obtengáis el error de No ‘Access-Control-Allow-Origin’. Para solucionarlo existen extensiones de Google Chrome que lo resuelven.
Como veis hemos creado un contacto en CRM a través de un token obtenido mediante OAuth del Azure Active Directory ejecutando una petición a la WEB API.
Espero que os sirva!