La Plataforma de identidad de Microsoft y el flujo de credenciales de cliente de OAuth 2.0

El flujo de concesión de credenciales de cliente de OAuth 2.0 permite que un servicio web (cliente confidencial) use sus propias credenciales para autenticarse al llamar a otro servicio web, en lugar de suplantar a un usuario. La concesión especificada en RFC 6749 y a veces denominada OAuth de dos días, se puede utilizar para acceder a recursos hospedados en la web mediante la identidad de una aplicación. Este tipo se usa principalmente para las interacciones entre servidores que se deben ejecutar en segundo plano, sin la interacción inmediata con un usuario y suele denominarse demonios o cuentas de servicio.

En el flujo de credenciales de cliente, un administrador concede los permisos directamente en la propia aplicación. Cuando la aplicación presenta un token a un recurso, este exige que la propia aplicación tenga autorización para realizar una acción, ya que no hay ningún usuario implicado en la autorización. En este artículo se describen los dos pasos necesarios para:

En este artículo se describe cómo programar directamente con el protocolo de la aplicación. Cuando sea posible, se recomienda usar las bibliotecas de autenticación de Microsoft (MSAL) admitidas, en lugar de adquirir tokens y API web protegidas por llamadas. También puede hacer referencia a las aplicaciones de ejemplo que usan MSAL. Como nota lateral, los tokens de actualización nunca se concederán con este flujo como client_id y client_secret (lo que sería necesario para obtener un token de actualización) se pueden usar para obtener un token de acceso en su lugar.

Para conseguir un mayor nivel de control, la plataforma de identidad de Microsoft también permite que el servicio que realiza la llamada se autentique con un certificado o una credencial federada en lugar de un secreto compartido. Dado que se usan las propias credenciales de la aplicación, estas credenciales deben mantenerse seguras. Nunca publique esas credenciales en el código fuente, nunca las inserte en páginas web ni las use en una aplicación nativa ampliamente distribuida.

Diagrama de protocolo

El flujo completo de credenciales de cliente tiene un aspecto similar al diagrama siguiente. Más adelante en este artículo se describe cada uno de los pasos.

Diagram showing the client credentials flow

Obtención de autorización directa

Una aplicación recibe habitualmente autorización directa para acceder a un recurso de una de dos maneras:

Estos dos métodos son los más comunes en Microsoft Entra ID y se recomiendan para los clientes y recursos que realizan el flujo de credenciales de cliente. Un recurso puede elegir autorizar a sus clientes de otras formas. Cada servidor de recurso puede elegir el mejor método para su aplicación.

Listas de control de acceso

Un proveedor de recursos podría exigir una comprobación de autorización basada en una lista de identificadores de aplicación (cliente) que conoce, y concede un nivel de acceso específico. Cuando el recurso recibe un token de la Plataforma de identidad de Microsoft, puede descodificar el token y extraer el identificador de la aplicación del cliente de las notificaciones appid y iss. Luego, compara la aplicación con una lista de control de acceso (ACL) que mantiene. El método y la granularidad de la ACL podrían variar considerablemente entre los recursos.

Un caso de uso común es utilizar una ACL para ejecutar pruebas para una aplicación web o para una API web. La API web podría conceder solo un subconjunto de permisos completos a un cliente específico. Para ejecutar pruebas de un extremo a otro en la API, puede crear un cliente de prueba que adquiera tokens desde la Plataforma de identidad de Microsoft y que, luego, los envíe a la API. Luego, la API comprueba la ACL del identificador de la aplicación del cliente de prueba para tener acceso completo a toda la funcionalidad de la API. Si usa este tipo de ACL, asegúrese de validar no solo el valor appid de la persona que llama, sino también que el valor de iss del token sea de confianza.

Este tipo de autorización es común para las cuentas de servicio y los demonios que necesitan tener acceso a datos que pertenecen a los usuarios consumidores con cuentas personales de Microsoft. En el caso de los datos que pertenecen a organizaciones, se recomienda obtener la autorización necesaria a través de los permisos de aplicación.

Control de tokens sin la notificación roles

Para habilitar este patrón de autorización basado en ACL, Microsoft Entra no requiere que las aplicaciones estén autorizadas para obtener tokens para otra aplicación. Por lo tanto, los tokens de solo aplicación se pueden emitir sin una notificación roles. Las aplicaciones que exponen las API deben implementar comprobaciones de permisos para aceptar tokens.

