Autenticación con Azure AD y OpenID Connect
La aplicación Surveys utiliza el protocolo OpenID Connect (OIDC) para autenticar a los usuarios con Azure Active Directory (Azure AD). La aplicación Surveys utiliza ASP.NET Core, que tiene integrado un middleware para OIDC. En el diagrama siguiente, se muestra lo que ocurre cuando el usuario inicia sesión, a un alto nivel.

- El usuario hace clic en el botón de inicio de sesión en la aplicación. Esta acción se controla mediante un controlador MVC.
- El controlador MVC devuelve una acción ChallengeResult .
- El software intermedio intercepta la acción ChallengeResult y crea una respuesta 302, que redirige al usuario a la página de inicio de sesión de Azure AD.
- El usuario se autentica con Azure AD.
- Azure AD envía un token de identificador a la aplicación.
- El software intermedio valida el token de identificador. En este punto, el usuario está ya autenticado dentro de la aplicación.
- El software intermedio redirige al usuario a la aplicación.
Registro de la aplicación con Azure AD
Para habilitar OpenID Connect, el proveedor de SaaS registra la aplicación dentro de su propio inquilino de Azure AD.
Para registrar la aplicación, siga los pasos descritos en Inicio rápido: Registro de una aplicación en la plataforma de identidad de Microsoft.
Para habilitar esta funcionalidad en la aplicación de encuestas de ejemplo, consulte el archivo Léame de GitHub. Tenga en cuenta lo siguiente:
En el caso de una aplicación multiinquilino, debe configurar explícitamente la opción de varios inquilinos. Esto permite que otras organizaciones tengan acceso a la aplicación.
La dirección URL de respuesta es la dirección URL a la que Azure AD enviará las respuestas de OAuth 2.0. Cuando se usa ASP.NET Core, es necesario que coincida con la ruta de acceso que configure en el middleware de autenticación (consulte la sección siguiente).
Configuración del middleware de autenticación
En esta sección se describe cómo configurar el middleware de autenticación en ASP.NET Core 1.0 para la autenticación multiinquilino con OpenID Connect.
En la clase de inicio, agregue el middleware OpenID Connect:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(
options =>
{
Configuration.Bind("AzureAd", options);
options.Events = new SurveyAuthenticationEvents(loggerFactory);
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Events.OnTokenValidated += options.Events.TokenValidated;
})
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDownstreamWebApi(configOptions.SurveyApi.Name, Configuration.GetSection("SurveyApi"))
.AddDistributedTokenCaches();
Tenga en cuenta que algunas de las opciones se proporcionan en el archivo secrets.json. El archivo debe tener una sección denominada AzureAd con la siguiente configuración:
- Instancia. Para una aplicación multiinquilino, establezca esta propiedad en
https://login.microsoftonline.com. Se trata de la dirección URL para el punto de conexión común de Azure AD, que permite a los usuarios de cualquier inquilino de Azure AD iniciar sesión. - ClientId. El identificador de cliente de la aplicación, que obtuvo al registrar la aplicación en Azure AD.
- TenantId. GUID para iniciar la sesión de los usuarios de la organización.
Esto es lo que significan las demás opciones de middleware:
- SignInScheme. Establezca esta opción en
CookieAuthenticationDefaults.AuthenticationScheme. Esta configuración significa que, después de autenticarse el usuario, las notificaciones de usuario se almacenan localmente en una cookie. Esta cookie es la forma en que la sesión del usuario permanece iniciada durante la sesión del explorador. - Eventos. Devoluciones de llamada de evento; consulte Eventos de autenticación.
Inicio del flujo de autenticación
Para iniciar el flujo de autenticación en el MVC de ASP.NET, devuelva una acción ChallengeResult desde el controlador:
[AllowAnonymous]
public IActionResult SignIn()
{
return new ChallengeResult(
OpenIdConnectDefaults.AuthenticationScheme,
new AuthenticationProperties
{
IsPersistent = true,
RedirectUri = Url.Action("SignInCallback", "Account")
});
}
Esto hace que el software intermedio devuelva una respuesta 302 (encontrado) que redirige al punto de conexión de autenticación.
Sesiones de inicio de sesión de usuario
Como se ha mencionado, cuando el usuario inicia sesión por primera vez, el software intermedio de autenticación de cookies escribe las notificaciones del usuario en una cookie. Después, se autentican las solicitudes HTTP al leer la cookie.
De forma predeterminada, el middleware de cookies escribe una cookie de sesión, que se elimina una vez que el usuario cierra el explorador. La próxima vez que el usuario visita el sitio, tendrá que iniciar sesión de nuevo. Sin embargo, si establece IsPersistent en true en ChallengeResult, el middleware escribe una cookie persistente, por lo que la sesión del usuario permanece abierta después de cerrar el explorador. Puede configurar la expiración de las cookies; para ello, consulte Control de las opciones de cookie. Las cookies persistentes son más cómodas para el usuario, pero pueden ser inadecuadas para algunas aplicaciones (por ejemplo, una aplicación de banca) en las que el usuario desea iniciar sesión cada vez.
Acerca del software intermedio OpenID Connect
El software intermedio OpenID Connect en ASP.NET oculta la mayoría de los detalles del protocolo. Esta sección contiene algunas notas sobre la implementación que pueden ser útiles para comprender el flujo del protocolo.
En primer lugar, vamos a examinar el flujo de autenticación en términos de ASP.NET (omitiendo los detalles del flujo de protocolo OIDC entre la aplicación y Azure AD). En el siguiente diagrama se muestra el proceso.

