Plataforma de identidad de Microsoft y flujo de concesión implícita de OAuth 2.0
La plataforma de identidad de Microsoft admite el flujo de concesión implícita de OAuth 2.0, tal y como se describe en la especificación OAuth 2.0. La característica que define la concesión implícita es que los tokens, de identificador o de acceso, se devuelven directamente del punto de conexión /authorize en lugar del punto de conexión /token. Con frecuencia se usa como parte del flujo de código de autorización, en lo que se denomina "flujo híbrido", para recuperar el token de identificador en la solicitud de /authorize, junto con un código de autorización.
En este artículo se describe cómo programar directamente con el protocolo de la aplicación para solicitar tokens de Microsoft Entra ID. 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. Para obtener una lista de ejemplos de código que usan MSAL, consulte los ejemplos de código de Plataforma de identidad de Microsoft.
Advertencia
Microsoft recomienda que no use el flujo de concesión implícita. En la mayoría de los escenarios, hay alternativas más seguras y recomendables. Determinadas configuraciones de este flujo requieren un alto grado de confianza en la aplicación y conllevan riesgos que no están presentes en otros flujos. Solo debe usar este flujo cuando no se puedan usar otros más seguros. Para obtener más información, consulte los problemas de seguridad del flujo de concesión implícita.
Diagrama de protocolo
En el diagrama siguiente se muestra el aspecto que tiene el flujo implícito de inicio de sesión completo y en las secciones siguientes se describe cada paso con detalle.
Escenarios adecuados para la concesión implícita de OAuth2
La concesión implícita solo resulta confiable con la parte inicial e interactiva del flujo de inicio de sesión, en la que la ausencia de cookies de terceros no puede afectar a la aplicación. Esta limitación implica que solo debe usarse como parte del flujo híbrido, en el que la aplicación solicita un código y un token al punto de conexión de autorización. En un flujo híbrido, la aplicación reciba un código que se puede canjear por un token de actualización y que la sesión de inicio de la aplicación siga siendo válida en el tiempo.
Preferencia del flujo de código de autenticación
Dado que algunos exploradores han eliminado la compatibilidad con cookies de terceros, el flujo de concesión implícita ya no es un método de autenticación adecuado. Las características de inicio de sesión único (SSO) silencioso del flujo implícito no funcionan sin las cookies de terceros, lo que provoca interrupciones en las aplicaciones cuando intentan obtener un nuevo token. Es muy recomendable que todas las aplicaciones nuevas usen el flujo de código de autorización, que ahora admite aplicaciones de una sola página en lugar del flujo implícito. Las aplicaciones de página única existentes también deben migrar al flujo de código de autorización.
Problemas de seguridad del flujo de concesión implícita
El flujo de concesión implícita está pensado para las aplicaciones web tradicionales en las que el servidor tiene control sobre el procesamiento seguro de los datos POST. Hay dos formas principales de entregar tokens con el flujo de concesión implícita: donde response_mode
se devuelve como un fragmento de dirección URL o como parámetro de consulta (mediante form POST
y GET
). En el flujo implícito donde response_mode=form_post
, el token se entrega de forma segura a través de un formulario HTML posterior al URI de redirección del cliente. Este método garantiza que el token no se expone en el fragmento de dirección URL, lo que a su vez evita los riesgos de pérdida de tokens a través del historial del navegador o los encabezados de referencia.
Los problemas de seguridad del flujo implícito surgen cuando se entregan tokens mediante response_mode=fragment
. El fragmento de dirección URL es la parte de la dirección URL que viene después del símbolo #
y no se envía al servidor cuando el navegador solicita una nueva página, pero está disponible para JavaScript, que se ejecuta en el navegador. Esto significa que el token se expone a cualquier JavaScript que se ejecute en la página, lo que podría ser un riesgo de seguridad si la página incluye scripts de terceros. Estos problemas de seguridad de los tokens de los SPA tampoco se aplican al flujo implícito con form POST
.
¿Cuándo debe permitir que se emita un token de acceso o un token de identificación cuando se solicite mediante concesión implícita o flujo híbrido?
La concesión implícita y el flujo híbrido no son tan seguros como otros flujos de OAuth. A menos que sea absolutamente necesario, no debería permitir que se emita un token de acceso o de identificación cuando se solicite mediante una concesión implícita o un flujo híbrido en el registro de la aplicación. Si usted (o los desarrolladores) están usando MSAL en la aplicación para implementar la autenticación y la autorización, entonces no es necesario habilitar ninguno de los dos campos.
Sin embargo, si usted (o los desarrolladores) no usan MSAL en su aplicación, la siguiente tabla describe cuándo deben activarse los tokens de acceso o de identificación.
Tipo de aplicación que está compilando | Tokens que debe habilitar en el registro de aplicaciones |
---|---|
Una SPA (aplicación de página única) que no usa el flujo de código de autorización con PKCE | Tokens de acceso y tokens de identificador |
Una aplicación web o SPA que llama a una API web a través de JavaScript mediante el flujo implícito | Tokens de acceso y tokens de identificador |
Una aplicación web de ASP.NET Core y otras aplicaciones web que usan la autenticación híbrida | Tokens de identificador |
Envío de la solicitud de inicio de sesión
Al principio, para iniciar la sesión del usuario en la aplicación, puede enviar una solicitud de autenticación OpenID Connect y obtener un id_token
de la Plataforma de identidad de Microsoft.
Importante
Para solicitar con éxito un token de identificador y un token de acceso, el registro de aplicación de la página Centro de administración de Microsoft Entra: Registros de aplicaciones debe tener habilitado el flujo de concesión implícita correspondiente; para ello, hay que seleccionar Tokens de identificador y Tokens de acceso en la sección Flujos de concesión implícita e híbridos. Si no está habilitado, se devolverá un error unsupported_response
:
The provided value for the input parameter 'response_type' is not allowed for this client. Expected value is 'code'
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
Parámetro | Tipo | Descripción |
---|---|---|
tenant |
requerido | El valor {tenant} de la ruta de acceso de la solicitud se puede usar para controlar quién puede iniciar sesión en la aplicación. Los valores permitidos son common , organizations , consumers y los identificadores de inquilinos. Para obtener más información, consulte los conceptos básicos sobre el protocolo. En el caso de los escenarios de invitado en los que se inicia la sesión de un usuario de un inquilino a otro inquilino, se debe proporcionar el identificador del inquilino para iniciar la sesión correctamente en el inquilino de recursos. |
client_id |
requerido | El identificador de aplicación (cliente) que elcentro de administración de Microsoft Entra: página de registros de aplicaciones asignó a la aplicación. |
response_type |
requerido | Debe incluir id_token para el inicio de sesión en OpenID Connect. También puede incluir el response_type , token . El uso de token aquí permite a la aplicación recibir un token de acceso inmediatamente desde el punto de conexión autorizado sin tener que realizar una segunda solicitud para autorizar el punto de conexión. Si usa el token response_type, el parámetro scope debe contener un ámbito que indica para qué recurso se va a emitir el token (por ejemplo, user.read en Microsoft Graph). También puede contener code en lugar de token a fin de proporcionar un código de autorización para su uso en el flujo de código de autorización. A esta respuesta de id_token +code se la denomina a veces flujo híbrido. |
redirect_uri |
recomendado | El URI de redirección de la aplicación, donde su aplicación envía y recibe las respuestas de autenticación. Debe coincidir exactamente con uno de los URI de redireccionamiento que registró en el Centro de administración de Microsoft Entra, excepto que debe estar codificado con dirección URL. |
scope |
requerido | Una lista de ámbitos separada por espacios. Para OpenID Connect (id_tokens ), asegúrese de incluir el ámbito openid , lo que se traduce en el permiso de inicio de sesión en la interfaz de usuario de consentimiento. Opcionalmente, también puede incluir los ámbitos email y profile para obtener acceso a datos de usuario adicionales. También puede incluir otros ámbitos en esta solicitud para solicitar consentimiento para diversos recursos, si se solicita un token de acceso. |
response_mode |
recomendado | Especifica el método que debe usarse para enviar el token resultante de nuevo a la aplicación. El valor predeterminado es query para un token de acceso, pero fragment si la solicitud incluye un valor id_token. Por motivos de seguridad, se recomienda usar form_post para el flujo implícito para garantizar que el token no queda expuesto en el fragmento de dirección URL. |
state |
recomendado | 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. Normalmente se usa un valor único generado de forma aleatoria para evitar los ataques de falsificación de solicitudes entre sitios. El estado también 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. |
nonce |
requerido | Un valor incluido en la solicitud, generada por la aplicación, que se incluirá en el token de identificador resultante como una notificación. La aplicación puede comprobar este valor para mitigar los ataques de reproducción de token. Normalmente, el valor es una cadena única aleatoria que se puede usar para identificar el origen de la solicitud. Solo es necesario cuando se solicita un valor id_token. |
prompt |
opcional | Indica el tipo de interacción necesaria con el usuario. Los únicos valores válidos en este momento son login , none , select_account y consent . prompt=login obliga al usuario a escribir sus credenciales en esa solicitud, negando el inicio de sesión único. prompt=none es lo contrario. Garantizará que no se presente al usuario ninguna solicitud interactiva. Si la solicitud no se puede completar sin notificaciones mediante el inicio de sesión único, la Plataforma de identidad de Microsoft devuelve un error. prompt=select_account envía al usuario a un selector de cuenta donde aparecen todas las cuentas que se recuerdan en la sesión. prompt=consent desencadenará el cuadro de diálogo de consentimiento de OAuth después de que el usuario inicia sesión, y solicitará a este que conceda permisos a la aplicación. |
login_hint |
opcional | Puede usar este parámetro para rellenar previamente el campo de nombre de usuario y dirección de correo electrónico de la página de inicio de sesión del usuario, si sabe el nombre de usuario con anticipación. A menudo, las aplicaciones usan este parámetro durante la reautenticación, una vez que ya se extrajo la notificación opcional de login_hint de un inicio de sesión anterior. |
domain_hint |
opcional | Si se incluye, omite el proceso de detección basado en correo electrónico por el que pasa el usuario en la página de inicio de sesión, con lo que la experiencia de usuario será ligeramente más sencilla. Este parámetro se usa normalmente con las aplicaciones de línea de negocio que se utilizan en un solo inquilino, en las que proporcionan un nombre de dominio para un inquilino determinado y reenviarán el usuario al proveedor de federación de ese inquilino. Esta indicación evita que los invitados inicien sesión en la aplicación y limita el uso de credenciales en la nube, como FIDO. |
En este punto, se le pide al usuario que escriba sus credenciales y que complete la autenticación. La Plataforma de identidad de Microsoft se asegura de que el usuario ha dado su consentimiento a los permisos indicados en el parámetro de consulta scope
. Si el usuario no ha dado su consentimiento a ninguno de esos permisos, se le solicita para los permisos necesarios. Para obtener más información, consulte Permisos, consentimiento y aplicaciones de varios inquilinos.
Una vez que el usuario se autentica y otorga su consentimiento, la Plataforma de identidad de Microsoft devuelve una respuesta a la aplicación en el redirect_uri
indicado mediante el método especificado en el parámetro response_mode
.
Respuesta correcta
Una respuesta correcta que usa response_mode=fragment
y response_type=id_token+code
es como la siguiente (con saltos de línea para mejorar la legibilidad):
GET https://localhost/myapp/#
code=0.AgAAktYV-sfpYESnQynylW_UKZmH-C9y_G1A
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
Parámetro | Descripción |
---|---|
code |
Incluido si response_type incluye code . Es un código de autorización adecuado para su uso en el flujo de código de autorización. |
access_token |
Incluido si response_type incluye token . El token de acceso que solicitó la aplicación. El token de acceso no se debe descodificar o inspeccionar en forma alguna; se debe tratar como una cadena opaca. |
token_type |
Incluido si response_type incluye token . Esta es siempre Bearer . |
expires_in |
Incluido si response_type incluye token . Indica el número de segundos que el token es válido para el almacenamiento en caché. |
scope |
Incluido si response_type incluye token . Indica uno o varios ámbitos para los access_token que es válido. Es posible que no incluya todos los ámbitos solicitados si no eran aplicables al usuario. Por ejemplo, los ámbitos exclusivos de Microsoft Entra que se solicitan al iniciar sesión con una cuenta personal. |
id_token |
Un token web JSON (JWT) firmado. La aplicación puede descodificar los segmentos de este token para solicitar información sobre el usuario que ha iniciado sesión. La aplicación puede almacenar en caché los valores y mostrarlos, pero no debe depender de estos para ningún límite de seguridad o autorización. Para más información sobre los tokens de identificación, consulte id_token reference . Nota: Solo se proporciona si el ámbito openid se solicitó, y response_type incluía id_tokens . |
state |
Si se incluye un parámetro de estado en la solicitud, debería aparecer el mismo valor en la respuesta. La aplicación debería comprobar que los valores de state de la solicitud y la respuesta sean idénticos. |
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
Las respuestas de error también pueden enviarse al redirect_uri
para que la aplicación pueda controlarlas adecuadamente:
GET https://localhost/myapp/#
error=access_denied
&error_description=the+user+canceled+the+authentication
Parámetro | Descripción |
---|---|
error |
Una cadena de código de error que puede utilizarse para clasificar los tipos de errores que se producen y para reaccionar ante ellos. |
error_description |
Un mensaje de error específico que puede ayudar a un desarrollador a identificar la causa de un error de autenticación. |
Adquisición silenciosa de tokens de acceso
Ahora que el usuario ha iniciado la sesión en su aplicación de página única, puede obtener tokens de acceso de forma silenciosa para llamar a las API web protegidas por la plataforma de identidad de Microsoft, como las de Microsoft Graph. Incluso si ya recibió un token mediante el token
response_type, puede usar este método para adquirir tokens para recursos adicionales sin tener que redirigir al usuario para que vuelva a iniciar sesión.
Importante
No es probable que esta parte del flujo implícito funcione con la aplicación, ya que se usa en diferentes exploradores debido a la eliminación de cookies de terceros de forma predeterminada. Aunque esto todavía funciona en exploradores basados en Chromium que no están en modo Incógnito, los desarrolladores deberían replantearse utilizar esta parte del flujo. En los exploradores que no admitan cookies de terceros, verá un error que indica que ningún usuario ha iniciado sesión, ya que el explorador quitará las cookies de la página de inicio de sesión.
En el flujo normal de OpenID Connect y OAuth, haría esto mediante una solicitud al punto de conexión /token
de la plataforma de identidad de Microsoft. Puede hacer la solicitud en un iframe oculto para obtener nuevos tokens para otras API web:
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&response_mode=fragment
&state=12345
&nonce=678910
&prompt=none
&login_hint=myuser@mycompany.com
Para obtener más información sobre los parámetros de consulta en la dirección URL, vea Envío de la solicitud de inicio de sesión.
Sugerencia
Pruebe a copiar y pegar la siguiente solicitud en una pestaña del navegador con un valor real client_id
y username
desde el registro de la aplicación. Esto le permitirá ver la solicitud de token silencioso en acción.
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={your-client-id}&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read&response_mode=fragment&state=12345&nonce=678910&prompt=none&login_hint={username}
Este paso funcionará incluso en exploradores que no admitan cookies de terceros, ya que escribirá la solicitud directamente en una barra del explorador en lugar de abrirla en un iframe.
Gracias al parámetro prompt=none
, esta solicitud tiene éxito o da error inmediatamente y vuelve a la aplicación. La respuesta se envia a la aplicación en el parámetro redirect_uri
indicado mediante el método especificado en el parámetro response_mode
.
Respuesta correcta
Una respuesta correcta al usar response_mode=fragment
tiene el siguiente aspecto:
GET https://localhost/myapp/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fdirectory.read
Parámetro | Descripción |
---|---|
access_token |
Incluido si response_type incluye token . El token de acceso que la aplicación ha solicitado, en este caso para Microsoft Graph. El token de acceso no se debe descodificar o inspeccionar en forma alguna; se debe tratar como una cadena opaca. |
token_type |
Esta es siempre Bearer . |
expires_in |
Indica el número de segundos que el token es válido con fines de almacenamiento en caché. |
scope |
Indica uno o varios ámbitos para los que el token de acceso es válido. Es posible que no incluya todos los ámbitos solicitados, si no eran aplicables al usuario (si solo se solicitan ámbitos exclusivos de Microsoft Entra al usar una cuenta personal para iniciar sesión). |
id_token |
Un token web JSON (JWT) firmado. Incluido si response_type incluye id_token . La aplicación puede descodificar los segmentos de este token para solicitar información sobre el usuario que ha iniciado sesión. La aplicación puede almacenar en caché los valores y mostrarlos, pero no debe depender de estos para ningún límite de seguridad o autorización. Para obtener más información sobre los parámetros id_token, vea la Referencia de id_token . Nota: Solo se proporciona si se solicitó el ámbito openid . |
state |
Si se incluye un parámetro de estado en la solicitud, debería aparecer el mismo valor en la respuesta. La aplicación debería comprobar que los valores de estado de la solicitud y la respuesta son idénticos. |
Respuesta de error
Las respuestas de error también pueden enviarse al redirect_uri
para que la aplicación pueda controlarlas adecuadamente. Si es prompt=none
, un error esperado es:
GET https://localhost/myapp/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Parámetro | Descripción |
---|---|
error |
Una cadena de código de error que puede utilizarse para clasificar los tipos de errores que se producen y para reaccionar ante ellos. |
error_description |
Un mensaje de error específico que puede ayudar a un desarrollador a identificar la causa de un error de autenticación. |
Si recibe este error en la solicitud de iframe, el usuario debe iniciar sesión de nuevo de manera interactiva para recuperar un nuevo token. Puede elegir tratar este caso de la manera que más sentido tenga para su aplicación.
Actualización de tokens
La concesión implícita no proporciona tokens de actualización. Tanto los tokens de identificación como los tokens de acceso caducan tras un corto período de tiempo, así que su aplicación debe estar preparada para actualizar estos tokens de manera periódica. Para actualizar cualquier tipo de token, puede realizar la misma solicitud de iframe oculto descrita anteriormente mediante el parámetro prompt=none
para controlar el comportamiento de la plataforma de identidad. Si quiere recibir un nuevo token de identificación, asegúrese de usar id_token
en response_type
y scope=openid
, así como un parámetro nonce
.
En los navegadores que no admiten cookies de terceros, se produce un error que indica que ningún usuario ha iniciado sesión.
Envío de una solicitud de cierre de sesión
end_session_endpoint
de OpenID Connect permite a la aplicación enviar una solicitud para la Plataforma de identidad de Microsoft para finalizar una sesión de usuario y borrar las cookies establecidas por la Plataforma de identidad de Microsoft. Para que un usuario cierre por completo la sesión de una aplicación web, la aplicación debe finalizar su propia sesión con el usuario (normalmente borrando una caché de tokens o eliminando las cookies) y luego redirigir el explorador para:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout?post_logout_redirect_uri=https://localhost/myapp/
Parámetro | Tipo | Descripción |
---|---|---|
tenant |
requerido | El valor {tenant} de la ruta de acceso de la solicitud se puede usar para controlar quién puede iniciar sesión en la aplicación. Los valores permitidos son common , organizations , consumers y los identificadores de inquilinos. Para obtener más información, consulte los conceptos básicos sobre el protocolo. |
post_logout_redirect_uri |
recomendado | La dirección URL a la que se debe redirigir al usuario después de completar el cierre de sesión. Este valor debe coincidir con uno de los URI de redirección registrados en la aplicación. Si no se incluye, el usuario ve un mensaje genérico de la Plataforma de identidad de Microsoft. |
Consulte también
- Repase los ejemplos de MSAL JS para comenzar a codificar.
- Revise el flujo de código de autorización como una alternativa más nueva y mejor que la concesión implícita.