Keycloak Authorization with HTTP Method

Viewed 204

I developed some taskmanagement services for learning/evaluating keycloak. What I have so far:

Users:

  • Marge
  • Homer
  • Lisa
  • Bart

Services:

  • POST /safe/tasks: Creates a new task
  • GET /safe/tasks: Lists all tasks

Requirements:

  • Only the boss, Marge, should be able to create new tasks
  • A new task can be flagged as 'parentOnly'
  • Everyone should be able to list tasks. The result list depends on who calls the service:
    • Parents get the full list
    • Children only get the non-parent tasks

Client:

  • Authorization enabled
  • Access Type: confidential

Authorization Scopes:

  • tasks:create
  • tasks:list
  • tasks:list_full

Resources:

  • Tasks Resource
    • URI: /safe/tasks
    • scopes:
      • tasks:create
      • tasks:list
      • tasks:list_full

Policies:

  • Boss only (user = Marge)
  • Parents only (user = Marge, Homer)
  • Children only (user = Bart, Lisa)
  • Family members only (aggregated = Parents only + Children only)

Permissions:

  • Boss can create tasks: Connects /safe/tasks with scope tasks:create and policy 'Boss only'
  • Family can list tasks: Connects /safe/tasks with scope tasks:list and policy 'Family Members only'
  • Parents can list all tasks: Connects /safe/tasks with scope tasks:list_full and policy 'Parents only'

It is implemented as a Spring Boot Application but with a KeycloakOIDCFilter listening on patterns "/keycloak/" and "/safe/". Policy enforcement is on.

So far SOME things work: The resource can be accessed and the available scopes (dump of AuthorizationContext) are as expected:

Lisa: Permission {id=5a1498e5-14e5-4353-8d5a-5fb12fc739c8, name=Tasks Resource, scopes=[tasks:list]}
Bart: Permission {id=5a1498e5-14e5-4353-8d5a-5fb12fc739c8, name=Tasks Resource, scopes=[tasks:list]}
Marge: Permission {id=5a1498e5-14e5-4353-8d5a-5fb12fc739c8, name=Tasks Resource, scopes=[tasks:list_full, tasks:list, tasks:create]}
Homer: Permission {id=5a1498e5-14e5-4353-8d5a-5fb12fc739c8, name=Tasks Resource, scopes=[tasks:list_full, tasks:list]}

So at least in GET /safe/tasks implementation I can check for list/list_full and return the Tasks accordingly.

Problem is: Everyone can access the resource with GET and POST.

I already tried http-method-as-scope=true with these Modifications:

  • Added GET and POST as Authorization Scopes
  • Added POST as scope to permission "Boss can create Tasks"
  • Added GET as scope to permission "Family can list Tasks"
  • Added GET as scope to permission "Parents can list all tasks"

With that at least only Marge can do POST. But the dump of AuthorizationContext does not show available scopes anymore. I only see POST. Marge: Permission: Permission {id=5a1498e5-14e5-4353-8d5a-5fb12fc739c8, name=Tasks Resource, scopes=[POST]} Also: At the same time it breaks the GET. Now I get 403 when Lisa calls GET on /safe/tasks.

I really would appreciate if someone could help me with this. How Do I get the permissions right and at the same time preserve access to available scopes in AuthorizationContext?

Thanks in advance!!

0 Answers
Related