Solución:
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 leer los documentos, libros, el buen YouTube y jugar con la herramienta.
Esta publicación 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
Un poco de terminología antes de empezar:
- En Keycloak, puede crear 2 tipos de permisos: basados en recursos y basados en alcance.
- En pocas palabras, para
Resource-Based
permisos, lo aplica directamente a su recurso - Para
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 tu caso, tienes 2 recursos: account
y transaction
, por lo que me inclinaría hacia el segundo enfoque.
A largo plazo, tener un view
alcance asociado con todos sus recursos (p. ej. account
, transaction
, customer
, settlement
…) dificulta la gestión y la adaptación de la autorización a los cambios en los requisitos de seguridad.
Aquí hay algunos ejemplos que puede consultar para familiarizarse con el diseño.
- API de Slack
- API de caja
- Raya
Sin embargo, tenga en cuenta que no estoy afirmando que no deba compartir ámbitos entre recursos. Cuestión de hecho, Keycloak
permite esto para recursos con el mismo type
. Podrías, por ejemplo, necesitar ambos viewAccount
y 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
, necesitas:
- Defina sus políticas
- Defina sus permisos
- Aplicar sus políticas a sus permisos
- Asocie sus permisos a un
scope
oresource
(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 un
aggregated
política (una política de políticas) y luego asociar esa política agregada con lascope-based
permiso. Podrías tener esoscoped-based
el permiso se aplica tanto al recurso como a todo su ámbito 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 delscope-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
- Cada política
Logic
valor.
los Logic
el valor es similar al de Java !
operador. Puede ser Positive
o Negative
. Cuando el Logic
es 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 su Logic
es Negative
, entonces sera true
). Para simplificar las cosas, supongamos que el Logic
siempre está configurado en Positive
.
los Decision Strategy
es lo que realmente queremos abordar. los Decision Strategy
puede ser 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 alcance 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, el Logic
es Positive
para todas las pólizas). Ahora:
Permission One
tiene unDecision Strategy
ajustado aAffirmative
. También tiene 3 políticas en las que cada una evalúa:true
false
false
Dado que una de las políticas está configurada para true
, Permission One
se establece en true
(Afirmativo: solo uno debe ser true
).
Permission Two
tiene unDecision Strategy
ajustado aUnanimous
con 2 políticas:true
false
En este caso Permission Two
es false
ya que una política es falsa (unánime: todas deben ser true
).
- Ahora viene el final evaluación. Si el servidor de recursos
Decision Strategy
se establece enAffirmative
, el acceso a ese recurso se otorgaría porquePermission One
estrue
. Si, por otro lado, el servidor de recursosDecision Strategy
se establece enUnanimous
, el acceso sería denegado.
Ver:
- Configuración del servidor de recursos
- Administrar permisos
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:
- Del servidor de recursos
Decision Strategy
ajustado aUnanimous
oAffirmative
- Permiso para acceder al
account/id
el recurso estrue
- Permiso para acceder al
view
el alcance estrue
Se le otorgará acceso para ver la cuenta.
true
+true
es igual atrue
bajo laAffirmative
oUnanimous
Decision Strategy
.
Ahora si tienes esto
- Del servidor de recursos
Decision Strategy
ajustado aAffirmative
- Permiso para acceder al
account/id
el recurso estrue
- Permiso para acceder al
view
el alcance esfalse
Vas a además tener acceso para ver la cuenta.
true
+false
estrue
bajo laAffirmative
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 crear 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 “viewAccount”. ¿Es esto correcto?
Bastante. Hay muchas formas de configurar esto. Por ejemplo, puede:
- Crea tu recurso (p. Ej.
/account/id
) y asociarlo con elaccount:view
alcance. - crear una política basada en roles y agregar la
helpdesk
papel bajo esa política - Crear un
Scope-Based
permiso llamadoviewAccount
y atarlo conscope
,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 necesita 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 - los
account/id
tendrá elaccount:view
alcance - Crearemos un usuario llamado
bob
bajo el nuevo reino - También crearemos tres roles:
bank_teller
,account_owner
yuser
- No nos asociaremos
bob
con cualquier rol. Esto no es necesario en este momento.
- No nos asociaremos
- Configuraremos los siguientes dos
Role-Based
políticas:bank_teller
yaccount_owner
tener acceso al/account/id
recursoaccount_owner
tiene acceso alaccount:view
alcanceuser
no tiene acceso al recurso o alcance
- Jugaremos con el
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 a
http://localhost:8080/auth
- Clickea en el
Administration Console
Enlace - Cree el usuario administrador e inicie sesión
Visite Primeros pasos para obtener más información. Para nuestros propósitos, lo anterior es suficiente.
Preparando el escenario
Crea un nuevo reino
- Mueva el mouse alrededor del
master
reino y haga clic en elAdd Realm
botón. - Ingresar
stackoverflow-demo
como el nombre. - Haga clic en
Create
. - La parte superior izquierda ahora debería decir
stackoverflow-demo
en vez demaster
reino.
Ver Creación de un nuevo reino
Crea un nuevo usuario
- Clickea en el
Users
enlace a la izquierda - Clickea en el
Add User
botón - Introducir el
username
(p.ejbob
) - Asegurarse de que
User Enabled
está prendido - Hacer clic
Save
Consulte Creación de un nuevo usuario.
Crear nuevos roles
- Clickea en el
Roles
Enlace - Haga clic en
Add Role
- Agregue los siguientes roles:
bank_teller
,account_owner
yuser
De nuevo, haz no asocia tu usuario con los roles. Para nuestros propósitos, esto no es necesario.
Ver roles
Crea un cliente
- Clickea en el
Clients
Enlace - Haga clic en
Create
- Ingresar
bank-api
Para elClient ID
- Para el
Root URL
ingresarhttp://127.0.0.1:8080/bank-api
- Haga clic en
Save
- Asegurarse de que
Client Protocol
esopenid-connect
- Cambiar el
Access Type
paraconfidential
- Cambio
Authorization Enabled
paraOn
- Desplácese hacia abajo y presione
Save
. Un nuevoAuthorization
La pestaña debería aparecer en la parte superior. - Clickea en el
Authorization
pestaña y luegoSettings
- Asegúrese de que el
Decision Strategy
se establece enUnanimous
- Este es el servidor de recursos
Decision Strategy
- Este es el servidor de recursos
Ver:
- Creación de una aplicación cliente
- Habilitación de servicios de autorización
Crear ámbitos personalizados
- Clickea en el
Authorization
pestaña - Haga clic en
Authorization Scopes
>Create
traer a colaciónAdd Scope
página - Ingresar
account:view
en el nombre y presione enter.
Crear “Ver recurso de cuenta”
- Haga clic en
Authorization
enlace de arriba - Haga clic en
Resources
- Haga clic en
Create
- Ingresar
View Account Resource
tanto para elName
yDisplay name
- Ingresar
account/id
Para elURI
- Ingresar
account:view
en elScopes
caja de texto - Hacer clic
Save
Ver Creación de recursos
Crea tus políticas
- De nuevo bajo el
Authorization
pestaña, haga clic enPolicies
- Seleccione
Role
desde elCreate Policy
desplegable - En el
Name
sección, tipoOnly Bank Teller and Account Owner Policy
- Debajo
Realm Roles
seleccione tanto elbank_teller
yaccount_owner
papel - Asegurarse de que
Logic
se establece enPositive
- Hacer clic
Save
- Clickea en el
Policies
Enlace - Seleccione
Role
de nuevo desde elCreate Policy
desplegable. - Esta vez usa
Only Account Owner Policy
Para elName
- Debajo
Realm Roles
Seleccioneaccount_owner
- Asegurarse de que
Logic
se establece enPositive
- Hacer clic
Save
- Clickea 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 bajo el
Authorization
pestaña, haga clic enPermissions
- Seleccione
Resource-Based
- Escribe
View Account Resource Permission
Para elName
- Debajo
Resources
escribeView Account Resource Permission
- Debajo
Apply Policy
SeleccioneOnly Bank Teller and Account Owner Policy
- Asegúrese de que el
Decision Strategy
se establece enUnanimous
- Hacer clic
Save
Consulte Crear permisos basados en recursos
Uf…
Evaluación del permiso basado en recursos
- De nuevo bajo el
Authorization
pestaña, seleccioneEvaluate
- Debajo
User
ingresarbob
- Debajo
Roles
Seleccioneuser
- Aquí es donde asociaremos a nuestro usuario con nuestros roles creados.
- Debajo
Resources
SeleccioneView Account Resource
y haga clic enAdd
- Haga clic en Evaluar.
- Ampliar la
View Account Resource with scopes [account:view]
para ver los resultados y debería verDENY
.
- Esto tiene sentido porque solo permitimos que dos roles accedan a ese recurso a través del
Only Bank Teller and Account Owner Policy
. ¡Probemos esto para asegurarnos de que sea cierto! - Clickea en el
Back
enlace justo encima del resultado de la evaluación - Cambia el rol de Bob a
account_owner
y haga clic enEvaluate
. Ahora debería ver el resultado comoPERMIT
. Mismo trato si regresa y cambia el rol abank_teller
Consulte Evaluación y prueba de políticas.
Crear permiso basado en alcance
- Vuelve al
Permissions
sección - Seleccione
Scope-Based
esta vez bajo elCreate Permission
desplegable. - Debajo
Name
, ingresarView Account Scope Permission
- Debajo
Scopes
, ingresaraccount:view
- Debajo
Apply Policy
, ingresarOnly Account Owner Policy
- Asegúrese de que el
Decision Strategy
se establece enUnanimous
- Hacer clic
Save
Consulte Creación de permisos basados en el alcance.
Segunda prueba de funcionamiento
Evaluando nuestros nuevos cambios
- Vuelve al
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 clic enAdd
- Haga clic en
Evaluate
y deberíamos conseguirDENY
.- Una vez más, esto no debería sorprendernos, ya que
bank_teller
tiene acceso alresource
pero no elscope
. Aquí, un permiso se evalúa como verdadero y el otro como falso. Dado que el servidor de recursosDecision Strategy
se establece enUnanimous
, la decisión final esDENY
.
- Una vez más, esto no debería sorprendernos, ya que
- Haga clic en
Settings
bajo laAuthorization
pestaña, y cambie laDecision Strategy
paraAffirmative
y vuelva a los pasos 1-6. Esta vez, el resultado final debería serPERMIT
(un permiso es verdadero, entonces la decisión final es verdadera). - En aras de la integridad, convierta el servidor de recursos
Decision Strategy
de regresoUnanimous
. Nuevamente, vuelva a los pasos 1 a 6, pero esta vez, configure el rol comoaccount_owner
. Esta vez, el resultado final es nuevamentePERMIT
lo cual tiene sentido, dado que elaccount_owner
tiene acceso tanto a laresource
yscope
.
Neat 🙂 Espero que esto ayude.
Estaba buscando hacer cumplir la autorización a través de métodos HTTP puros, sin usar el adaptador, ya que Lua no tenía un adaptador. Espero que esta respuesta ayude a las personas que buscan un método no basado en adaptadores.
Si está buscando el adaptador, la guía de inicio rápido es el mejor lugar para comenzar. Especialmente el ejemplo de autenticación de arranque de primavera.
Para una implementación puramente basada en HTTP:
Paso 1:
Defina las políticas y los permisos en la interfaz de usuario de administración de Keycloak
Paso 2
Tenga un mapeo interno de qué rutas HTTP pertenecen a qué recursos y los alcances necesarios para cada ruta. Esto también se puede guardar en el archivo de configuración. Cuando se invoca una ruta en particular, llame al extremo del token de Keycloak para validar las afirmaciones del token de acceso.
"policy-enforcer":
"user-managed-access" : ,
"enforcement-mode" : "ENFORCING"
"paths": [
"path" : "/someUri/*",
"methods" : [
"method": "GET",
"scopes" : ["urn:app.com:scopes:view"]
,
"method": "POST",
"scopes" : ["urn:app.com:scopes:create"]
]
]
Si está utilizando un adaptador y no especifica la ruta o el recurso, el adaptador buscará internamente las rutas y los recursos de Keycloak.
Paso 3:
Utilice el punto final del token para obtener o evaluar los permisos. Puedes usar response_mode
parámetro para obtener la decisión final (si proporcionar acceso) o recuperar todos los permisos.
curl -X POST
http://$host:$port/auth/realms/$realm/protocol/openid-connect/token
-H "Authorization: Bearer $access_token"
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"
--data "permission=Resource A#Scope A"
Si la solicitud de autorización no se asigna a ningún permiso, 403
En su lugar, se devuelve el código de estado HTTP.
Sección de Reseñas y Valoraciones
Si haces scroll puedes encontrar las referencias de otros creadores, tú todavía tienes la libertad de insertar el tuyo si lo crees conveniente.