CAPÍTULO 7 · La identidad sale del equipo
El login acompaña al proyecto
El motivo para conducir el login desde Django no se limita a hacerlo funcionar en Azure. El equipo también piensa en el futuro: si cambia el alojamiento, conviene que el flujo de autenticación permanezca junto al código en vez de depender exclusivamente de una función particular de App Service. Microsoft Entra sigue siendo el proveedor de identidad, pero su integración se controla desde la aplicación.
Registramos la aplicación, configuramos su retorno y entregamos al servidor los identificadores y la credencial que necesita. La URI debe coincidir con la ruta que Django atiende, como /aad/callback. En este recorrido dejamos desactivada la autenticación de plataforma de App Service y evitamos agregar un proveedor que intente conducir otro flujo al mismo tiempo.
La decisión mejora la continuidad al cambiar de alojamiento, aunque una migración seguirá requiriendo revisar secretos, dominios y configuración. Para comprender por qué no activamos determinadas opciones del portal, ahora conviene examinar la alternativa: permitir que el propio App Service autentique antes de entregar la petición a Django.
Leer esta parte dentro del relato completo →DEL RELATO A LA PRÁCTICA
Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.
LABORATORIO DE CONFIGURACIÓN
Prepara tu estación de despliegue
Cambia el entorno, el servidor y la identidad para comparar sus responsabilidades.

