Sé que llego más de 2 años tarde, pero me imagino que compartiría lo que sé y, con suerte, aliviaré un poco el dolor de los futuros lectores. Transparencia total: de ninguna manera soy un experto en Keycloak / OAuth / OIDC y lo que sé es principalmente de la lectura de documentos, libros, el buen YouTube y jugar con la herramienta.
Este artículo constará de dos partes:
- Intentaré responder todas sus preguntas lo mejor que pueda.
- Le mostraré cómo puede jugar con políticas / ámbitos / permisos en Keycloak sin necesidad de implementar una aplicación separada para comprender mejor algunos de los conceptos centrales de este hilo. Sin embargo, tenga en cuenta que esto está destinado principalmente a que todos comiencen. Estoy usando
Keycloak 8.0.0.
Parte I
Algo de terminología antes de comenzar:
- En Keycloak, puede crear 2 tipos de permisos: Basada en Recursos y Alcance-Based .
- En pocas palabras, para los
Resource-Basedpermisos, lo aplica directamente a su recurso
- Para obtener
Scoped-Basedpermiso, lo aplica a su (s) alcance (s) o alcance (s) y recurso.
¿Es una buena práctica crear un solo alcance de "vista" y utilizarlo en varios recursos (cuenta, transacción, etc.)? ¿O debería crear un alcance "viewAccount", un alcance "viewTransaction", etc.?
Los ámbitos representan un conjunto de derechos sobre un recurso protegido. En su caso, tiene 2 recursos: accounty transaction, por lo que me inclinaría hacia el segundo enfoque.
A la larga, tener un mundial viewalcance asociado con todos sus recursos (por ejemplo account, transaction, customer, settlement...) hace difícil la autorización tanto de manejo y la adaptación a cambios en los requisitos de seguridad.
Aquí hay algunos ejemplos que puede consultar para familiarizarse con el diseño.
Sin embargo, tenga en cuenta que no estoy afirmando que no deba compartir ámbitos entre recursos. De hecho, Keycloakpermite esto para recursos con el mismo type. Por ejemplo, podría necesitar ambos viewAccounty el viewTransactionalcance para leer una transacción en una cuenta determinada (después de todo, es posible que necesite acceder a la cuenta para ver las transacciones). Sus requisitos y estándares influirán en gran medida en su diseño.
Para cada combinación práctica de recurso y alcance, ¿es una práctica habitual crear un permiso?
Disculpas, no entiendo completamente la pregunta, así que seré un poco amplio. Para otorgar / denegar el acceso a un resource, debe:
- Defina sus políticas
- Defina sus permisos
- Aplicar sus políticas a sus permisos
- Asocie sus permisos a uno
scopeo resource(o ambos)
para que la aplicación de la política surta efecto. Ver proceso de autorización .
La forma de configurar todo esto depende totalmente de usted. Podrías, por ejemplo:
Defina políticas individuales y vincule cada política con el permiso correspondiente.
Mejor aún, defina políticas individuales, luego agrupe todas sus políticas relacionadas bajo una aggregatedpolítica (una política de políticas) y luego asocie esa política agregada con el scope-basedpermiso. Puede hacer que ese scoped-basedpermiso se aplique tanto al recurso como a todo su alcance asociado.
O bien, podría dividir aún más sus permisos aprovechando los dos tipos separados. Puede crear permisos únicamente para sus recursos a través del resource-basedtipo de permiso y asociar por separado otros permisos únicamente con un alcance a través del scope-basedtipo de permiso.
Tienes opciones.
Si hay varios permisos que coinciden con un recurso / alcance determinado, ¿qué hace Keycloak?
Esto depende de
- El servidor de recursos
Decision Strategy
- Cada permiso
Decision Strategy
- El
Logicvalor de cada póliza .
El Logicvalor es similar con el !operador de Java . Puede ser Positiveo Negative. Cuando Logices así Positive, la evaluación final de la política permanece sin cambios. Cuando es Negative, el resultado final se niega (por ejemplo, si una política se evalúa como falsa y Logices Negative, entonces lo será true). Para simplificar las cosas, supongamos que Logicsiempre está configurado en Positive.
Eso Decision Strategyes lo que realmente queremos abordar. El Decision Strategypuede ser tanto Unanimouso Affirmative. De los documentos,
Estrategia de decisión
Esta configuración cambia la forma en que el motor de evaluación de políticas decide si se debe otorgar o no un recurso o ámbito en función del resultado de todos los permisos evaluados. Afirmativo significa que al menos un permiso debe evaluar una decisión positiva para otorgar acceso a un recurso y sus alcances. Unánime significa que todos los permisos deben evaluar una decisión positiva para que la decisión final también sea positiva. Por ejemplo, si dos permisos para un mismo recurso o alcance están en conflicto (uno de ellos otorga acceso y el otro lo niega), el permiso para el recurso o alcance se otorgará si la estrategia elegida es Afirmativa. De lo contrario, una sola denegación de cualquier permiso también denegará el acceso al recurso o alcance.
Usemos un ejemplo para comprender mejor lo anterior. Suponga que tiene un recurso con 2 permisos y alguien está intentando acceder a ese recurso (recuerde, Logices Positivepara todas las políticas). Ahora:
Permission Onetiene un Decision Strategyconjunto de Affirmative. También tiene 3 políticas donde cada uno evalúa:
Dado que una de las políticas está configurada en true, Permission Onese establece en true(Afirmativo; solo se necesita 1 true).
Permission Twotiene un Decision Strategyconjunto de Unanimous2 políticas:
En este caso Permission Twoes falseporque una política es falsa (Unánime - todas deben serlo true).
- Ahora viene la evaluación final . Si el servidor de recursos
Decision Strategyestá configurado en Affirmative, el acceso a ese recurso se otorgaría porque Permission Onees true. Si, por otro lado, el servidor de recursos Decision Strategyestá configurado en Unanimous, se denegará el acceso.
Ver:
Seguiremos revisando esto. Explico cómo configurar el servidor de recursos Decision Strategy en la Parte II.
entonces, por ejemplo, podría tener permiso para acceder a "cuentas" y permiso para "ver" el alcance, por lo tanto, ¿tendría permiso para ver cuentas?
La respuesta corta es sí. Ahora, ampliemos esto un poco :)
Si tiene el siguiente escenario:
- El servidor de recursos está
Decision Strategyconfigurado en UnanimousoAffirmative
- El permiso para acceder al
account/{id}recurso estrue
- El permiso para acceder al
viewalcance estrue
Se le otorgará acceso para ver la cuenta.
true+ truees igual a truedebajo de Affirmativeo Unanimous Decision Strategy.
Ahora si tienes esto
- El servidor de recursos está
Decision Strategyconfigurado enAffirmative
- El permiso para acceder al
account/{id}recurso estrue
- El permiso para acceder al
viewalcance esfalse
También se le otorgará acceso para ver la cuenta.
true+ falseestá truebajo la Affirmativeestrategia.
El punto aquí es que el acceso a un recurso determinado también depende de su configuración, así que tenga cuidado, ya que es posible que no desee el segundo escenario.
Pero, ¿tengo razón en que esto significa que necesito una política para cada uno de los grupos heredados a los que podría pertenecer un usuario?
No estoy seguro de cómo se comportó Keycloak hace 2 años, pero puede especificar una política basada en grupos y simplemente agregar todos sus grupos bajo esa política. Ciertamente, no es necesario que cree una política por grupo.
Por ejemplo, si tengo un rol de "servicio de asistencia técnica", entonces necesito una política de "membresía de servicio de asistencia técnica", que luego podría agregar al permiso "ver cuenta". ¿Es esto correcto?
Bastante. Hay muchas formas de configurar esto. Por ejemplo, puede:
- Cree su recurso (por ejemplo
/account/{id}) y asócielo con el account:viewalcance.
- crear una política basada en roles y agregar el
helpdeskrol bajo esa política
- Cree un
Scope-Basedpermiso llamado viewAccounty átelo con scope, resourceypolicy
Configuraremos algo similar en la Parte II.
Parte II
Keycloak tiene una pequeña herramienta que le permite probar todas sus políticas. Mejor aún, en realidad no es necesario activar otro servidor de aplicaciones e implementar una aplicación separada para que esto funcione.
Este es el escenario que configuraremos:
- Crearemos un nuevo reino llamado
stackoverflow-demo
- Crearemos un
bank-apicliente bajo ese reino
- Definiremos un recurso llamado
/account/{id}para ese cliente
- El
account/{id}tendrá el account:viewalcance
- Crearemos un usuario llamado
bobbajo el nuevo reino
- También vamos a crear tres funciones:
bank_teller, account_owneryuser
- No nos asociaremos
bobcon ningún rol. Esto no es necesario en este momento.
- Configuraremos las siguientes dos
Role-Basedpolíticas:
bank_tellery account_ownertener acceso al /account/{id}recurso
account_ownertiene acceso al account:viewalcance
user no tiene acceso al recurso o alcance
- Jugaremos con la
Evaluateherramienta para ver cómo se puede otorgar o denegar el acceso.
Perdóname, este ejemplo no es realista pero no estoy familiarizado con el sector bancario :)
Configuración de Keycloak
Descarga y ejecuta Keycloak
cd tmp
wget https://downloads.jboss.org/keycloak/8.0.0/keycloak-8.0.0.zip
unzip keycloak-8.0.0.zip
cd keycloak-8.0.0/bin
./standalone.sh
Crear usuario administrador inicial
- Ir
http://localhost:8080/auth
- Haga clic en el
Administration Consoleenlace
- Cree el usuario administrador e inicie sesión
Visita Getting Started para obtener más información. Para nuestros propósitos, lo anterior es suficiente.
Preparando el escenario
Crea un nuevo reino
- Pase el mouse por el
masterreino y haga clic en el Add Realmbotón.
- Ingrese
stackoverflow-democomo el nombre.
- Haga clic en
Create.
- La parte superior izquierda debería decir ahora en
stackoverflow-demolugar del masterreino.
Ver Crear un nuevo reino
Crea un nuevo usuario
- Haga clic en el
Usersenlace de la izquierda.
- Haga clic en el
Add Userbotón
- Ingrese el
username(por ejemplo bob)
- Asegúrese de que
User Enabledesté encendido
- Hacer clic
Save
Ver Creación de un nuevo usuario
Crear nuevos roles
- Haga clic en el
Rolesenlace
- Haga clic en
Add Role
- Añadir las siguientes funciones:
bank_teller, account_owneryuser
Nuevamente, no asocie a su usuario con los roles. Para nuestros propósitos, esto no es necesario.
Ver roles
Crea un cliente
- Haga clic en el
Clientsenlace
- Haga clic en
Create
- Entrar
bank-apipara elClient ID
- Para
Root URLentrarhttp://127.0.0.1:8080/bank-api
- Haga clic en
Save
- Asegúrese de que
Client Protocolseaopenid-connect
- Cambiar el
Access Typeaconfidential
- Cambiar
Authorization EnabledaOn
- Desplácese hacia abajo y presione
Save. AuthorizationDebería aparecer una nueva pestaña en la parte superior.
- Haga clic en la
Authorizationpestaña y luegoSettings
- Asegúrese de que
Decision Strategyesté configurado enUnanimous
- Este es el servidor de recursos
Decision Strategy
Ver:
Crear ámbitos personalizados
- Haga clic en la
Authorizationpestaña
- Haga clic en
Authorization Scopes> Createpara abrir la Add Scopepágina
- Ingrese
account:viewel nombre y presione enter.
Crear "Ver recurso de cuenta"
- Haga clic en el
Authorizationenlace de arriba
- Haga clic en
Resources
- Haga clic en
Create
- Ingrese
View Account Resourcepara NameyDisplay name
- Entrar
account/{id}para elURI
- Entrar
account:viewen el Scopescuadro de texto
- Hacer clic
Save
Ver Creación de recursos
Crea tus políticas
- De nuevo debajo de la
Authorizationpestaña, haga clic enPolicies
- Seleccione
Roledel Create Policymenú desplegable
- En la
Namesección, escribaOnly Bank Teller and Account Owner Policy
- Bajo
Realm Rolesseleccionar tanto el bank_tellery account_ownerpapel
- Asegúrese de que
Logicesté configurado enPositive
- Hacer clic
Save
- Haga clic en el
Policiesenlace
- Seleccione
Rolenuevamente del Create Policymenú desplegable.
- Esta vez utilícelo
Only Account Owner PolicyparaName
- Bajo
Realm Rolesseleccionaraccount_owner
- Asegúrese de que
Logicesté configurado enPositive
- Hacer clic
Save
- Haga clic en el
Policiesenlace en la parte superior, ahora debería ver sus políticas recién creadas.
Ver política basada en roles
Tenga en cuenta que Keycloak tiene políticas mucho más poderosas. Ver Gestión de políticas
Crear permiso basado en recursos
- De nuevo debajo de la
Authorizationpestaña, haga clic enPermissions
- Seleccione
Resource-Based
- Escriba
View Account Resource Permissionpara elName
- Bajo
ResourcestipoView Account Resource Permission
- Bajo
Apply PolicyseleccionarOnly Bank Teller and Account Owner Policy
- Asegúrese de que
Decision Strategyesté configurado enUnanimous
- Hacer clic
Save
Consulte Crear permisos basados en recursos
Uf...
Evaluación del permiso basado en recursos
- De nuevo debajo de la
Authorizationpestaña, seleccioneEvaluate
- Debajo de
Userentrarbob
- Bajo
Rolesseleccionaruser
- Aquí es donde asociaremos a nuestro usuario con nuestros roles creados.
- En
Resourcesseleccione View Account Resourcey haga clic enAdd
- Haga clic en Evaluar.
- Expanda
View Account Resource with scopes [account:view]para ver los resultados y debería ver DENY.