Si quiere impedir que las aplicaciones obtengan tokens de acceso de solo aplicación sin roles para su aplicación, asegúrese de que los requisitos de asignación estén habilitados para la aplicación. Esto impedirá que los usuarios y las aplicaciones sin roles asignados puedan obtener un token para esta aplicación.

Permisos de aplicación

En lugar de usar las ACL, puede usar las API para exponer un conjunto de permisos de aplicación. El administrador de una organización los concede a una aplicación y solo se pueden usar para obtener acceso a los datos que pertenecen a esa organización y sus empleados. Por ejemplo, Microsoft Graph expone varios permisos de aplicación para hacer lo siguiente:

  • Leer correo en todos los buzones de correo
  • Leer y escribir correo en todos los buzones de correo
  • Enviar correo como cualquier usuario
  • Leer datos de directorio

Para usar roles de aplicación (permisos de aplicación) con su propia API (en lugar de Microsoft Graph), primero debe exponer los roles de aplicación en el registro de la aplicación de API en el Centro de administración de Microsoft Entra. A continuación, para configurar los roles de aplicación necesarios, seleccione esos permisos en el registro de aplicaciones de la aplicación cliente. Si no ha expuesto ningún rol de aplicación en el registro de la aplicación de API, no podrá especificar permisos de aplicación para esa API en el registro de aplicaciones de la aplicación cliente en el Centro de administración de Microsoft Entra.

Al autenticarse como una aplicación, en lugar de como un usuario, no puede usar permisos delegados, ya que no hay ningún usuario en nombre del cual la aplicación pueda actuar. Debe usar permisos de aplicación, también conocidos como roles de aplicación, concedidos por un administrador o por el propietario de la API.

Para obtener más información acerca de los permisos de aplicación, consulte los Permisos y consentimiento.

Habitualmente, cuando compila una aplicación que usa permisos de aplicación, la aplicación requiere una página o vista en la que el administrador aprueba los permisos de la aplicación. Esta página puede formar parte del flujo de inicio de sesión de la aplicación, de la configuración de la aplicación o de un flujo de conexión específico. En muchos casos, tiene sentido que la aplicación muestre esta vista de conexión solo después de que un usuario haya iniciado sesión con una cuenta Microsoft profesional o educativa.

Si inicia la sesión del usuario en la aplicación, puede identificar la organización a la que este pertenece antes de pedirle que apruebe los permisos de la aplicación. Aunque no es estrictamente necesario, puede ayudarlo a crear una experiencia más intuitiva para los usuarios. Para iniciar la sesión del usuario, siga los tutoriales del protocolo de la Plataforma de identidad de Microsoft.

Solicitud de los permisos de un administrador de directorios

Cuando esté listo para solicitar permisos al administrador de la organización, puede redirigir al usuario al punto de conexión de consentimiento del administrador de la Plataforma de identidad de Microsoft.

// Line breaks are for legibility only.

GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&state=12345
&redirect_uri=http://localhost/myapp/permissions

Sugerencia profesional: Intente pegar la siguiente solicitud en un explorador.

https://login.microsoftonline.com/common/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions
Parámetro Condition Descripción
tenant Obligatorio El inquilino de directorio al que quiere solicitar permiso. Puede estar en formato de nombre descriptivo o GUID. Si no sabe a qué inquilino pertenece el usuario y desea permitirle iniciar sesión con cualquier inquilino, use common.
client_id Obligatorio El identificador de aplicación (cliente) que elcentro de administración de Microsoft Entra: experiencia de registro de aplicaciones asignó a la aplicación.
redirect_uri Obligatorio El URI de redireccionamiento adonde desea que se envíe la respuesta para que la controle la aplicación. Debe coincidir exactamente con uno de los URI de redireccionamiento que registró en el portal, con la excepción de que debe estar codificado como dirección URL y puede tener segmentos de trazado adicionales.
state Recomendado Un valor incluido en la solicitud que también se devolverá en la respuesta del token. Puede ser una cadena de cualquier contenido que desee. El estado se usa para codificar información sobre el estado del usuario en la aplicación antes de que se haya producido la solicitud de autenticación, por ejemplo, la página o vista en la que estaban.

En este momento, Microsoft Entra ID solo exige que un administrador de inquilino pueda iniciar sesión para completar la solicitud. Se pedirá al administrador que apruebe todos los permisos de aplicación directos que solicitó para la aplicación en el portal de registro de aplicaciones.

Respuesta correcta

