Gestiona y usa roles en tu aplicación web con Azure Active Directory

En el post anterior te hablé de cómo autenticar a tus usuarios en tus aplicaciones web, pero normalmente solo con esto no es suficiente. En este post quiero hablarte de cómo usar roles de la misma forma que los has usado hasta ahora utilizando Azure Active Directory.

Lo primero que tienes que hacer es definir los roles que quieres asignar a tus usuarios. Para ello, necesitas ir al portal antiguo de Microsoft Azure y acceder a la aplicación que creaste. En ella debes descargarse el manifiesto de la aplicación, a través del botón que tienes en el menú inferior.

AAD – AADemo app – Download Manifest

El manifiesto es un archivo JSON que contiene toda la configuración de la aplicación asociada a tu directorio en Azure. Al principio del archivo puedes ver que existe una propiedad llamada appRoles, que en este momento es un array vacío.

{
  "appId": "1979618f-c854-489b-b88c-0582a68d1016",
  "appRoles": [],
  "availableToOtherTenants": false,
  "displayName": "AADDemo",

En este array puedes incluir tantos roles como necesite tu aplicación. Cada uno de ellos debe tener el siguiente formato:

"appRoles": [
    {
      "allowedMemberTypes": [
        "User"
      ],
      "description": "Admins can change all settings and do all  operations",
      "displayName": "Admins",
      "id": "82d5052f-ad50-4c05-abc2-4269af88c157",
      "isEnabled": true,
      "value": "admin"
    },
    {
      "allowedMemberTypes": [
        "User"
      ],
      "description": "Staff can manage their stuff",
      "displayName": "Staff",
      "id": "7a30824e-dabe-4904-a026-fcd2c51acea4",
      "isEnabled": true,
      "value": "staff"
    }
  ],
  • allowedMemberTypes: los tipos de usuario de Azure Active Directory que pueden pertenecer a este rol.
  • description: descripción del role.
  • Display name: el nombre a mostrar del rol en el combo de selección.
  • id: un GUID que debes generar para asignarlo como id del rol.
  • isEnabled: por lo general este valor es true pero es posible que quieras desactivar el rol en algún momento.
  • value: este es el valor con el que trabajarás en tus aplicaciones.

Una vez que hayas añadido los roles que necesitas, debes volver a subir el archivo JSON a través del portal.

Una vez hecho esto ya podrás asignar tus usuarios a los roles que creaste desde la pestaña Users de la aplicación.

AAD – Application – Users – Assign

Asigna un par de usuarios a los dos roles que has creado, a Admins y a Staff, para poder comprobar que todo funciona correctamente.

Ahora sólo queda adaptar tu código para que puedas hacer uso de los roles de los usuarios una vez autenticados. En el archivo App_Start/Startup.Auth.cs hay que modificar la configuración del objeto OpenIdConnectAuthenticationOptions, indicando a través de la propiedad TokenValidationParameters que quieres recuperar los roles:

using System;
using System.Configuration;
using System.IdentityModel.Claims;
using System.Threading.Tasks;
using System.Web;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Owin;
using AADDemo.Models;


namespace AADDemo
{
    public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
        private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
        private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];

        public static readonly string Authority = aadInstance + tenantId;

        // This is the resource ID of the AAD Graph API.  We'll need this to request a token to call the Graph API.
        string graphResourceId = "https://graph.windows.net";

        public void ConfigureAuth(IAppBuilder app)
        {
            ApplicationDbContext db = new ApplicationDbContext();

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = Authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
                    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                    {
                        ValidateIssuer = false,
                        RoleClaimType = "roles"
                    },
                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                        AuthorizationCodeReceived = (context) =>
                        {
                            var code = context.Code;
                            ClientCredential credential = new ClientCredential(clientId, appKey);
                            string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                            AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
                            AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                            code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);

                            return Task.FromResult(0);
                        }
                    }
                });
        }
    }
}

Por último ya solo queda usar dichos roles en aquellos Controlladores, en el caso de ASP.NET MVC, donde quieras que tengan acceso unos u otros.

using System.Web.Mvc;

namespace AADDemo.Controllers
{
    [Authorize(Roles = "admin,staff")]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

AAD – AADDemo – Checking roles

¡Saludos!