postgrest icon indicating copy to clipboard operation
postgrest copied to clipboard

jwt: iterate over roles

Open michael-todorovic opened this issue 5 years ago • 16 comments

Environment

  • PostgreSQL version: 12
  • PostgREST version: 7.0.0
  • Operating system: Linux

Description of issue

Hello, I configured postgrest authentication through jwt with Keycloak and here is what I get for my roles in the jwt token:

"realm_access": {
    "roles": [
      "role1",
      "role2"
    ]
  }

In postgrest.conf, I have set role-claim-key = ".realm_access.roles" but postgrest takes it as a simple string and I get

{"hint":null,"details":null,"code":"22023","message":"role \"[\"role1\",\"role2\"]\" does not exist"}

I tried to look at parsers.hs but I don't know haskell so I was unable to tell if it's feasible or not.

As role1 exists in my DB, I got it working with role-claim-key = ".realm_access.roles[0]" but this not good enough for production as the list ordering may depend on the user.

Do you have any clue how I can achieve this?

Thanks!

michael-todorovic avatar May 25 '20 15:05 michael-todorovic

Do you mean you'd like to search for a role name in the array?

(PostgREST can only accept one role at a time)

The role-claim-key config follows jspath. Looks like they have some comparison operators that could be used for this: https://github.com/dfilatov/jspath#comparison-operators.

steve-chavez avatar May 25 '20 16:05 steve-chavez

Not sure if this is really follows the spec, but looks like the expression could be:

role-claim-key=".realm_access{.roles == 'myrole'}[0]"

steve-chavez avatar May 25 '20 16:05 steve-chavez

Yes I have multiple roles in my array and I'd like to match one of them against postgresql or postgrest configuration.

I wanted to try your proposal but actually, https://github.com/PostgREST/postgrest/blob/master/src/PostgREST/Parsers.hs#L259-L272 prevents the full usage of JSPath features: {}= characters are not allowed

postgrest: FatalError {fatalErrorMessage = "Left (ParseRequestError \"\\\"failed to parse role-claim-key value (.realm_access{.roles=='myrole'})\\\" (line 1, column 14)\" \"unexpected '{' expecting letter or digit, array index [0..n], period (.) or end of input\")"}

I'm exploring an alternative with Keycloak to provide a single string to bypass the issue. However, I'll be happy to test any patch :)

michael-todorovic avatar May 27 '20 07:05 michael-todorovic

@michael-todorovic Yes, that was mostly a proposal. Not implemented for now. Though adding the capability looks reasonable since it follows jspath.

I could help reviewing a PR If you'd like to give it a shot. Otherwise the single string role is your best bet for now.

steve-chavez avatar May 27 '20 16:05 steve-chavez

@michael-todorovic, I used a custom mapper to check that I had a specific role. I then added another claim according to the test. Would you be interested in seeing this?

Videl avatar Jul 29 '20 20:07 Videl

@Videl I would - yes please.

davidjamesstone avatar Aug 13 '20 11:08 davidjamesstone

@davidjamesstone https://gist.github.com/Videl/222eff2f16383e2f318ecec2228d1008

Videl avatar Aug 15 '20 11:08 Videl

I'm exploring an alternative with Keycloak to provide a single string to bypass the issue. However, I'll be happy to test any patch :)

@michael-todorovic It seems I have the some issues with Keycloak and multiple roles too. Did you ever solve your issue, to only provide a single role as you mentioned above...? Care to dig it up? Thanks

stratosgear avatar Jan 21 '21 18:01 stratosgear

Considering https://github.com/PostgREST/postgrest/issues/2877, looks we also need prefix string comparison .role ==^ "postgrest_".

steve-chavez avatar Aug 01 '23 03:08 steve-chavez

Would like a solution on this as well, same problem using auth0 as we cannot guarantee the order of the claims...

mbwmbw1337 avatar Dec 16 '23 08:12 mbwmbw1337

Would ❤️ to see this too! Keycloak is a major OAuth provider and pretty much always comes with multiple roles. Should be solvable with some JSPath magic?

For now I'm praying on Keycloak always putting the last added role first in the array..

Sjoerd82 avatar Mar 20 '24 20:03 Sjoerd82