Si el administrador aprueba los permisos para la aplicación, la respuesta correcta tendrá un aspecto similar al siguiente:

GET http://localhost/myapp/permissions?tenant=aaaabbbb-0000-cccc-1111-dddd2222eeee&state=state=12345&admin_consent=True
Parámetro Descripción
tenant El inquilino de directorio que concedió los permisos solicitados a la aplicación, en formato GUID.
state Un valor incluido en la solicitud que también se devuelve en la respuesta del token. Puede ser una cadena de cualquier contenido que desee. El estado se usa para codificar información sobre el estado del usuario en la aplicación antes de que se haya producido la solicitud de autenticación, por ejemplo, la página o vista en la que estaban.
admin_consent Se establece en True.
Respuesta de error

Si el administrador no aprueba los permisos de la aplicación, la respuesta de error tendrá el aspecto siguiente:

GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
Parámetro Descripción
error Una cadena de código de error que puede usar para clasificar los tipos de errores y que puede usar para reaccionar ante los errores.
error_description Un mensaje de error específico que puede ayudarle a identificar la causa raíz de un error.

Una vez que reciba una respuesta correcta desde el punto de conexión de aprovisionamiento de la aplicación, esta habrá obtenido los permisos de aplicación directos que solicitó. Ahora puede solicitar un token para el recurso que desee.

Obtención de un token

Una vez que obtenga la autorización necesaria para la aplicación, siga con el proceso de adquisición de tokens de acceso para las API. Para obtener un token mediante la concesión de credenciales de cliente, envíe una solicitud POST a la Plataforma de identidad de Microsoft /token. Existen distintos casos:

Primer caso: solicitud de token de acceso con un secreto compartido

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=A1bC2dE3f...&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
Parámetro Condition Descripción
tenant Obligatorio El inquilino del directorio en el que va a funcionar la aplicación, con el formato de GUID o de nombre de dominio.
client_id Obligatorio El identificador de la aplicación que está asignado a la aplicación. Puede encontrar esta información en el portal donde registró la aplicación.
scope Obligatorio El valor pasado del parámetro scope en esta solicitud debe ser el identificador de recurso (URI de identificador de aplicación) del recurso que desea, con el sufijo .default. Todos los ámbitos incluidos deben corresponder a un único recurso. Si se incluyen ámbitos para varios recursos, se producirá un error.
Para el ejemplo de Microsoft Graph, el valor es https://graph.microsoft.com/.default. Este valor indica a la Plataforma de identidad de Microsoft que, de todos los permisos directos de la aplicación que ha configurado para la aplicación, debe emitir un token para los que están asociados con el recurso que quiere usar. Para más información sobre el ámbito /.default, consulte la documentación de consent.
client_secret Obligatorio El secreto de cliente que generó para la aplicación en el portal de registro de aplicaciones. El secreto de cliente debe codificarse como dirección URL antes de enviarse. También se admite el patrón de autenticación Básico de proporcionar credenciales en el encabezado de autorización, conforme a RFC 6749.
grant_type Obligatorio Se debe establecer en client_credentials.

Segundo caso: solicitud de token de acceso con un certificado

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Parámetro Condition Descripción
tenant Obligatorio El inquilino del directorio en el que va a funcionar la aplicación, con el formato de GUID o de nombre de dominio.
client_id Obligatorio El identificador de aplicación (cliente) que se asigna a la aplicación.
scope Obligatorio El valor pasado del parámetro scope en esta solicitud debe ser el identificador de recurso (URI de identificador de aplicación) del recurso que desea, con el sufijo .default. Todos los ámbitos incluidos deben corresponder a un único recurso. Si se incluyen ámbitos para varios recursos, se producirá un error.
Para el ejemplo de Microsoft Graph, el valor es https://graph.microsoft.com/.default. Este valor indica a la Plataforma de identidad de Microsoft que, de todos los permisos directos de la aplicación que ha configurado para la aplicación, debe emitir un token para los que están asociados con el recurso que quiere usar. Para más información sobre el ámbito /.default, consulte la documentación de consent.
client_assertion_type Obligatorio El valor se debe establecer en urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
client_assertion Obligatorio Una aserción (JSON Web Token) que debe crear y firmar con el certificado que ha registrado como credenciales de la aplicación. Lea el artículo sobre las credenciales de certificado para información sobre cómo registrar el certificado y el formato de la aserción.
grant_type Obligatorio Se debe establecer en client_credentials.

