Autenticación por AAD en ASP.NET Core

Este es un post introductorio, de una serie de posts, donde veremos como podemos integrar ASP.NET Core y Azure Active Directory (AAD). En este primer escenario el objetivo es tener una aplicación web, donde se requiera hacer login contra AAD para autenticarse.

Nota: El post está basado en la RC1 de ASP.NET Core… Lo digo porque bueno, a saber que romperán mejorarán en futuras versiones, pues igual algo cambia 🙂

Paso 1 – Configurar Azure Active Directory

Antes de poder usar AAD como proveedor de autenticación necesitas configurar una aplicación en AAD. Para ello, debes entrar en el portal de azure. Actualmente parece que la configuración de AAD está solo en el portal viejo (https://manage.windowsazure.com), de hecho si desde el nuevo te redirige al viejo si vas a la sección de “Active Directory”. Supongo que algún día lo meterán en el nuevo. O no, a saber, la verdad es que el ritmo de novedades de Azure es tal que los desarrolladores del portal nuevo deben ir de culo :p`

Lo dicho, una vez estés en la configuración del AAD debes ir a la pestaña “APPLICATIONS” y dar de alta la nueva aplicación, pulsando el botón de “ADD” de la parte inferior y seleccionar la opción “Add an application my organization is developing”. Te aparecerá una pantalla como la siguiente:

image

Seleccionamos la opción de “Web Application” y vamos al siguiente paso, donde solo nos pregunta dos cosas:

  1. SIGN-ON URL: Esa es la URL de inicio de sesión. Sirve que coloques directamente la URL inicial de la aplicación. Puedes usar localhost si estás desarrollando (luego se puede modificar, por supuesto). Así, si tienes la aplicación corriendo en localhost:5000 puedes entrar http://localhost:5000 y listos. Si entras cualquier otro valor verás que la autenticación sigue funcionando, pero puedes tener problemas en escenarios más avanzados, así que entra la URL de tu aplicación.
  2. APP ID URI: Esa es una URL que debe ser única. Lo que se suele hacer es usar una URL con tu tenant de Azure (*.onmicrosoft.com) junto con el nombre de la aplicación (p.ej. http://eiximenis.onmicrosoft.com/DemoGeeks).

Una vez has entrado esos dos valores se creará la aplicación, pero todavía no hemos terminado. Debes ir a la pestaña CONFIGURATION a entrar un valor adicional, la “REPLY URL”. Esa sí que es importante, es donde AAD se redirigirá después del proceso de login. En esta sí que debe estar ejecutándose nuestra aplicación. Se puede cambiar cuando quieras, y no hay problema en usar localhost, así que si tienes la aplicación ejecutandose en localhost:5000, entra algo como http://localhost:5000/aad. No debes entrar la raíz, así que debes usar una ruta (en este caso he usado /aad), cual es esa ruta, da igual (siempre y cuando no la quieras para nada más, puesto que el middleware de autenticación la va a gestionar).

Ahora debes copiar el “CLIENT ID” que aparece en esta misma pantalla de configuración (es un guid) puesto que lo vas a necesitar para configurar la aplicación:

image

Ahora sí, que hemos terminado con AAD. El siguiente paso es usar configurar la aplicación ASP.NET Core para que use AAD como proveedor de autenticación.

Paso 2: Configurar la aplicación ASP.NET Core

Lo primero es agregar la configuración necesaria. Para ello, lo más sencillo es crear un fichero json nuevo con el siguiente contenido:

  1.   “AzureAd”: {
  2.     “AadInstance”: “https://login.microsoftonline.com/{0}”,
  3.     “CallbackPath”: “/aad”,     // Este path DEBE ser el mismo que indicamos en el portal
  4.     “ClientId”: “xxxx-xxxxx-xxxx”,    // El client ID de Azure
  5.     “PostLogoutRedirectUri”: “https://localhost:5000/”,      // Coloca aqu la URL de la app
  6.     “Tenant”: “eiximenis.onmicrosoft.com” // Tu tenant de azure
  7.   }
  8. }

Nota: Recuerdas que en la configuración de AAD comenté que el valor de “REPLY URL”, no podía ser la raíz? Pues igualmente el valor de CallbackPath no puede ser “/”. Si es así recibirás un 500 sin más información.

Guardalo con cualquier nombre (p. ej. AzureAd.json) y agrégalo a la configuración en el Startup.cs:

  1. var builder = new ConfigurationBuilder()
  2.     .SetBasePath(appEnv.ApplicationBasePath)
  3.     .AddJsonFile(“appsettings.json”)
  4.     .AddJsonFile(“AzureAd.json”);

Bueno, ya tenemos la configuración cargada, vamos a configurar el middleware. Lo primero, claro, va a ser agregarlo al project.json. Agrega esas dos entradas a la sección “dependences”:

  1. “Microsoft.AspNet.Authentication.OpenIdConnect”: “1.0.0-rc1-final”,
  2. “Microsoft.AspNet.Authentication.Cookies”: “1.0.0-rc1-final”,

Necesitamos el middleware de autenticación de Cookies y el de OpenId (el primero es un requisito del segundo).

El siguiente paso es agregar ambos middlewares en el pipeline de la aplicación (en el método Configure de Startup.cs):

  1. app.UseCookieAuthentication(new CookieAuthenticationOptions()
  2. {
  3.     AutomaticAuthenticate = true,
  4.     AutomaticChallenge = true,
  5.     AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme
  6. });
  7. app.UseOpenIdConnectAuthentication(options => {
  8.     options.AutomaticChallenge = true;
  9.     options.ClientId = Configuration.Get(“AzureAd:ClientId”, “”);
  10.     options.CallbackPath = Configuration.Get(“AzureAd:CallbackPath”, “”);
  11.     options.Authority = String.Format(Configuration.Get(“AzureAd:AadInstance”, “”), Configuration.Get(“AzureAd:Tenant”, “”));
  12.     options.PostLogoutRedirectUri = Configuration.Get(“AzureAd:PostLogoutRedirectUri”, “”);
  13.     options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
  14. });

Importante: El valor de SignInScheme de las opciones de OpenId debe corresponderse con el valor de AuthenticationScheme de Cookies. Si no lo haces obtendrás un error después del login:
NotSupportedException: Specified method is not supported.
Microsoft.AspNet.Authentication.RemoteAuthenticationHandler`1.HandleSignInAsync(SignInContext context)

Observa que colocamos la opción AutomaticChallenge a true, eso es porque si la autenticación es necesaria (p. ej. un [Authorize]) en lugar de devolver directamente un 401, se lance el proceso de autenticació contra AAD. Si esa propiedad vale false entonces debemos lanzar este proceso manualmente.

El último paso es colocar un [Authorize] en algún controlador y navegar a este controlador. En este momento te debería saltar a la página de autenticación de AAD donde debes entrar tus credenciales. Si esas son correctas, AAD enviará el token a la dirección que pusimos en “REPLY URL” en Azure… y como hemos configurado el valor del CallbackPath para que sea esa misma dirección, el middleware de autenticación recojerá ese token y dejará las cookies necesarias. Luego el middleware de autenticación por cookies autenticará nuestra petición y accederemos a la acción (de ahí que uno sea requisito del otro). Una vez tenemos la cookie, por supuesto, ya no necesitamos posteriores accesos a Azure AD para autenticarnos.

Y evidentemente en la propiedad User, tendremos un ClaimsPrincipal con una ClaimsIdentity conteniendo los claims enviados por Azure AD:

image

Bueno, lo dejamos aquí en este post. En posts sucesivos iremos viendo otros escenarios de autenticación y operaciones más “avanzadas”

Saludos!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *