Microsoft Graph OAuthAutenticar buzones de Outlook y Microsoft 365
Una guía completa de OAuth de Microsoft Graph para 2026 para desarrolladores de SaaS. Cubre el registro de aplicaciones de Microsoft Entra, los puntos de conexión de autoridad, los ámbitos de Mail, los permisos delegados vs. de aplicación, el consentimiento del administrador, el código de autorización + PKCE, la rotación de tokens de actualización, los códigos de error AADSTS y cómo Unipile elimina 5 semanas de "plomería" de OAuth en 5 minutos.
import solicita
# Paso 1: Generar un enlace de autenticación alojado
response = requests.Correo electrónico:(
"https://apiXXX.unipile.com:XXX
/api/v1/hosted/cuentas/enlace",
encabezados={"Clave API X": clave_api},
json={
"tipo": "crear",
"proveedores": ["MICROSOFT"],
"url_de_la_api": tu_dsn,
"expiraEn": "31/12/2026 23:59:59"
}
)
# Paso 2: Redirige al usuario a la URL
auth_url = respuesta.json()["url"]
# Unipile gestiona todo el flujo de OAuth
#, incluyendo Entra, osciloscopios, tokens y actualizaciónPor qué OAuth de Microsoft Graph es innegociable en 2026
Si tu aplicación SaaS lee, envía o sincroniza correos electrónicos de Outlook o Microsoft 365, la autenticación OAuth de Microsoft Graph ya no es opcional. Tres importantes deprecaciones han hecho obsoletas la autenticación básica, los protocolos heredados y las contraseñas de aplicación. OAuth 2.0 a través de la API de Microsoft Graph es la única vía compatible.
Los 3 flujos de OAuth que Microsoft admite (y cuál necesita SaaS)
La plataforma de identidad de Microsoft admite varios tipos de concesión de OAuth 2.0. Elegir el incorrecto es una fuente común de tiempo de ingeniería desperdiciado. Aquí está el desglose para aplicaciones SaaS que acceden al correo electrónico en nombre de sus usuarios.
Registro de Aplicación de Microsoft Entra: 7 Pasos
Antes de que tu aplicación pueda solicitar tokens OAuth, necesitas una aplicación registrada en Microsoft Entra ID (anteriormente Azure Active Directory). Aquí están los pasos exactos, incluyendo qué valores de campo son importantes y cuáles son cosméticos.
portal.azure.com, ir a Microsoft Entra ID (buscar en la barra superior), luego Registros de aplicaciones, luego haz clic + Nuevo registro. Ver el Documentación completa de Microsoft OAuth para contexto adicional.Cuentas en cualquier directorio organizacional (cualquier inquilino de Microsoft Entra ID - multiinquilino) y cuentas personales de Microsoft. Esto corresponde a la /común endpoint de autoridad./organizaciones autoridad y reduce tu superficie de consentimiento. Más sobre los puntos finales de autoridad en la sección 4.Web para aplicaciones del lado del servidor. Usar Aplicación de página única (SPA) para flujos del lado del cliente (habilita automáticamente PKCE).https://app.yourproduct.com/auth/microsoft/callback. Se requiere una coincidencia exacta, cualquier desviación genera AADSTS50011.http://localhost:3000/callback) pero las URIs de producción deben usar HTTPS. Registre ambos por separado.Mail.Read, acceso_sin_conexión, openid, perfilMail.ReadWrite, Mail.Enviar, acceso_sin_conexión, openid, perfilclient_id parámetro en todas las solicitudes de autenticación./común en su lugar, pero mantenga este valor para las URL de consentimiento del administrador.Elegir el punto de conexión de autoridad de Microsoft adecuado
La URL de autoridad que utilizas en tus solicitudes OAuth determina qué tipos de cuentas de Microsoft pueden autenticarse y qué tokens recibes. Si la configuras incorrectamente, se producirán errores silenciosos que impedirán que algunos usuarios se autentiquen por completo.
| URL de autoridad | Acepta | Caso práctico | Advertencias |
|---|---|---|---|
| /comúnLa mayoría de SaaS | Tanto las cuentas de Microsoft Entra (trabajo/escuela) como las cuentas personales de Microsoft (Outlook.com, Hotmail, Live) | SaaS multi-inquilino que da servicio a todos los usuarios de Microsoft. Un único punto de conexión controla a toda su base de usuarios. | Los tokens son emitidos por el tenant principal de cada usuario, no por el tuyo. La validación de tokens debe usar un emisor específico del tenant o aceptar múltiples emisores. No se pueden aplicar directivas de Acceso Condicional. |
| /organizaciones | Cuentas de Microsoft Entra ID solamente (trabajo/escuela). No se admiten cuentas personales de Microsoft. | SaaS B2B dirigido solo a clientes empresariales, nunca a usuarios de consumidor de Outlook.com. | Los usuarios con cuentas personales de Microsoft recibirán un error. Validación de tokens más simple (patrón de emisor único aceptable). |
| consumidores | Solo cuentas personales de Microsoft (Outlook.com, Hotmail, Live). | Aplicaciones de consumo dirigidas a bandejas de entrada personales. Raro en SaaS B2B. | Las cuentas de Microsoft 365 para empresas son rechazadas. No es útil para SaaS que atiende a usuarios de negocios. |
| /{id-de-inquilino} | Cuentas en un inquilino específico de Microsoft Entra solamente. | Herramientas internas de un solo inquilino (la aplicación de tu propia empresa). Flujos de consentimiento de administrador dirigidos a un inquilino específico. También se usa en el patrón de URL de redirección de consentimiento de administrador. | Los usuarios de inquilinos alternativos son rechazados. Solo apropiado para aplicaciones internas o cuando se bloquea deliberadamente a un inquilino de un cliente. |
/común endpoint, el iss (emisor) la reclamación en el JWT será https://login.microsoftonline.com/{tenantId}/v2.0 dónde {tenantId} varía por usuario. Configura tu biblioteca de validación JWT para aceptar cualquier emisor que coincida con https://login.microsoftonline.com/{tenantId}/v2.0 en lugar de una cadena de emisor fija.Ámbitos de correo de Microsoft Graph: Desglose granular
Microsoft Graph utiliza ámbitos de permisos para controlar lo que tu aplicación puede hacer. Solicitar demasiados ámbitos aumenta la fricción en la pantalla de consentimiento y reduce la conversión. Solicitar muy pocos provoca errores en tiempo de ejecución. Aquí tienes todos los ámbitos de correo que necesitas conocer.
| Alcance | Tipo | Qué permite | ¿Consentimiento de administrador? |
|---|---|---|---|
| Mail.Read | Delegado | Leer todos los mensajes en el buzón del usuario autenticado. Incluye encabezados, cuerpo, archivos adjuntos. Solo lectura, no se puede modificar ni enviar. | Usuario |
| Mail.ReadBasic | Delegado | Leer propiedades limitadas del mensaje: asunto, remitente, destinatarios, fecha. No se puede leer el cuerpo del mensaje ni los archivos adjuntos. Útil para listar la bandeja de entrada de forma ligera sin acceso completo al contenido. | Usuario |
| Mail.ReadWrite | Delegado | Leer y modificar todos los mensajes. Incluye crear, actualizar, eliminar mensajes y carpetas. Superconjunto de Mail.Read - no solicites ambos. | Usuario |
| Mail.Enviar | Delegado | Envía correos electrónicos como el usuario autenticado. Requerido incluso si también tienes Mail.ReadWrite: el envío es un permiso separado en Microsoft Graph. | Usuario |
| Correo.Leer.Compartido | Delegado | Leer correo en buzones compartidos o en los buzones de otros usuarios a los que el usuario autenticado ha tenido acceso. No para leer el buzón del propio usuario. | Usuario |
| Mail.ReadWrite.Shared | Delegado | Leer y modificar correos electrónicos en buzones compartidos a los que el usuario tiene acceso. | Usuario |
| Mail.Enviar.Compartido | Delegado | Enviar correo electrónico desde buzones compartidos o "enviar en nombre de" otro usuario (si dicho usuario ha concedido acceso). | Usuario |
| acceso_sin_conexión | Delegado | Instruye a Microsoft a emitir un token de actualización. Sin él, solo recibes un token de acceso de corta duración sin forma de renovarlo. Siempre requerido para aplicaciones SaaS. | Usuario |
| openid | Delegado | Devuelve un token de identificación con la identidad básica del usuario. Requerido si quieres saber quién se autenticó sin hacer una llamada separada a la API /me. | Usuario |
| perfil | Delegado | Agrega las reclamaciones `name` y `preferred_username` al token de ID. Normalmente se incluye con `openid`. | Usuario |
| Mail.Read (Aplicación) | Aplicación | Leer todo el correo de todos los buzones del tenant sin interacción del usuario. Usado por servicios de daemon. Requiere el consentimiento del administrador del tenant. | Se necesita administrador |
| Mail.ReadWrite (Aplicación) | Aplicación | Leer y escribir todo el correo en todos los buzones de inquilinos. Permiso muy amplio. Solo para herramientas internas confiables con la aprobación explícita del administrador del inquilino. | Se necesita administrador |
scope=Mail.Readoffline_accessopenidprofile
scope=Mail.ReadWriteMail.Sendoffline_accessopenidprofile
Permisos delegados vs. permisos de aplicación: cuándo aplicar cada uno
Microsoft Graph utiliza dos modelos de permisos fundamentalmente diferentes. La mayoría de los desarrolladores de SaaS eligen por defecto el incorrecto, lo que da lugar a requisitos innecesarios de consentimiento del administrador y a una experiencia de usuario deficiente. Aquí se explica exactamente cuándo usar cada uno.
Código de autorización + PKCE: Ejemplos de Curl paso a paso
Aquí está el flujo completo de código de autorización OAuth 2.0 de Microsoft Graph con PKCE, desde la generación del verificador de código hasta el intercambio de tokens. Estos son ejemplos de calidad de producción que puedes adaptar directamente a tu pila.
import os, base64, hashlib
# 1. Generar code_verifier (43-128 caracteres, codificación Base64 compatible con URL)
verificador_de_código = base64.urlsafe_b64encode(
os.urandom(32)
).descifrar('utf-8').eliminar espacios en blanco al final('=')
# 2. Generar code_challenge = BASE64URL(SHA256(code_verifier))
desafío_de_código = base64.urlsafe_b64encode(
hashlib.sha256verificador_de_código.codificar('utf-8')).digestivo()
).descifrar('utf-8').eliminar espacios en blanco al final('=')
# Guarda el código de verificación en la sesión; lo necesitarás en el paso 4
# Enviar el código de desafío en la URL de autorizacióncódigo - solicita un código de autorizaciónacceso_sin_conexión para tokens de actualización.S256 - usa siempre SHA-256, nunca en texto plano# Generar la URL de autorización (formato para facilitar la lectura)
AUTH_URL="https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id=TU_CLIENT_ID
&tipo_de_respuesta=código
&redirect;_uri=https://3aapp.com/3aauth/3ams/3acb
&scope;=Mail.ReadWriteMail.Sendoffline_access
&estado=VALOR_ALEATORIO_DEL_ESTADO
&code_challenge=TU_CODE_CHALLENGE
&code_challenge_method=S256"
# Redirigir al usuario a $AUTH_URL
#: Microsoft se encarga del inicio de sesión, la autenticación multifactorial y la pantalla de consentimiento
# En caso de éxito: redirect_uri?code=AUTH_CODE&state;=...código parámetro de consulta. Valide el estado El parámetro coincide con lo que enviaste. El código caduca en 10 minutos - cámbialo inmediatamente en el paso 4.Código de autorización de # Exchange para tokens
curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=TU_CLIENT_ID" \
-d "client_secret=TU_CLIENT_SECRET" \
-d "tipo_concesión=código_autorización" \
-d "código=AUTH_CODE_FROM_CALLBACK" \
-d "redirect_uri=https://app.com/auth/ms/cb" \
-d "code_verifier=TU_VERIFICADOR_DE_CÓDIGO" \
-d "scope=Mail.ReadWrite Mail.Send offline_access"{
"tipo_token": "Portador",
"alcance": "Mail.ReadWrite Mail.Send offline_access",
"expira_en": 3600,
"token_de_acceso": "eyJ0eXAiOiJKV1Qi...",
"token de actualización": "0.ARoAi7W...",
"id_token": "eyJ0eXAi..."
}Manejo de Tokens de Actualización: Rotación, Expiración y Acceso Condicional
Los tokens de actualización de Microsoft Graph son de larga duración pero no permanentes. Varias condiciones pueden invalidarlos de forma silenciosa. Comprender estos casos extremos es lo que diferencia una integración de Microsoft OAuth de calidad de producción de una que falla aleatoriamente para los usuarios empresariales.
concesión_inválida manejar errores con gracia y solicitar reautenticación.concesión_inválida error.concesión_inválida. Este es el comportamiento esperado; manéjelo marcando la cuenta vinculada como que necesita reautorización.# Actualizar el token de acceso utilizando el token de actualización almacenado
curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=TU_CLIENT_ID" \
-d "client_secret=TU_CLIENT_SECRET" \
-d "grant_type=refresh_token" \
-d "refrescar_token=TOKEN_DE_ACTUALIZACIÓN_ALMACENADO" \
-d "scope=Mail.ReadWrite Mail.Send offline_access"
#: comprueba SIEMPRE si hay un nuevo refresh_token en la respuesta.
# Si está presente, sustitúyalo inmediatamente.
# Si aparece el error «invalid_grant», solicita al usuario que vuelva a autenticarse.Errores comunes de AADSTS decodificados
Los errores de OAuth de Microsoft Graph siguen un patrón de código de error AADSTS consistente. Estos son los más comunes que encontrará durante el desarrollo y la producción, con causas exactas y soluciones.
| Código de error | Qué significa | Causa raíz y solución |
|---|---|---|
| AADSTS65001 | No se ha concedido el consentimiento para uno o más de los ámbitos solicitados | El usuario no ha consentido los ámbitos de tu aplicación o un administrador de inquilino ha bloqueado el consentimiento del usuario para tu aplicación. Solución: Incluir consentimiento en tu URL de autorización para forzar una pantalla de consentimiento, o envía la URL de consentimiento del administrador al administrador del inquilino.Agregar solicitud=consentimiento o solicitar consentimiento del administrador |
| AADSTS50011 | Conflicto de URI de redirección | En uri_redireccionamiento En tu solicitud, la URI de redirección no coincide exactamente con ninguna URI de redirección registrada en el registro de aplicaciones de Entra. Incluso una diferencia en la barra final causa esto. Solución: Copia la URI exacta del registro de aplicaciones de Entra y úsala textualmente.Corregir: coincidencia exacta de URI en el registro de la aplicación Entra |
| AADSTS700016 | Aplicación no encontrada en el inquilino | En client_id no existe en el inquilino contra el que se está autenticando. Común cuando se usa una autoridad específica del inquilino/{id-de-inquilino}) para una aplicación multitenant. Corrección: Usar /común o /organizaciones autoridad para aplicaciones multiinquilino.Corregir: cambiar a la autoridad /common u /organizations |
| AADSTS90099 | La aplicación no ha sido autorizada en este tenant (consent_required) | La aplicación existe pero no ha sido consentida en el tenant del usuario. Difiere de AADSTS65001 en que toda la aplicación está bloqueada, no solo ámbitos específicos. Solución: Envíe la URL de consentimiento del administrador al administrador de TI del cliente. Corregir: URL de consentimiento del administrador al administrador del tenant del cliente |
| AADSTS70011 | La subvención proporcionada es inválida o ha caducado | El token de actualización o el código de autorización ha expirado o ha sido revocado. Los códigos de autorización expiran en 10 minutos. Los tokens de actualización expiran después de 90 días de inactividad o revocación por parte del administrador. Solución: Pida al usuario que se reautentique desde el principio del flujo OAuth. Corregir: solicitar reautenticación completa |
| AADSTS50076 | Se requiere MFA por la política de acceso condicional | El inquilino del usuario requiere autenticación multifactor para tu aplicación. Esta es una decisión del lado del cliente que aplica el administrador del inquilino. Tu aplicación no puede omitirla. El usuario necesita completar la MFA. Si se usa el flujo de código de autenticación, Microsoft mostrará automáticamente el aviso de MFA en el navegador. Los problemas surgen en flujos automatizados (credenciales de cliente) que no pueden completar la MFA. Esperado: el usuario debe completar la MFA |
| AADSTS50020 | La cuenta de usuario del proveedor de identidad externo no existe en el inquilino | El usuario está intentando autenticarse con una cuenta personal de Microsoft en un tenant que solo permite cuentas organizacionales, o viceversa. Corrección: Verifique su punto final de autoridad; si está utilizando /organizaciones, las cuentas personales no pueden autenticarse. Cambiar a /común si necesitas ambos.Arreglo: cambiar autoridad a /common |
| AADSTS53003 | Acceso bloqueado por la directiva de acceso condicional | La directiva de Acceso Condicional del inquilino ha bloqueado completamente este intento de autenticación (por ejemplo, país bloqueado, dispositivo no administrado, aplicación bloqueada). Esta es una decisión del lado del cliente. No puede anularla. Muestre el error al usuario y aconséjele que se ponga en contacto con su administrador de TI. Lado del cliente: aconseje al usuario que se ponga en contacto con el administrador de TI |
Olvida 5 semanas de configuración manual de OAuth con Unipile
Todo en esta guía —registro de aplicaciones Entra, puntos de conexión de autoridad, selección de ámbitos, PKCE, rotación de tokens, manejo de errores AADSTS— es tiempo de ingeniería que no hace avanzar tu producto. Unipile se encarga de toda la pila de OAuth de Microsoft Graph como un servicio administrado, por lo que tu equipo escribe una llamada a la API en lugar de 500 líneas de código de conexión de OAuth.
import solicita
UNIPILE_API_URL = "https://apiXXX.unipile.com:XXX"
UNIPILE_API_KEY = "tu-api-llave"
# Paso 1: Generar un enlace de autenticación alojado para Microsoft
response = requests.Correo electrónico:(
"{UNIPILE_API_URL}/api/v1/hosted/accounts/link",
encabezados={
"Clave API X": Clave_API_UNIPILE,
"Tipo-Contenido": "application/json"
},
json={
"tipo": "crear",
"proveedores": ["MICROSOFT"],
"url_de_la_api": UNIPILE_API_URL,
"expiraEn": "31/12/2026 23:59:59",
# Opcional: vincula este enlace a un usuario concreto
"nombre": "usuario_id_123",
# Opcional: recibir una notificación cuando se vincule la cuenta
"url_de_notificación": "https://app.yourproduct.com/webhooks/account-linked"
}
)
# Paso 2: Redirige al usuario a esta URL
url_autenticacion_alojada = respuesta.json()["url"]
Ejemplo de #: https://account.unipile.com/[encoded-token]
# Unipile gestiona: redireccionamiento de Entra, pantalla de consentimiento, PKCE,
Intercambio de tokens #, actualización del almacenamiento de tokens, gestión del ámbito
# Paso 3: Tras la autenticación, utiliza la API de correo electrónico de Unipile para leer y enviar mensajes
correos_electrónicos = requests.consiga(
f"{UNIPILE_API_URL}/api/v1/correos",
encabezados={"Clave API X": {UNIPILE_API_KEY},
params={"account_id": "id-cuenta-vinculada"}
)Preguntas frecuentes
Las preguntas más comunes sobre OAuth de Microsoft Graph para la integración de correo electrónico, desde la selección de alcances hasta el ciclo de vida de los tokens y los flujos de consentimiento empresarial.
/común endpoint de autoridad, un único registro de aplicación de Microsoft Entra maneja la autenticación tanto para cuentas personales de Outlook.com como para cuentas de trabajo/escuela de Microsoft 365. La clave es seleccionar "Cuentas en cualquier directorio organizacional y cuentas personales de Microsoft" al registrar tu aplicación en el portal de Azure.concesión_inválida error. Maneja esto con gracia: marca la cuenta enlazada como que requiere reautenticación y muestra una indicación clara de reautenticación en tu producto. Este es un comportamiento esperado, una decisión del lado del cliente fuera de tu control.Mail.Read, Mail.ReadWritey Mail.Enviar los ámbitos de consentimiento del usuario, que los usuarios individuales pueden aprobar durante el flujo de OAuth. El consentimiento del administrador solo es necesario para los permisos de la aplicación o los ámbitos de alta privilegios, como Usuario.Leer.Todos. Algunos inquilinos empresariales configuran políticas que bloquean el consentimiento de todas las aplicaciones de terceros; esa es una decisión del cliente.concesión_inválida errores y reemplazar los tokens de actualización antiguos por el nuevo devuelto en cada respuesta de token.consentimiento a su URL de autorización para forzar una pantalla de consentimiento nueva. AADSTS90099Toda la aplicación no ha sido autorizada en ese tenant; el administrador del tenant necesita pre-aprobar tu aplicación. Envía la URL de consentimiento del administrador al administrador de TI del cliente. Ambos errores son comunes en escenarios empresariales donde los tenants restringen el consentimiento del usuario.Mail.ReadWrite y Mail.Enviar en el mismo ámbito de cadena. Nota que Mail.ReadWrite y Mail.Enviar son ámbitos separados: tener acceso de lectura/escritura no otorga automáticamente permiso para enviar. Siempre incluye acceso_sin_conexión para asegurarte de que recibes un token de actualización. Consulta Página de la API de correo electrónico para detalles de implementación.