Los parámetros de la solicitud basada en certificados solo difieren de una manera de la solicitud basada en secreto compartido: el parámetro client_secret se reemplaza por los parámetros client_assertion_type y client_assertion.

Tercer caso: solicitud de token de acceso con una credencial federada

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Parámetro Condition Descripción
client_assertion Obligatorio Aserción (un JWT, o JSON Web Token) que la aplicación recibe de otro proveedor de identidades fuera de la plataforma de identidad de Microsoft, como Kubernetes. Los detalles de este JWT deben estar registrados en la aplicación como una credencial de identidad federada. Lea sobre la federación de identidades de carga de trabajo para obtener información sobre cómo configurar y usar las aserciones generadas por otros proveedores de identidades.

Todo el contenido de la solicitud es igual al del flujo basado en certificados anterior, con una excepción fundamental: el origen de client_assertion. En este flujo, la aplicación no crea la propia aserción de JWT. En su lugar, la aplicación usa un JWT creado por otro proveedor de identidades. Esto se denomina federación de identidades de carga de trabajo, donde la identidad de las aplicaciones de otra plataforma de identidad se usa para adquirir tokens dentro de la plataforma de identidad de Microsoft. Esto es óptimo para escenarios entre nubes, como hospedar el proceso fuera de Azure, pero acceder a las API protegidas por la plataforma de identidad de Microsoft. Para obtener información sobre el formato necesario de los JWT creados por otros proveedores de identidades, consulte la información sobre el formato de aserción.

Respuesta correcta

Una respuesta correcta de cualquiera de los métodos tiene el siguiente aspecto:

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
Parámetro Descripción
access_token El token de acceso solicitado. La aplicación puede usar este token para autenticarse en el recurso protegido, como una API web.
token_type Indica el valor de tipo de token. El único tipo que la Plataforma de identidad de Microsoft admite es bearer.
expires_in La cantidad de tiempo que un token de acceso es válido (en segundos).

Advertencia

No intente validar ni leer tokens para ninguna API de su propiedad, incluidos los tokens de este ejemplo, en el código. Los tokens de los servicios de Microsoft pueden usar un formato especial que no se validará como un JWT y también se pueden cifrar para los usuarios consumidores (cuenta Microsoft). Aunque la lectura de tokens es una herramienta útil de depuración y aprendizaje, no tome dependencias de esto en el código ni asuma detalles sobre los tokens que no son para una API que controle.

Respuesta de error

Una respuesta de error (400 solicitud no correcta) tiene el siguiente aspecto:

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "YYYY-MM-DD HH:MM:SSZ",
  "trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
  "correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
Parámetro Descripción
error Una cadena de código de error que puede usar para clasificar los tipos de errores que se producen y para reaccionar ante ellos.
error_description Un mensaje de error específico que podría ayudarlo a identificar la causa raíz de un error de autenticación.
error_codes Una lista de los códigos de error específicos de STS que podrían ayudar en los diagnósticos.
timestamp La hora a la que se produjo el error.
trace_id Un identificador único de la solicitud para ayudar con los diagnósticos.
correlation_id Un identificador único de la solicitud para ayudar con los diagnósticos entre componentes.

Uso de un token

Ahora que adquirió un token, úselo para hacer solicitudes al recurso. Cuando expire el token, repita la solicitud al punto de conexión /token para adquirir un token de acceso nuevo.

GET /v1.0/users HTTP/1.1
Host: graph.microsoft.com:443
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...

Pruebe el siguiente comando en el terminal, asegurándose de reemplazar el token por el suyo propio.

curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG..." 'https://graph.microsoft.com/v1.0/users'

Ejemplos de código y otra documentación

Lea la documentación en la que se describen de forma general las credenciales del cliente en la Biblioteca de autenticación de Microsoft

Muestra Plataforma Descripción
active-directory-dotnetcore-daemon-v2 .NET 6.0+ Una aplicación de ASP.NET Core que muestra a los usuarios de un inquilino que consulta Microsoft Graph mediante la identidad de la aplicación, en lugar hacerlo en nombre de un usuario. El ejemplo también muestra la variación del uso de certificados para la autenticación.
active-directory-dotnet-daemon-v2 ASP.NET MVC Una aplicación web que sincroniza datos de Microsoft Graph mediante la identidad de la aplicación, en lugar hacerlo en nombre de un usuario.
ms-identity-javascript-nodejs-console Node.js Console Una aplicación Node.js que muestra los usuarios de un inquilino mediante la consulta de Microsoft Graph con la identidad de la aplicación