Como hemos visto en las anteriores entregas de esta serie de posts, WSO2 Identity Server (IS) nos permite gestionar e integrar diferentes tipos de identidades, además de dotar de seguridad a las aplicaciones que trabajan con estos universos de usuarios.
En este artículo vamos a trabajar en ver cómo es la definición y uso de políticas XACML en Identity Server. XACML es un lenguaje basado en XML que se utiliza, entre otras cosas, para implementar políticas de autorización de grano fino.
En esta entrada nos vamos a apoyar en la configuración que realizamos en el primer artículo de la serie Aprendiendo WSO2 Identity Server (I): Single Sign-On
¿Qué nos aporta XACML?
Una de las principales ventajas de utilizar políticas XACML es que nos permite, de manera estándar, cambiar la lógica de autorización a un recurso dinámicamente sin tener que realizar ningún cambio programático.
XACML soporta el paradigma Attribute Based Access Control (ABAC) por el cual el acceso a un elemento protegido puede ser gestionado por políticas que combinan el uso de atributos del usuario, del recurso y del entorno y también soporta el paradigma Role Based Access Control (RBAC) que gestiona el acceso a los recursos en función del rol del usuario. RBAC es un subconjunto de ABAC.
En WSO2 IS podemos combinar ambos paradigmas para crear políticas personalizadas que permitan gestionar autorizaciones de grado fino con expresiones descritas en lenguaje natural:
- ABAC: La página de acceso restringido de la aplicación sólo podrá ser accesible en horario laboral.
- RBAC: La página de acceso restringido de la aplicación sólo podrá ser accesible por usuarios de tipo empleado o administrador.
La siguiente expresión aúna el uso combinado de ambos paradigmas:
"La página de acceso restringido de la aplicación sólo podrá ser accesible en horario laboral y sólo por usuarios de tipo empleado o administrador".
En este caso se usarían en la política los atributos de tipo:
- Usuario (subject): Roles de usuario habilitados, administrador y empleado.
- Entorno (environment): Horario laboral.
La acción que se llevaría a cabo tras la evaluación de la política es el acceso o prohibición de ver la página restringida.
Componentes participantes en la Arquitectura XACML
La arquitectura de referencia XACML se basa en los siguientes componentes:
- Policy Enforcement Point (PEP): Componente que gestiona el acceso a un recurso, solicita la autorización mediante una petición XACML al PDP y actúa en función de la decisión tomada por este.
- Policy Decision Point (PDP): Componente que evalúa la solicitud de autorización en base a las políticas configuradas que apliquen a dicha solicitud.
- Policy Information Point (PIP): Componente que facilita al PDP los atributos que no estén incluidos en la petición de autenticación generada por el PEP y que sean necesarios para evaluar las políticas contra la solicitud.
- Policy Administration Point (PAP): Componente que permite crear y gestionar políticas y conjuntos de las mismas.
Creamos la política
Como se indicó anteriormente, las políticas se gestionan en el Policy Administration Point (PAP), en WSO2 Identity Server esta configuración se realiza en el apartado Entitlement - PAP - Policy Administration.
Por defecto, Identity Server incluye un conjunto de plantillas de políticas XACML que cubren los principales casos de uso con los que nos podemos encontrar. Es interesante antes de empezar a escribir una nueva política revisar si se puede utilizar una de estas plantillas. El conjunto de plantillas out-of-the-box sería el siguiente:
- authn scope based policy template
- authn time and user claim based policy template
- provisioning user claim based policy template
- authn time based policy template
- authn user claim based policy template
- provisioning time based policy template
- authn role based policy template
- authn time and role based policy template
- provisioning role based policy template
- authn user claim based policy template
- provisioning time and role based policy template
- authn time and scope based policy template
- provisioning time and user claim based policy template
También ofrece una serie de editores para crear una política XACML, basándonos o no en una de las plantillas:
- Simple Policy Editor
- Basic Policy Editor
- Standard Policy Editor
- Policy Set Editor
- Import Existing Policy
- Write Policy in XML
En nuestro caso hay una plantilla que se ajusta a nuestras necesidades (authn time and role based policy template) por lo que podemos utilizar el editor XML (Write Policy in XML) para modificarla y crear una nueva política que se ajuste a la condición:
"La página de acceso restringido de la aplicación sólo podrá ser accesible en horario laboral y sólo por usuarios de tipo empleado o administrador".
La política quedaría así:
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="travelocity_authn_time_and_role_based_policy_template" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
<Description>This policy template provides ability to authorize users to a given service provider(defined by SP_NAME) in the authentication flow based on the Roles of the user (defined by ROLE_1 and ROLE_2) and the time of the day (eg. between 09:00:00 to 17:00:00). Users who have at least one of the given roles will be able to login within the given time. Any other requests will be denied.</Description>
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">travelocitySP</AttributeValue>
<AttributeDesignator AttributeId="http://wso2.org/identity/sp/sp-name" Category="http://wso2.org/identity/sp" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Match>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">authenticate</AttributeValue>
<AttributeDesignator AttributeId="http://wso2.org/identity/identity-action/action-name" Category="http://wso2.org/identity/identity-action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
</Target>
<Rule Effect="Permit" RuleId="permit_by_roles_and_time">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" DataType="http://www.w3.org/2001/XMLSchema#time" MustBePresent="true"></AttributeDesignator>
</Apply>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">10:00:00</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">17:00:00</AttributeValue>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">EMPLOYEES/employee</AttributeValue>
<AttributeDesignator AttributeId="http://wso2.org/claims/role" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue>
<AttributeDesignator AttributeId="http://wso2.org/claims/role" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Apply>
</Apply>
</Apply>
</Condition>
</Rule>
<Rule Effect="Deny" RuleId="deny_others"></Rule>
</Policy>
En la política creada podemos destacar la siguiente información:
Valor | Detalle | |
---|---|---|
PolicyId | travelocity_authn_time_and_role_based_policy_template | Es el identificador de la política, es un campo libre |
sp-name | travelocitySP | Service Provider sobre el que aplica la política, en nuestro campo aplicará sobre Travelocity |
action-name | authenticate | Acción a realizar por la política, autenticar en este caso |
Rule | Effect="Permit" RuleId="permit_by_roles_and_time | Regla en la que se definen las condiciones para validar la petición |
Rule | Effect="Deny" RuleId="deny_others | Regla en la que se definen las condiciones para no validar la petición |
Current time | 10:00:00 - 17:00:00 | Atributo de tipo environment a comprobar, identifica el intervalo horario donde se permitirá el acceso |
Role | EMPLOYEES/employee / admin | Atributo de tipo subject a comprobar, identifica los roles que pueden acceder |
Una vez creada la política ya estaría disponible para su utilización en el Policy Administration Point:
En este punto ya podríamos proceder a publicarla en el Policy Decision Point mediante la opción Publish To My PDP:
Al ser la primera vez que publicamos esta política podríamos dejar todas las opciones por defecto, si se tratara de una modificación sobre una política deberíamos elegir la opción a realizar:
- Select policy publishing action: Add policy
- Select policy Enable/Disable: Publish as enabled policy
- Select policy version: Use current policy version
- Select policy order: Use default policy order
Una vez publicada la política en la sección PDP - Policy View vemos la política en disposición de ser ejecutada.
Si tuviéramos más políticas publicadas deberíamos configurar el orden de ejecución de cada una de ellas.
Por último, hemos de recordar que para que el Service Provider ejecute la política asociada a él debe tener marcada la opción Enable Authorization en el apartado Local & Outbound Authentication Configuration.
¡Probemos la política!
Una vez tenemos la política publicada podemos ver su funcionamiento con nuestros viejos conocidos Travelocity y Avis, para ello vamos a utilizar los usuarios Pedro y Miguel, empleado y cliente respectivamente:
La configuración de Pedro es:
Y la configuración de Miguel es:
Si nos autenticamos con Pedro no tendríamos problema para acceder debido a que el usuario tiene un rol permitido y estamos dentro de la franja horaria habilitada:
Pero si nos logamos con Miguel:
Podemos ver cómo la solicitud de autenticación es rechazada ya que este usuario no tiene asociado ningún rol habilitado para autenticarse en el Service Provider.
Si nos fijamos en las trazas que muestra el servidor podemos ver cómo ha sido la política la que no ha permitido acceder a Miguel.
WARN
org.wso2.carbon.identity.application.authentication.framework.handler.claims.impl.DefaultClaimHandler} - Subject claim could not be found amongst unfiltered local claims
WARN
org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler} - Subject claim could not be found. Defaulting to Name Identifier.
Si probamos ahora a acceder en la aplicación Avis con Miguel, podemos comprobar como la autenticación se realiza correctamente debido a que la política que hemos creado no está asociada con el Service Provider de Avis.
Conclusión
Hemos visto cómo mediante la aplicación de políticas XACML podemos habilitar procedimientos de autenticación de grano fino para determinados Service Providers. De esta manera se puede configurar dinámicamente de una manera no programática el acceso de determinados usuarios a los recursos protegidos.
Si te ha gustado, ¡síguenos en Twitter para estar al día de nuevos posts!