Usar autenticación de OAuth con Microsoft Dataverse
OAuth 2.0 es el protocolo estándar del sector para autorizaciones. Después de que los usuarios de aplicaciones proporcionan las credenciales para autenticarse, OAuth determina si están autorizadas para acceder a los recursos.
Las aplicaciones cliente deben admitir el uso de OAuth para el acceso a los datos mediante la API web. OAuth habilita la autenticación en dos fases (2FA) o autenticación basada en certificados para escenarios de aplicación entre servidores.
OAuth requiere un proveedor de identidad para la autenticación. Para Dataverse, el proveedor de identidades es Microsoft Entra ID. Para autenticarse usando una cuenta de trabajo o centro educativo de Microsoft, use Microsoft Authentication Libraries (MSAL).
Nota
Este tema introducirá los conceptos comunes relacionados con la conexión con Dataverse mediante OAuth con las bibliotecas de autenticación. Este contenido se centrará en la forma en que un programador puede conectarse a Dataverse pero no en el funcionamiento interno de OAuth ni en las bibliotecas. Si desea obtener más información sobre autencación, consulte la documentación de Microsoft Entra ID. ¿Qué es la autenticación? es un buen punto de inicio.
Los ejemplos que proporcionamos se preconfiguran con los valores apropiados de registro para que pueda ejecutarlos sin generar su propio registro de la aplicación. Al publicar sus propias aplicaciones, debe usar sus propios valores de registro.
Registro de aplicaciones
Al conectarse con OAuth, primero debe registrar una aplicación en su inquilino de Microsoft Entra ID. Cómo debe registrar la aplicación depende del tipo de aplicación que desee crear.
En todos los casos, comience con los pasos básicos para registrar una aplicación descrita en el artículo: Inicio rápido: Registrar una aplicación con la plataforma de identidad de Microsoft. Para consultar instrucciones específicas de Dataverse, consulte Tutorial: Registrar una aplicación con Microsoft Entra ID.
Las opciones que deberá tomar en este paso dependen principalmente de la opción de tipo de aplicación (véase a continuación).
Tipos de registro de la aplicación
Cuando registra una aplicación con Microsoft Entra ID, una de las decisiones que debe tomar es el tipo de aplicación. Hay dos tipos de aplicación que puede registrar:
Tipo de aplicación | Descripción |
---|---|
Aplicación web/API | Cliente web Tipo de aplicación cliente que ejecuta todos los códigos en un servidor web. Cliente basado en usuario-agente Tipo de aplicación cliente que descarga código desde un servidor web y se ejecuta en un agente de usuario (por ejemplo, explorador web), como una aplicación de una sola página (SPA). |
Modo nativo de | Tipo de aplicación cliente que está instalada nativamente en un dispositivo. |
Cuando selecciona Aplicación web/API debe proporcionar una Dirección URL de inicio de sesión que es la dirección URL a la que Microsoft Entra ID enviará la respuesta de autenticación, incluido un símbolo (token) si la autenticación se realiza correctamente. Mientras desarrolla una aplicación, esta URL se establece normalmente en https://localhost/appname:[port]
por lo que puede desarrollar y depuración su aplicación localmente. Al publicar la aplicación, necesita cambiar este valor en la dirección URL publicada de la aplicación.
Cuando selecciona Nativo, debe proporcionar el identificador uniforme de recursos URI de una redirección. Este URL es un identificador único al que Microsoft Entra ID redirigirá el agente de usuario en una solicitud de OAuth 2.0. Esta URL suele ser un valor con un formato similar al siguiente: app://<guid>
.
Dar acceso a Dataverse
Si su aplicación es un cliente que permite al usuario autenticado realizar operaciones, debe configurar la aplicación para que tenga Access Dynamics 365 como permiso delegado de los usuarios de la organización.
Para ver los pasos específicos para establecer permisos, consulte Registrar una aplicación con Microsoft Entra ID.
Si su aplicación va a usar la autenticación entre servidores (S2S), este paso no es obligatorio. Esa configuración requiere un usuario del sistema específico y las operaciones se realizarán por la cuenta de ese usuario en lugar de cualquier usuario que tenga que ser autenticado.
Uso de Secretos y certificados del cliente
En los escenarios entre servidores, no aparecerá una cuenta de usuario interactiva para la autenticación. En estos casos, debe proporcionar algunos medios de confirmar que la aplicación es de confianza. Esto se realiza con secretos o certificados del cliente.
Para aplicaciones que se registran con el tipo de aplicación Aplicación web/API, puede configurar secretos. Estos se establecen utilizando el área Teclas de Acceso de API en Configuración para el registro de la aplicación.
Para ambos tipos de aplicación, puede cargar un certificado.
Más información: Conectar como aplicación
Uso de las bibliotecas de autenticación para conectar
Utilice una de las bibliotecas cliente de autenticación de Microsoft Entra ID compatibles con Microsoft para conectarse a Dataverse como la Biblioteca de autenticación de Microsoft (MSAL). Esta biblioteca está disponible para varias plataformas, como se muestra en los enlaces proporcionados.
Nota
La Biblioteca de autenticación de Azure Active Directory (ADAL) ya no recibe actualizaciones de forma activa y está programada para recibir soporte solo hasta junio de 2022. MSAL es la biblioteca de autenticación recomendada para usar en proyectos.
Para obtener una muestra de código que demuestra el uso de las bibliotecas MSAL para la autenticación con Dataverse, vea Ejemplo de inicio rápido.
Bibliotecas de cliente .NET
Dataverse admite la autenticación de aplicaciones con la API web punto de conexión mediante el protocolo OAuth 2.0. Para sus aplicaciones .NET personalizadas, use MSAL para la autenticación de aplicaciones con el punto de conexión API web.
SDK de Dataverse para .NET incluye clases de clientes CrmServiceClient yServiceClient para manejar la autenticación. La clase CrmServiceClient
actualmente usa ADAL para la autenticación, mientras que ServiceClient
utiliza MSAL. Escribir el código de su aplicación para usar estos clientes elimina la necesidad de administrar la autenticación directamente. Ambos clientes trabajan con los puntos de conexión SDK y Web API.
Use el AccessToken con sus solicitudes
El objetivo de usar las bibliotecas de autenticación es obtener un token de acceso que pueda incluir con las solicitudes. Obtener el token esto requiere solo unas líneas de código y solo unas cuantas líneas más para configurar un HttpClient para ejecutar una solicitud.
Importante
Como se muestra en el código de ejemplo de este artículo, use un ámbito "<environment-url>/user_impersonation" para un cliente público. Para un cliente confidencial, use un ámbito de "<environment-url>/.default".
Ejemplo sencillo:
A continuación se presenta la cantidad mínima de código necesaria para ejecutar una sola solicitud de web API, pero no es el método recomendado. Tenga en cuenta que este código utiliza la biblioteca MSAL y se toma del ejemplo QuickStart.
string resource = "https://contoso.api.crm.dynamics.com";
var clientId = "51f81489-12ee-4a9e-aaae-a2591f45987d";
var redirectUri = "http://localhost"; // Loopback for the interactive login.
// MSAL authentication
var authBuilder = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
.WithRedirectUri(redirectUri)
.Build();
var scope = resource + "/user_impersonation";
string[] scopes = { scope };
AuthenticationResult token =
authBuilder.AcquireTokenInteractive(scopes).ExecuteAsync().Result;
// Set up the HTTP client
var client = new HttpClient
{
BaseAddress = new Uri(resource + "/api/data/v9.2/"),
Timeout = new TimeSpan(0, 2, 0) // Standard two minute timeout.
};
HttpRequestHeaders headers = client.DefaultRequestHeaders;
headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
headers.Add("OData-MaxVersion", "4.0");
headers.Add("OData-Version", "4.0");
headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
// Web API call
var response = client.GetAsync("WhoAmI").Result;
Este método sencillo no es un buen patrón que deba seguirse, porque el token
expirará aproximadamente en una hora. Las bibliotecas de MSAL almacenarán en memoria caché el símbolo en su nombre y lo actualizarán cada vez que se llame al método AcquireTokenInteractive
. Sin embargo, en este ejemplo simple, el token solo se adquiere una vez.
Ejemplo que demuestra la delegación de un controlador de mensaje
El método recomendado consiste en implementar una clase derivada de DelegatingHandler, que se pasará al constructor del HttpClient. Este controlador le permitirá reemplazar el método HttpClient.SendAsync para que los métodos de llamada de AcquireToken*
actualicen el token de acceso con cada solicitud enviada por el cliente Http.
A continuación se presenta un ejemplo de una clase personalizada derivada de DelegatingHandler. Este código utiliza la biblioteca MSAL y se toma del ejemplo QuickStart mejorado mencionado anteriormente.
class OAuthMessageHandler : DelegatingHandler
{
private AuthenticationHeaderValue authHeader;
public OAuthMessageHandler(string serviceUrl, string clientId, string redirectUrl, string username, string password,
HttpMessageHandler innerHandler)
: base(innerHandler)
{
string apiVersion = "9.2";
string webApiUrl = $"{serviceUrl}/api/data/v{apiVersion}/";
var authBuilder = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
.WithRedirectUri(redirectUrl)
.Build();
var scope = serviceUrl + "/user_impersonation";
string[] scopes = { scope };
// First try to get an authentication token from the cache using a hint.
AuthenticationResult authBuilderResult=null;
try
{
authBuilderResult = authBuilder.AcquireTokenSilent(scopes, username)
.ExecuteAsync().Result;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(
$"Error acquiring auth token from cache:{System.Environment.NewLine}{ex}");
// Token cache request failed, so request a new token.
try
{
if (username != string.Empty && password != string.Empty)
{
// Request a token based on username/password credentials.
authBuilderResult = authBuilder.AcquireTokenByUsernamePassword(scopes, username, password)
.ExecuteAsync().Result;
}
else
{
// Prompt the user for credentials and get the token.
authBuilderResult = authBuilder.AcquireTokenInteractive(scopes)
.ExecuteAsync().Result;
}
}
catch (Exception msalex)
{
System.Diagnostics.Debug.WriteLine(
$"Error acquiring auth token with user credentials:{System.Environment.NewLine}{msalex}");
throw;
}
}
//Note that an Microsoft Entra ID access token has finite lifetime, default expiration is 60 minutes.
authHeader = new AuthenticationHeaderValue("Bearer", authBuilderResult.AccessToken);
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Headers.Authorization = authHeader;
return base.SendAsync(request, cancellationToken);
}
}
Usando esta clase OAuthMessageHandler
, el método sencillo Main
se vería así.
class Program
{
static void Main(string[] args)
{
try
{
//Get configuration data from App.config connectionStrings
string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;
using (HttpClient client = SampleHelpers.GetHttpClient(connectionString, SampleHelpers.clientId,
SampleHelpers.redirectUrl))
{
// Use the WhoAmI function
var response = client.GetAsync("WhoAmI").Result;
if (response.IsSuccessStatusCode)
{
//Get the response content and parse it.
JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
Guid userId = (Guid)body["UserId"];
Console.WriteLine("Your UserId is {0}", userId);
}
else
{
Console.WriteLine("The request failed with a status of '{0}'",
response.ReasonPhrase);
}
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
catch (Exception ex)
{
SampleHelpers.DisplayException(ex);
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
}
Lea la siguiente información importante sobre el uso de una cadena de conexión o la autenticación de nombre de usuario/contraseña en el código de la aplicación.
Importante
Microsoft recomienda utilizar el flujo de autenticación más seguro disponible. El flujo de autenticación descrito en este artículo requiere un alto grado de confianza en la aplicación y conlleva riesgos que no están presentes en otros flujos. Solo debe usar este flujo cuando otros flujos más seguros, como las identidades administradas, no sean viables.
Los valores de la cadena de configuración se han movido a una cadena de conexión de archivo App.config, y el cliente Http está configurado en el método GetHttpClient
.
public static HttpClient GetHttpClient(string connectionString, string clientId, string redirectUrl, string version = "v9.2")
{
string url = GetParameterValueFromConnectionString(connectionString, "Url");
string username = GetParameterValueFromConnectionString(connectionString, "Username");
string password = GetParameterValueFromConnectionString(connectionString, "Password");
try
{
HttpMessageHandler messageHandler = new OAuthMessageHandler(url, clientId, redirectUrl, username, password,
new HttpClientHandler());
HttpClient httpClient = new HttpClient(messageHandler)
{
BaseAddress = new Uri(string.Format("{0}/api/data/{1}/", url, version)),
Timeout = new TimeSpan(0, 2, 0) //2 minutes
};
return httpClient;
}
catch (Exception)
{
throw;
}
}
Ver el ejemplo Inicio rápido mejorado para el código completo.
Aunque este ejemplo utiliza HttpClient.GetAsync en lugar del SendAsync reemplazado, solicitará todos los métodos de HttpClient que envían una solicitud.
Conectar como aplicación
Algunas aplicaciones que va a crear no están previstas para ser ejecutadas recíprocamente por un usuario. Por ejemplo, es posible que desee crear una aplicación cliente web que pueda realizar operaciones en datos de Dataverse, o una aplicación de consola que realice una tarea programada de algún tipo.
Aunque puede llegar a realizar estos escenarios usando las credenciales de un usuario normal, la cuenta de ese usuario necesitaría usar una licencia de pago. Este no es el enfoque recomendado.
En estos casos puede crear un usuario de aplicación especial que está vinculado a una aplicación registrada de Microsoft Entra ID y usar la clave secreta configurada para la aplicación o cargar un certificado X.509. Otro ventaja de este método es que no consume una licencia de pago.
Requisitos para conectarse como aplicación
Para conectarse como una aplicación necesitará:
- Una aplicación registrada
- Un usuario de Dataverse vinculado a la aplicación registrada
- Conectarse usando la clave secreta de la aplicación o una huella digital del certificado
Registrar su aplicación
Al registrar una aplicación repite muchos de los pasos descritos en Tutorial: Registrar una aplicación con Microsoft Entra ID, con las excepciones siguientes:
No es necesario conceder el permiso Acceso a Dynamics 365 como usuarios de la organización.
Esta aplicación estará enlazada a una cuenta de usuario específica.
Debe configurar un secreto para el registro de la aplicación O cargar un certificado de clave pública.
Puede crear o ver credenciales en el registro de su aplicación en Administrar>certificados y secretos.
Para agregar un certificado (clave pública):
- En la pestaña Certificados , seleccione Cargar certificado.
- Seleccione el archivo que le gustaría cargar. Debe ser uno de los siguientes tipos de archivo: .cer, .pem, .crt.
- Proporcione una descripción.
- Seleccione Agregar.
Para agregar un secreto de cliente (contraseña de aplicación):
- En la pestaña Secretos de cliente, agregue una descripción para su secreto de cliente.
- Seleccione un período de tiempo de vencimiento.
- Seleccione Agregar.
Importante
Después de guardar los cambios de configuración, se muestra un valor secreto. Asegúrese de copiar el valor del secreto para usarla en el código de aplicación cliente, ya que ese valor no es accesible una vez que sale de la página.
Más información: Agregar credenciales
Una cuenta de usuario de Dataverse vinculado a la aplicación registrada
Lo primero que debe hacer es crear un rol de seguridad personalizado que definirá qué acceso y privilegios esta cuenta tendrá dentro de la organización de Dataverse. Más información: Creación o configuración de un rol de seguridad personalizado
Después de crear el rol de seguridad personalizado, debe crear la cuenta de usuario que lo usará.
Cree manualmente un usuario de la aplicación de Dataverse
El procedimiento para crear un usuario de la aplicación se puede encontrar en el artículo Administrar Power Platform: Crear un usuario de aplicación.
Tras crear un usuario de aplicación, asocie el usuario de la aplicación al rol de seguridad personalizado que ha creado.
Conectar con el secreto de la aplicación
Si se conecta mediante un secreto de cliente y utiliza el Microsoft.Xrm.Tooling.Connector.CrmServiceClient Puede usar código como el siguiente:
string SecretID = "00000000-0000-0000-0000-000000000000";
string AppID = "00001111-aaaa-2222-bbbb-3333cccc4444";
string InstanceUri = "https://yourorg.crm.dynamics.com";
string ConnectionStr = $@"AuthType=ClientSecret;
SkipDiscovery=true;url={InstanceUri};
Secret={SecretID};
ClientId={AppID};
RequireNewInstance=true";
using (ServiceClient svc = new ServiceClient(ConnectionStr))
{
if (svc.IsReady)
{
//your code goes here
}
}
Conectar con una huella digital del certificado
Si se conecta mediante un certificado y utiliza el Microsoft.Xrm.Tooling.Connector.CrmServiceClient Puede usar código como el siguiente:
string CertThumbPrintId = "DC6C689022C905EA5F812B51F1574ED10F256FF6";
string AppID = "00001111-aaaa-2222-bbbb-3333cccc4444";
string InstanceUri = "https://yourorg.crm.dynamics.com";
string ConnectionStr = $@"AuthType=Certificate;
SkipDiscovery=true;url={InstanceUri};
thumbprint={CertThumbPrintId};
ClientId={AppID};
RequireNewInstance=true";
using (ServiceClient svc = new ServiceClient(ConnectionStr))
{
if (svc.IsReady)
{
//your code goes here
}
}
Consultar también
Autenticación con servicios web Microsoft Dataverse
Autenticación de las aplicaciones de .NET Framework
Descripción general de la biblioteca de autenticación de Microsoft (MSAL)