- Esto tiene sentido porque solo permitimos el acceso de dos roles a ese recurso a través de
Only Bank Teller and Account Owner Policy. ¡Probemos esto para asegurarnos de que sea cierto!
- Haga clic en el
Backenlace que está justo encima del resultado de la evaluación.
- Cambie el rol de Bob a
account_ownery haga clic en Evaluate. Ahora debería ver el resultado como PERMIT. Mismo trato si regresa y cambia el rol abank_teller
Consulte Evaluación y prueba de políticas.
Crear permiso basado en alcance
- Volver a la
Permissionssección
- Seleccione
Scope-Basedeste tiempo en el Create Permissionmenú desplegable.
- Debajo
Name, ingreseView Account Scope Permission
- Debajo
Scopes, ingreseaccount:view
- Debajo
Apply Policy, ingreseOnly Account Owner Policy
- Asegúrese de que
Decision Strategyesté configurado enUnanimous
- Hacer clic
Save
Consulte Creación de permisos basados en el alcance
Segunda prueba de funcionamiento
Evaluando nuestros nuevos cambios
- Volver a la
Authorizationsección
- Haga clic en
Evaluate
- El usuario debe ser
bob
- Los roles deben ser
bank_teller
- Los recursos deben ser
View Account Resourcey haga clicAdd
- Haga clic en
Evaluatey deberíamos obtener DENY.
- Una vez más, esto no debería sorprendernos, ya que
bank_tellertiene acceso al resourcepero no al scope. Aquí, un permiso se evalúa como verdadero y el otro como falso. Dado que el servidor de recursos Decision Strategyestá configurado en Unanimous, la decisión final es DENY.
- Haga clic en
Settingsdebajo de la Authorizationpestaña, cambie Decision Strategya Affirmativey vuelva a los pasos 1-6 nuevamente. Esta vez, el resultado final debería ser PERMIT(un permiso es verdadero, por lo que la decisión final es verdadera).
- En aras de la integridad, dé la vuelta al servidor de recursos
Decision Strategya Unanimous. Nuevamente, vuelva a los pasos 1 a 6, pero esta vez configure el rol como account_owner. Esta vez, el resultado final es una vez más PERMITlo que tiene sentido, dado que la account_ownertiene acceso tanto a la resourcey scope.
Neat :) Espero que esto ayude.