En este diagrama, hay dos controladores MVC. El controlador de cuentas controla las solicitudes de inicio de sesión y el controlador principal sirve la página principal.
Este es el proceso de autenticación:
- El usuario hace clic en el botón de inicio de sesión y el explorador envía una solicitud GET. Por ejemplo:
GET /Account/SignIn/. - El controlador de cuentas devuelve una acción
ChallengeResult. - El software intermedio OIDC devuelve una respuesta HTTP 302 y redirige al usuario a Azure AD.
- El explorador envía la solicitud de autenticación a Azure AD.
- El usuario inicia sesión en Azure AD, desde donde se devuelve una respuesta de autenticación.
- El software intermedio OIDC crea una entidad de seguridad de notificaciones y la pasa al software intermedio de autenticación de cookies.
- El software intermedio de cookies serializa la entidad de seguridad de notificaciones y establece una cookie.
- El software intermedio OIDC redirige a la dirección URL de devolución de llamada de la aplicación.
- El explorador sigue a la redirección y envía la cookie en la solicitud.
- El software intermedio de cookies deserializa la cookie en una entidad de seguridad de notificaciones y establece
HttpContext.Useren dicha entidad. La solicitud se enruta a un controlador MVC.
Vale de autenticación
Si la autenticación se realiza correctamente, el software intermedio OIDC crea un vale de autenticación, que contiene una entidad de seguridad de notificaciones con las notificaciones del usuario.
Nota
Hasta que se complete el flujo de autenticación en su totalidad, HttpContext.User sigue albergando una entidad de seguridad anónima, no el usuario autenticado. La entidad de seguridad anónima tiene una colección vacía de notificaciones. Una vez que la autenticación se completa y la aplicación realiza la redirección, el software intermedio de cookies deserializa la cookie de autenticación y establece HttpContext.User en una entidad de seguridad de notificaciones que representa al usuario autenticado.
Eventos de autenticación
Durante el proceso de autenticación, el software intermedio OpenID Connect genera una serie de eventos:
- RedirectToIdentityProvider. Se llama justo antes de que el software intermedio redirija al punto de conexión de autenticación. Puede usar este evento para modificar la dirección URL de redireccionamiento; por ejemplo, para agregar parámetros de solicitud. Consulte Incorporación de la petición de consentimiento del administrador para ver un ejemplo.
- AuthorizationCodeReceived. Se llama con el código de autorización.
- TokenResponseReceived. Se llama después de que el software intermedio obtiene un token de acceso desde el IDP, pero antes de que se valide. Se aplica solo al flujo de código de autorización.
- TokenValidated. Se llama después de que el software intermedio valide el token de identificador. En este punto, la aplicación tiene un conjunto de notificaciones validadas sobre el usuario. Puede usar este evento para realizar una validación adicional de las notificaciones o para transformarlas. Consulte Working with claims-based identities (Trabajo con identidades basadas en notificaciones).
- UserInformationReceived. Se llama si el software intermedio obtiene el perfil de usuario desde el punto de conexión de información de usuario. Solo se aplica al flujo de código de autorización y solamente con
GetClaimsFromUserInfoEndpoint = trueen las opciones del software intermedio. - TicketReceived. Se llama cuando se completa la autenticación. Se trata del último evento, siempre que la autenticación se realice correctamente. Una vez que se controla este evento, el usuario inicia sesión en la aplicación.
- AuthenticationFailed. Se llama si se produce un error de autenticación. Use este evento para controlar los errores de autenticación; por ejemplo, redirigiendo a una página de error.
Para proporcionar devoluciones de llamada para estos eventos, establezca la opción Events en el software intermedio. Hay dos maneras diferentes de declarar los controladores de eventos: en línea con expresiones lambda o en una clase que se obtenga de OpenIdConnectEvents. Se recomienda el segundo enfoque si sus devoluciones de llamada de evento tienen lógica sustancial, para que no sobrecarguen la clase de inicio. Nuestra implementación de referencia usa este enfoque.
Puntos de conexión de OpenID Connect
Azure AD admite OpenID Connect Discovery, donde un proveedor de identidades devuelve un documento de metadatos de JSON desde un punto de conexión conocido. El documento de metadatos contiene información como:
- La dirección URL del punto de conexión de autorización. Aquí es a donde redirige la aplicación para autenticar al usuario.
- La dirección URL del punto de conexión de fin de sesión, a donde la aplicación va para cerrar la sesión del usuario.
- La dirección URL para obtener las claves de firma, que el cliente usa para validar los tokens de OIDC que obtiene del IDP.
De forma predeterminada, el software intermedio OIDC sabe cómo capturar estos metadatos. Establezca la opción Authority en el software intermedio, el cual construye la dirección URL para los metadatos. (La dirección URL de metadatos se puede invalidar estableciendo la opción MetadataAddress ).
Flujos de OpenID Connect
De forma predeterminada, el software intermedio OIDC usa un flujo híbrido con el modo de respuesta de envío de formulario.
- Flujo híbrido significa que el cliente puede obtener un token de identificador y un código de autorización en el mismo recorrido de ida y vuelta al servidor de autorización.
- Modo de respuesta de envío de formulario significa que el servidor de autorización usa una solicitud POST HTTP para enviar el token de identificador y el código de autorización a la aplicación. Los valores tienen el formato form-urlencoded (content type = "application/x-www-form-urlencoded").
Cuando el software intermedio OIDC redirige al punto de conexión de autorización, la dirección URL de redireccionamiento incluye todos los parámetros de cadena de consulta necesarios para OIDC. Para el flujo híbrido:
- client_id. Este valor se establece en la opción ClientId.
- scope = "openid profile", lo que significa que es una solicitud de OIDC y que se busca el perfil del usuario.
- response_type = "code id_token". Esto especifica el flujo híbrido.
- response_mode = "form_post". Esto especifica la respuesta de envío de formulario.
Para especificar un flujo diferente, establezca la propiedad ResponseType en las opciones.
app.AddAuthentication().AddOpenIdConnect(options =>
{
options.ResponseType = "code"; // Authorization code flow
// Other options
}
Código de ejemplo