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-Based
permisos, lo aplica directamente a su recurso
- Para obtener
Scoped-Based
permiso, 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: account
y transaction
, por lo que me inclinaría hacia el segundo enfoque.
A la larga, tener un mundial view
alcance 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, Keycloak
permite esto para recursos con el mismo type
. Por ejemplo, podría necesitar ambos viewAccount
y el viewTransaction
alcance 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
scope
o 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 aggregated
política (una política de políticas) y luego asocie esa política agregada con el scope-based
permiso. Puede hacer que ese scoped-based
permiso 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-based
tipo de permiso y asociar por separado otros permisos únicamente con un alcance a través del scope-based
tipo 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
Logic
valor de cada póliza .
El Logic
valor es similar con el !
operador de Java . Puede ser Positive
o Negative
. Cuando Logic
es 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 Logic
es Negative
, entonces lo será true
). Para simplificar las cosas, supongamos que Logic
siempre está configurado en Positive
.
Eso Decision Strategy
es lo que realmente queremos abordar. El Decision Strategy
puede ser tanto Unanimous
o 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, Logic
es Positive
para todas las políticas). Ahora:
Permission One
tiene un Decision Strategy
conjunto 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 One
se establece en true
(Afirmativo; solo se necesita 1 true
).
Permission Two
tiene un Decision Strategy
conjunto de Unanimous
2 políticas:
En este caso Permission Two
es false
porque una política es falsa (Unánime - todas deben serlo true
).
- Ahora viene la evaluación final . Si el servidor de recursos
Decision Strategy
está configurado en Affirmative
, el acceso a ese recurso se otorgaría porque Permission One
es true
. Si, por otro lado, el servidor de recursos Decision Strategy
está 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 Strategy
configurado en Unanimous
oAffirmative
- El permiso para acceder al
account/{id}
recurso estrue
- El permiso para acceder al
view
alcance estrue
Se le otorgará acceso para ver la cuenta.
true
+ true
es igual a true
debajo de Affirmative
o Unanimous
Decision Strategy
.
Ahora si tienes esto
- El servidor de recursos está
Decision Strategy
configurado enAffirmative
- El permiso para acceder al
account/{id}
recurso estrue
- El permiso para acceder al
view
alcance esfalse
También se le otorgará acceso para ver la cuenta.
true
+ false
está true
bajo la Affirmative
estrategia.
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:view
alcance.
- crear una política basada en roles y agregar el
helpdesk
rol bajo esa política
- Cree un
Scope-Based
permiso llamado viewAccount
y átelo con scope
, resource
ypolicy
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-api
cliente bajo ese reino
- Definiremos un recurso llamado
/account/{id}
para ese cliente
- El
account/{id}
tendrá el account:view
alcance
- Crearemos un usuario llamado
bob
bajo el nuevo reino
- También vamos a crear tres funciones:
bank_teller
, account_owner
yuser
- No nos asociaremos
bob
con ningún rol. Esto no es necesario en este momento.
- Configuraremos las siguientes dos
Role-Based
políticas:
bank_teller
y account_owner
tener acceso al /account/{id}
recurso
account_owner
tiene acceso al account:view
alcance
user
no tiene acceso al recurso o alcance
- Jugaremos con la
Evaluate
herramienta 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 Console
enlace
- 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
master
reino y haga clic en el Add Realm
botón.
- Ingrese
stackoverflow-demo
como el nombre.
- Haga clic en
Create
.
- La parte superior izquierda debería decir ahora en
stackoverflow-demo
lugar del master
reino.
Ver Crear un nuevo reino
Crea un nuevo usuario
- Haga clic en el
Users
enlace de la izquierda.
- Haga clic en el
Add User
botón
- Ingrese el
username
(por ejemplo bob
)
- Asegúrese de que
User Enabled
esté encendido
- Hacer clic
Save
Ver Creación de un nuevo usuario
Crear nuevos roles
- Haga clic en el
Roles
enlace
- Haga clic en
Add Role
- Añadir las siguientes funciones:
bank_teller
, account_owner
yuser
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
Clients
enlace
- Haga clic en
Create
- Entrar
bank-api
para elClient ID
- Para
Root URL
entrarhttp://127.0.0.1:8080/bank-api
- Haga clic en
Save
- Asegúrese de que
Client Protocol
seaopenid-connect
- Cambiar el
Access Type
aconfidential
- Cambiar
Authorization Enabled
aOn
- Desplácese hacia abajo y presione
Save
. Authorization
Debería aparecer una nueva pestaña en la parte superior.
- Haga clic en la
Authorization
pestaña y luegoSettings
- Asegúrese de que
Decision Strategy
esté configurado enUnanimous
- Este es el servidor de recursos
Decision Strategy
Ver:
Crear ámbitos personalizados
- Haga clic en la
Authorization
pestaña
- Haga clic en
Authorization Scopes
> Create
para abrir la Add Scope
página
- Ingrese
account:view
el nombre y presione enter.
Crear "Ver recurso de cuenta"
- Haga clic en el
Authorization
enlace de arriba
- Haga clic en
Resources
- Haga clic en
Create
- Ingrese
View Account Resource
para Name
yDisplay name
- Entrar
account/{id}
para elURI
- Entrar
account:view
en el Scopes
cuadro de texto
- Hacer clic
Save
Ver Creación de recursos
Crea tus políticas
- De nuevo debajo de la
Authorization
pestaña, haga clic enPolicies
- Seleccione
Role
del Create Policy
menú desplegable
- En la
Name
sección, escribaOnly Bank Teller and Account Owner Policy
- Bajo
Realm Roles
seleccionar tanto el bank_teller
y account_owner
papel
- Asegúrese de que
Logic
esté configurado enPositive
- Hacer clic
Save
- Haga clic en el
Policies
enlace
- Seleccione
Role
nuevamente del Create Policy
menú desplegable.
- Esta vez utilícelo
Only Account Owner Policy
paraName
- Bajo
Realm Roles
seleccionaraccount_owner
- Asegúrese de que
Logic
esté configurado enPositive
- Hacer clic
Save
- Haga clic en el
Policies
enlace 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
Authorization
pestaña, haga clic enPermissions
- Seleccione
Resource-Based
- Escriba
View Account Resource Permission
para elName
- Bajo
Resources
tipoView Account Resource Permission
- Bajo
Apply Policy
seleccionarOnly Bank Teller and Account Owner Policy
- Asegúrese de que
Decision Strategy
esté configurado enUnanimous
- Hacer clic
Save
Consulte Crear permisos basados en recursos
Uf...
Evaluación del permiso basado en recursos
- De nuevo debajo de la
Authorization
pestaña, seleccioneEvaluate
- Debajo de
User
entrarbob
- Bajo
Roles
seleccionaruser
- Aquí es donde asociaremos a nuestro usuario con nuestros roles creados.
- En
Resources
seleccione View Account Resource
y 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
Back
enlace que está justo encima del resultado de la evaluación.
- Cambie el rol de Bob a
account_owner
y 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
Permissions
sección
- Seleccione
Scope-Based
este tiempo en el Create Permission
menú desplegable.
- Debajo
Name
, ingreseView Account Scope Permission
- Debajo
Scopes
, ingreseaccount:view
- Debajo
Apply Policy
, ingreseOnly Account Owner Policy
- Asegúrese de que
Decision Strategy
esté 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
Authorization
sección
- Haga clic en
Evaluate
- El usuario debe ser
bob
- Los roles deben ser
bank_teller
- Los recursos deben ser
View Account Resource
y haga clicAdd
- Haga clic en
Evaluate
y deberíamos obtener DENY
.
- Una vez más, esto no debería sorprendernos, ya que
bank_teller
tiene acceso al resource
pero no al scope
. Aquí, un permiso se evalúa como verdadero y el otro como falso. Dado que el servidor de recursos Decision Strategy
está configurado en Unanimous
, la decisión final es DENY
.
- Haga clic en
Settings
debajo de la Authorization
pestaña, cambie Decision Strategy
a Affirmative
y 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 Strategy
a 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 PERMIT
lo que tiene sentido, dado que la account_owner
tiene acceso tanto a la resource
y scope
.
Neat :) Espero que esto ayude.