Simulación didáctica. Los valores son ejemplos: no crea recursos, no inicia sesión ni publica archivos. Sin JavaScript, consulta la tabla y los pasos de la lección.
MIRA · CONECTA · COMPRENDE
Un adaptador entre identidad y dominio
Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.
Selecciona una pieza para destacar su responsabilidad.
Leer la explicación del mapa
- Claims verificadas. No son JSON sin validar
- Adaptador. Construye actor estable
- Capacidades. Mapea roles conocidos
- Objeto. Evalúa pertenencia y alcance
01 / EL PROBLEMA
¿Para qué sirve?
Una librería de autenticación no define la política de negocio. Hace falta un contrato estable entre identidad corporativa y servicios Django.
02 / COMPRENDER
El concepto, explicado
MSAL propio puede funcionar en local y Azure. Aquí Django inicia el flujo y procesa la respuesta. En App Service Authentication deja la autenticación de plataforma desactivada y no agregues el proveedor Microsoft para este recorrido. Configurar USE_EASYAUTH=False en Python no desactiva por sí solo Easy Auth en el portal.
En Entra, Registro de aplicaciones, configura plataforma Web y una URI de retorno que coincida con la ruta real. Usaremos http://localhost:8000/aad/callback en DEV y https://tu-host/aad/callback en PROD. Respeta esquema, host, puerto local, ruta y barra final; no intercambies localhost y 127.0.0.1 sin registrarlo y probarlo.
El client ID y tenant ID identifican el registro y directorio. El client secret es una credencial del servidor: conserva el valor, no el identificador del secreto, en el almacén del entorno; controla vencimiento y rotación. Una app pública no debe recibir este secreto en JavaScript.
Usaremos AZURE_REDIRECT_URI de forma uniforme: AZURE_REDIRECT_URL es otro nombre y solo funciona si tu código lo lee explícitamente. USE_EASYAUTH también es una opción propia del proyecto, no de MSAL.
La aplicación empresarial asociada gestiona asignaciones en el tenant. Resuelve permisos de negocio después de validar identidad. Valida state/nonce mediante el flujo de biblioteca, tenant y audiencia; no confíes en headers de identidad enviados por el cliente.
Easy Auth es una alternativa separada, explicada en los temas siguientes. Usa su proveedor de plataforma y su callback /.auth/login/aad/callback. No mezcles ese callback con la vista /aad/callback de Django.
AZURE_SCOPES, si tu implementación lo usa, debe convertirse del texto de configuración a una lista de permisos que realmente necesita el cliente. No pidas permisos de Microsoft Graph solo para mostrar una pantalla. Aplica también la política de tenants permitidos en el validador de identidad; una variable llamada ALLOWED_TENANTS no valida nada por sí sola.
El equipo eligió MSAL dentro de Django para que el flujo de autenticación acompañara al código si el alojamiento cambiaba, por ejemplo de Azure a AWS. Esto reduce el acoplamiento al middleware de App Service, pero conserva la dependencia de Microsoft Entra como proveedor de identidad. Una migración todavía exige actualizar callbacks, secretos, red, sesiones y configuración del nuevo alojamiento.
El punto de partida es Entra ID > Registros de aplicaciones > Nuevo registro. Allí se obtienen el client ID y tenant ID, se registra la plataforma Web y se crea el secreto de cliente. La aplicación empresarial es el service principal asociado en el tenant; se usa para asignaciones y acceso. Registro y aplicación empresarial son objetos relacionados, no dos nombres intercambiables del mismo paso.
Dos mecanismos de autenticación
| Decisión | MSAL propio | Easy Auth |
|---|---|---|
| Quién procesa el login | Django + biblioteca MSAL | Plataforma App Service |
| Authentication del App Service | Desactivado en esta ruta | Activado con proveedor Microsoft |
| Callback productivo | https://host/aad/callback | https://host/.auth/login/aad/callback |
| Local con runserver | Sí, con registro y URI DEV | No incluye el servicio de plataforma |
| Permisos de negocio | Se verifican en Django | También se verifican en Django |
03 / CONSTRUIR
Implementación paso a paso
- Crea o identifica registros separados para DEV y PROD.
- Configura Web y registra el callback exacto de cada entorno.
- Guarda client ID, tenant ID y credencial de servidor en el entorno correspondiente.
- En Azure para MSAL propio, desactiva App Service Authentication y evita configurar su proveedor Microsoft.
- Implementa inicio y callback con el flujo de MSAL y sesión de servidor.
- Prueba login, retorno, logout, tenant incorrecto y permisos de negocio.
04 / APLICAR
Ejemplo en SensorHub
# Contrato del ejemplo, sin credenciales reales:
# .env DEV, cargado por development.py
# USE_EASYAUTH=false
# AZURE_TENANT_ID=tenant-del-laboratorio
# AZURE_CLIENT_ID=client-id-del-registro-dev
# AZURE_CLIENT_SECRET=valor-guardado-fuera-de-git
# AZURE_REDIRECT_URI=http://localhost:8000/aad/callback
# PROD: mismos nombres, valores del registro PROD en App Service.
# AZURE_REDIRECT_URI=https://tu-host/aad/callback
# App Service Authentication: desactivado en este recorrido.
# Esquema de integración; requiere vistas y sesión implementadas:
# config/urls.py
# path("aad/login", login_view, name="aad_login")
# path("aad/callback", callback_view, name="aad_callback")
# Inicio: flow = msal_client.initiate_auth_code_flow(
# scopes=scopes, redirect_uri=settings.AZURE_REDIRECT_URI)
# Guardar flow en sesión del servidor antes de redirigir a flow["auth_uri"].
# Callback: msal_client.acquire_token_by_auth_code_flow(flow, request.GET)
# Comprobar errores y claims antes de establecer la sesión de usuario.Cómo leer el ejemplo
- El esquema muestra puntos de integración, no un módulo de autenticación completo para copiar.
- La ruta sin barra final debe coincidir con Entra y la variable del entorno.
- La sesión que guarda el flujo debe sobrevivir a la redirección y a distintos workers.
Error habitual
Si el navegador acaba en /.auth/login/aad, interviene la autenticación de plataforma. Comprueba Authentication y su proveedor, además de la configuración de Django. No cambies rutas al azar.
05 / PRACTICAR
Tu turno
El código usa /aad/callback pero Entra devuelve AADSTS50011. Enumera tres comprobaciones.
Ver solución orientativa
Comprueba redirect_uri enviada, URI Web registrada y AZURE_REDIRECT_URI del entorno activo; compara host, protocolo, puerto y barra final. Después verifica que Easy Auth no intercepte el recorrido MSAL propio.
06 / VERIFICAR
Cómo sabes que funciona
- DEV y PROD vuelven al callback de Django correspondiente.
- El estado del portal coincide con el mecanismo elegido.
- Los secretos y tokens no se exponen al navegador ni en logs.
Para profundizar
Documentación oficial para comprobar configuración, permisos y condiciones vigentes. Revisión del tema: 2026-10-12.
CONTINUAR LA EXPERIENCIA
El siguiente paso del recorrido:
Easy Auth: autenticación antes de Django →Continuar en modo relato