Autorización de usuarios y consideraciones de planificación relacionadas para su implementación de B2B IAM.
Comencemos dando un paso atrás para hablar del control de acceso. No existe una definición única y clara de control de acceso en la industria, pero si dedica algo de tiempo a investigar y leer, verá que la mayoría de las fuentes autorizadas coinciden en que es el concepto general que engloba la autenticación, la autorización, el consentimiento y la aplicación de políticas para garantizar que solo las personas y los servicios adecuados tengan acceso a sus aplicaciones y API.A continuación, veamos más de cerca las diferencias entre autenticación, autorización, consentimiento y aplicación de políticas. Su inquilino de Auth0 (su ) suele ser responsable de la autenticación y el consentimiento, así como de parte o de la totalidad de la autorización y la aplicación de políticas. Además, la propia aplicación o API casi siempre es el principal responsable de hacer cumplir las políticas, especialmente cuando se requiere acceso contextual:
Autenticación: el proceso de determinar si un principal (un usuario o una aplicación) es quien o lo que dice ser.
Autorización: el proceso de determinar qué está permitido, en función del principal, de los permisos que se le han concedido y/o del conjunto de criterios de acceso específicos del contexto.
Consentimiento: los permisos que el usuario () ha autorizado a una aplicación a realizar en su nombre. Por lo general, este es un requisito de la autorización delegada. El usuario debe dar permiso al cliente para acceder a los datos del usuario en un sistema distinto.
Aplicación de políticas: el acto de hacer cumplir las políticas de la aplicación o API, rechazando o permitiendo el acceso en función de la información de autenticación y/o autorización de un usuario.
En general, solemos agrupar los distintos tipos de control de acceso en tres categorías diferenciadas para que sea más fácil entender a) qué actor es responsable de almacenar la información, b) qué actor es responsable de tomar decisiones y c) cuál es responsable de aplicar las restricciones.
La primera categoría es aquella en la que se concede o se deniega el acceso a una aplicación o API en su totalidad. Tanto los datos necesarios para aplicar esto como el proceso de aplicación suelen definirse en el contexto del Servidor de autorización. Por ejemplo, mediante el uso de app_metadata asociado a un usuario y una Action definida en su inquilino de Auth0.
La segunda categoría es aquella en la que se concede o se deniega el acceso a un subconjunto específico de la funcionalidad de la aplicación o API. Los datos necesarios para aplicar esto suelen almacenarse en el Servidor de autorización. Por ejemplo, mediante el uso de app_metadata en un usuario de su inquilino de Auth0, mientras que el proceso de aplicación se realiza en la propia aplicación o API. En este escenario, los datos suelen comunicarse como uno o más claims personalizados en un token de id o access.
La tercera categoría es aquella en la que se concede o se deniega el acceso en función de aquello sobre lo que el principal (sujeto) puede operar dentro del contexto de una aplicación o API. Tanto los datos necesarios para aplicar esto como el proceso de aplicación suelen definirse en el contexto de la aplicación o API. En este escenario, los datos comunicados como uno o más claims personalizados en un token de id o access pueden consumirse con o sin datos de una fuente externa distinta de Auth0.
Además, los mecanismos de control de acceso basado en roles (RBAC) y control de acceso basado en atributos (ABAC) pueden aplicarse en cualquiera de las categorías de control de acceso descritas anteriormente. Sea cual sea su caso de uso, hay una serie de aspectos que querrá tener en cuenta al evaluar la funcionalidad y el flujo de trabajo que necesita:
¿Hay escenarios en los que debería rechazarse el acceso a una aplicación o API completa?
¿Va a ofrecer APIs a las que puedan acceder aplicaciones de terceros?
¿Sus APIs también serán accedidas por sus propias aplicaciones (de primera parte)?
¿Su aplicación llamará a una API de terceros?
¿Sus aplicaciones y/o APIs deben aplicar control de acceso en función de los claims del usuario?
¿Qué ocurre si necesito saber a qué organización está asociado un o un ?
Auth0 admite restringir el acceso a aplicaciones o APIs en función de determinadas condiciones. En algunos casos, puede que desee crear una Action que devuelva un UnauthorizedError cuando, por ejemplo, un usuario intente acceder a una aplicación o una API en un momento no permitido (como se describe en este ejemplo) o si el usuario no tiene los claims adecuados en su app_metadata. En el caso de una aplicación que use OpenID Connect (OIDC), esto impediría la emisión del ID Token utilizado para autorizar el acceso. Del mismo modo, en el caso de una API, podría impedirse la emisión de cualquier Token de acceso de OAuth2 (utilizado al llamar a la API), como se describe en este ejemplo.
En general, hemos comprobado que OIDC es el protocolo estándar del sector más utilizado por los clientes de Auth0 para la autenticación en sus aplicaciones. También hemos observado que, aunque OAuth2 se creó como un protocolo de delegación, se usa habitualmente en aplicaciones de primera parte cuando hay una API que no comparte una sesión con la aplicación.
Auth0 también puede proporcionar la información necesaria para que una aplicación pueda aplicar restricciones. Para la integración a nivel de aplicación, Auth0 le permite añadir claims personalizados a un ID Token, que su aplicación puede verificar y usar después para aplicar la policy. En este caso, deberá decidir qué información necesita para que su aplicación pueda tomar decisiones de aplicación. Si necesita tomar decisiones en una API en lugar de en su aplicación, probablemente tendrá que usar un Token de acceso en lugar de un token de ID. Siga leyendo para obtener más información.
Al decidir qué datos incluir en su token de ID y/o token de acceso, tenga en cuenta el tamaño del token, especialmente si lo pasa en la URL. Aunque no pase tokens en la URL, también deberá considerar el riesgo de exponer PII (información de identificación personal) sensible. La información del token no está cifrada, así que, aunque por lo general no supone un problema de seguridad que se filtre un token de ID, puede convertirse en un problema de privacidad según los datos incluidos en el token.
Para la integración a nivel de API, Auth0 admite tanto claims personalizados como la reconfiguración del scope, ambas en el contexto de un Token de acceso. De nuevo, deberá decidir qué información será necesaria para que su API tome decisiones de acceso, y su API deberá aplicar esto validando el contenido del Token de acceso.
Al decidir si debe usar permisos mediante claims personalizados o alcances, asegúrese de comprender la naturaleza y el propósito de los alcances. Hay una buena entrada de blog sobre ello, fácil de leer y útil para aclarar el tema.
En escenarios con varias organizaciones, a menudo puede ser importante saber a qué organización se aplica un token de acceso (o incluso un token de ID). Seguir cuidadosamente las prácticas recomendadas puede ahorrarle tiempo y esfuerzo.
En este escenario, tu inquilino de Auth0 proporciona un token como indicador de acceso autorizado a una aplicación. En el caso de las aplicaciones que utilizan OpenID Connect (OIDC), el protocolo estándar del sector que suele usarse con más frecuencia en aplicaciones de cara al cliente, se trataría de un ID Token expresado como un JWT.
Con la extensibilidad de Actions, Auth0 le permite agregar fácilmente claims personalizados a un ID Token en función de, por ejemplo, el contenido de los metadatos de un usuario. Después, su aplicación puede verificar en el ID Token los claims necesarios y permitir o denegar el acceso a determinadas funcionalidades, según corresponda. Tenga en cuenta que, aunque el proceso para agregar claims personalizados mediante Actions es sencillo, Actions es flexible y le permite escribir código personalizado que podría tener efectos negativos.
Si está considerando agregar claims personalizados, le recomendamos almacenar cualquier dato de control de acceso que necesite incluir en los claims como parte del app_metadata del usuario. En primer lugar, esto evita tener que llamar a una API externa para obtener los datos, lo que puede afectar negativamente al rendimiento y la escalabilidad de la secuencia de inicio de sesión. En segundo lugar, app_metadatano puede ser modificado por un usuario, por lo que este no puede eludir directamente ninguna restricción de control de acceso modificando sus propios metadatos. Recuerde también consultar nuestra guía de prácticas recomendadas sobre metadatos.
Si está creando distintas instancias de su aplicación para las organizaciones de sus clientes, una práctica habitual es crear un claim personalizado en su token de ID para representar la organización del usuario. Por ejemplo:
Los alcances de OIDC suelen utilizarse para que una aplicación obtenga el consentimiento para acceder de forma autorizada a los datos de un usuario durante la autenticación. Cada uno de los alcances predefinidos devuelve el conjunto de claims estándar cuando corresponde, tal como se describe en la especificación de OIDC. Los alcances que solicita una aplicación dependen de los atributos del usuario que esta necesite. Una vez que el usuario autoriza los alcances solicitados, los claims se devuelven en el ID Token y también están disponibles a través del endpoint /userinfo.
En este escenario, su inquilino de Auth0 puede proporcionar un OAuth2 token de acceso, normalmente expresado como un JWT, que su API puede usar para restringir el acceso a determinados actores. Además, Auth0 ofrece compatibilidad con lo que, en términos generales, se conoce como aplicaciones de primera parte y de terceros.Actuando como servidor de autorización, y con el consentimiento del usuario (el propietario del recurso), su inquilino de Auth0 puede usarse para proporcionar un token de acceso —normalmente expresado como un JWT— a una aplicación (cliente) para que pueda acceder a recursos protegidos alojados en un en nombre del propietario del recurso. El token de acceso emitido normalmente se envía como token Bearer en el encabezado HTTP Authorization que se manda a una API.Tanto si tiene una sola API como si tiene un conjunto de APIs de microservicios relacionadas lógicamente, puede aprovechar los tokens de acceso que proporciona Auth0 para proteger el acceso a sus servicios. Aunque configurarlo es relativamente sencillo en el Auth0 Dashboard o mediante la Auth0 Management API, es importante revisar los distintos escenarios de aplicación y diseños de API para determinar la mejor arquitectura para su sistema.
Los tokens de acceso de OAuth2 están diseñados principalmente para proteger APIs expuestas públicamente; cuando se expresan como un JWT, un token de acceso es una entidad autocontenida que puede verificarse sin necesidad de realizar ninguna llamada adicional a una API de terceros. Si sus APIs no entran en esta categoría, es decir, si forman parte de una aplicación en sí mismas (por ejemplo, si solo esa aplicación las invoca) o están detrás de su cortafuegos, protegerlas con tokens puede ser innecesariamente complejo, y su flujo de trabajo actual basado en cookies (entre otros) puede ser suficiente.
OAuth2 se diseñó específicamente pensando en el acceso de terceros. Por ejemplo, un escenario posible es que un usuario (propietario del recurso) quiera usar una aplicación (un cliente) que no pertenece a la misma organización que el servicio que proporciona los datos del usuario (el servidor de recursos). En este caso, cuando la aplicación necesita acceder a datos que pertenecen al usuario, redirige a la organización donde residen los datos del usuario, que a su vez autentica al usuario y luego le solicita permiso para que la aplicación acceda a sus datos. Esta solicitud de permiso se denomina consentimiento y es una parte fundamental de lo que implica ofrecer compatibilidad con aplicaciones de terceros. Si planea integrar aplicaciones de terceros, es importante que las marque como de terceros desde el principio para que Auth0 gestione la solicitud de consentimiento del usuario.Por otro lado, si su organización es propietaria de las aplicaciones, de los propios datos del usuario y de las APIs a través de las cuales se accede a esos datos, entonces normalmente no se requiere consentimiento, ya que todas las interacciones son de primera parte. Si solo está creando aplicaciones de primera parte, puede asegurarse de no presentar a sus usuarios ninguna pantalla de consentimiento innecesaria permitiendo omitir el consentimiento del usuario como parte de cualquier definición de servicio de recursos.
Aunque puede configurar sus aplicaciones como de primera parte y posteriormente configurar sus APIs para permitir que los clientes de primera parte omitan el consentimiento, si está usando localhost Auth0 no puede verificar que la aplicación sea realmente una aplicación de primera parte, por lo que de todos modos se solicitará el consentimiento a sus usuarios. Para evitar esta limitación, cuando haga pruebas en su máquina local durante el desarrollo, cree un nombre de host local falso y úselo en su lugar.
Al igual que con los ID Tokens, puedes agregar claims personalizadas a los tokens de acceso mediante la extensibilidad de Actions de Auth0. Una vez agregadas, tu API puede verificar que un token de acceso contenga las claims necesarias y permitir o impedir el acceso a determinadas funcionalidades, según corresponda.
Si estás pensando en agregar claims personalizadas, te recomendamos almacenar en el app_metadata del usuario cualquier dato de control de acceso que necesites incluir en las claims. En primer lugar, esto evita tener que llamar a una API externa para recuperar esos datos, lo que puede afectar negativamente al rendimiento y la escalabilidad. En segundo lugar, un usuario no puede modificar app_metadata, por lo que no puede eludir directamente ninguna restricción de control de acceso modificando sus propios metadatos. Recuerda también consultar nuestra guía de prácticas recomendadas para metadatos.
Los alcances de OAuth2 se usan normalmente como el mecanismo mediante el cual una API puede determinar qué acciones se pueden realizar en nombre de un usuario. Los alcances se pueden agregar por API para definir permisos de acceso específicos en el o a través de la ). Los alcances también se pueden manipular mediante la extensibilidad de Auth0 (por ejemplo, con una Action, como en este ejemplo). Los alcances que una aplicación solicita para acceder a una API deben depender de la funcionalidad para la que la aplicación necesite que el usuario le conceda permiso. Una vez autorizados los alcances solicitados, se devolverán en el Token de acceso, que posteriormente podrá ser verificado por esa API. Un buen ejemplo de esto es cuando inicia sesión en una aplicación que usa un proveedor social para el inicio de sesión: la API del proveedor social requiere que la aplicación especifique si el usuario quiere que la aplicación publique contenido en su nombre. Esto permite al usuario aceptar o denegar esta solicitud. Este ejemplo demuestra cómo el usuario delega permisos en la aplicación, lo cual es diferente de que la API restrinja el acceso en función del rol de un usuario, y debe manejarse de otra manera.
Aunque tiene la capacidad de manipular por completo los alcances del Token de acceso mediante la extensibilidad de Auth0, como práctica recomendada de seguridad, solo debe eliminar los alcances que no estén autorizados y abstenerse de agregar alcances que no se hayan solicitado.
Aunque los alcances suelen usarse como una forma de aplicar permisos de acceso para un usuario, hay situaciones en las que puede resultar complicado usarlos de esta manera. Por lo tanto, le recomendamos que use los alcances para su propósito previsto (es decir, delegar permisos a una aplicación) y que use claims personalizados para sus escenarios de control de acceso basado en roles o de otro tipo.
La autorización granular le permite conceder a usuarios individuales acceso a un recurso u objeto específico en función de lo siguiente:
El rol de un usuario dentro de una organización, como editor o admin
Un atributo del usuario o del objeto, como manager para un usuario o marketing para un objeto
Una relación entre un usuario y un objeto, como cuando un usuario con acceso de visualización a una carpeta principal también tiene acceso de visualización a la carpeta secundaria
Con , puede crear un modelo de autorización para definir qué relaciones determinan el acceso del usuario.
Auth0 ofrece soporte integrado para el control de acceso basado en roles (RBAC). RBAC consiste en asignar permisos a los usuarios según su rol dentro de una organización y proporciona un control de acceso más sencillo al ofrecer un enfoque más fácil de administrar y menos propenso a errores.La funcionalidad básica de RBAC puede usarse en muchos escenarios con múltiples organizaciones. Consulta Datos de la organización en un token de acceso para obtener más información sobre cómo garantizar que tu configuración pueda satisfacer tus necesidades de RBAC.
Hay muchos escenarios en los que una aplicación sin ninguna sesión interactiva de usuario necesita obtener un token de acceso para llamar a una API. En estos casos, debe autenticar al cliente en lugar del usuario, y 2 ofrece el tipo de concesión de credenciales de cliente, lo que facilita este proceso. Algunos ejemplos habituales en los que esto es necesario son:
Una tarea cron u otro servicio que necesite comunicarse con su API (por ejemplo, cuando se debe generar un informe diario y enviarlo por correo electrónico a un administrador).
Una API independiente que admite acceso privilegiado (por ejemplo, la API no se expone directamente a los usuarios, sino solo a un backend).
En determinadas arquitecturas de microservicios, en las que algunas capas de API necesitan comunicarse con otras capas de API sin la intervención de un usuario, o después de que haya expirado el token de un usuario.
Una API privilegiada que puede necesitar invocarse antes de que un usuario se autentique (es decir, desde una Action o un script de base de datos personalizado en su inquilino de Auth0)
Tradicionalmente, se creaba una “cuenta de servicio” especial para cubrir estos escenarios: un usuario con username y contraseña configurado para servicios que admitían casos de uso no interactivos. Ese enfoque ya no se recomienda por muchas razones, y la práctica recomendada actual es usar OAuth 2.0 Client Credentials Grant en estas situaciones.
Si en su sistema tiene una API separada de su aplicación que da soporte a una aplicación con múltiples organizaciones, es importante restringir las operaciones únicamente a la organización para la que se generó el token. Para ello, el token de acceso debe incluir algún tipo de información que indique a la API para qué organización se emitió. Esto puede hacerse de distintas maneras, según las respuestas a unas preguntas sencillas:
¿Los usuarios finales de esta organización podrían pertenecer a más de una organización, o cada usuario final está limitado a una organización específica?
¿Permitirá acceso de máquina a máquina (M2M) a su API?
Si permite acceso de máquina a máquina (M2M) a su API, ¿tendrá desarrolladores que necesiten un único ID de cliente y secreto para acceder a varias organizaciones (pero no a todas)?
¿Permitirá la creación de aplicaciones de terceros que requieran consentimiento?
Si los usuarios finales están limitados a una sola organización y no permitirá acceso M2M a su API o tendrá un /secreto independiente para cada organización que necesite acceso y no permitirá aplicaciones de terceros que requieran consentimiento, entonces el enfoque más sencillo es crear un claim personalizado en el token de acceso mediante Actions para los tokens basados en usuario y mediante el hook de credenciales de cliente para llamadas M2M. Puede almacenar el nombre de la organización en los metadatos del cliente y extraerlo desde Actions o hooks para incluirlo en access_token como un claim personalizado. RBAC también funcionará de forma predeterminada con este enfoque, siempre que cada usuario final solo pueda pertenecer a una organización.Si los usuarios finales pueden pertenecer a más de una organización o podría dar a un solo desarrollador un ID de cliente y secreto para llamadas M2M a más de una organización, el mejor enfoque es crear una independiente (una instancia de API independiente en su inquilino de Auth0) para cada organización. Esto le ofrece varias ventajas:
En primer lugar, le permite pasar la audiencia como un parámetro de primer nivel a Auth0 sin tener que crear un parámetro personalizado. La ventaja es que Auth0 ayudará a garantizar la presencia de la audiencia y la pasará a sus Actions. También garantizará que un Token de actualización emitido solo funcione para la audiencia específica para la que se emitió originalmente.
Le permite restringir las concesiones de cliente únicamente a organizaciones específicas de forma predeterminada. La alternativa es crear un hook de credenciales de cliente más complejo para intentar recuperar las restricciones desde otro lugar, y además requerir una forma mucho más compleja y potencialmente problemática de indicar en la llamada de credenciales de cliente para qué organización debe emitirse el token de acceso.
Esto también le permite usar la funcionalidad principal de RBAC de Auth0 y garantizar que los usuarios finales que tienen acceso a más de una organización puedan tener potencialmente un rol distinto para cada organización.
Ofrecemos una guía de planificación en formato PDF que puede descargar y consultar para obtener más detalles sobre nuestras estrategias recomendadas.Guía de planificación del proyecto de B2B IAM
Arquitectura de múltiples organizaciones (multitenencia)
Muchas plataformas B2B implementan algún tipo de aislamiento o de marca para la organización de sus clientes, y esto puede añadir complejidad a cualquier sistema de gestión de identidades y accesos (IAM). Si este es tu caso, te recomendamos dedicar algo de tiempo a leer nuestra guía y recomendaciones de buenas prácticas para este tipo de entorno.Arquitectura de múltiples organizaciones