strimzi / strimzi-kafka-oauth

OAuth2 support for Apache Kafka® to work with many OAuth2 authorization servers
Apache License 2.0
140 stars 89 forks source link

Username prefix only available for fallback #228

Open nkostoulas opened 6 months ago

nkostoulas commented 6 months ago

Is there any reason that the username claim prefix (oauth.fallback.username.prefix) is only configurable for the fallback username (oauth.fallback.username.claim) and not the primary one (oauth.username.claim)?

The question is mainly focused around Strimzi Brokers but I thought it would be more relevant to ask here. We basically want to use different OAuth ingress listeners that connect to different OAuth servers. Using a different prefix on each OAuth listener would allow to set up authorisation more easily.

I guess it is still technically possible by setting oauth.username.claim to something that might never be there.

mstruk commented 6 months ago

The original use case for adding the fallback prefix configuration was the difference in JWT token claims in tokens obtained from some authorization servers when authenticating with client_credentials vs. refresh_token or password.

I never thought of your use case. It sounds legitimate.

The workaround is exactly like you described.

nkostoulas commented 6 months ago

I noticed you've added oauth.username.prefix prefix in 0.15, thanks! I'll be waiting for it to get adopted by the latest strimzi operator.

I noticed that if oauth.username.claim is set to the empty string then it is ignored, sub isn't used and the fallback is used instead. It wasn't very clear in the docs but I've verified this in Strimzi 0.33. This behaviour really suits us but I wanted to double-check if that is the case.

mstruk commented 6 months ago

Yes. This issue has been addressed by #230.

Can you be more specific about the exact configuration you have?

nkostoulas commented 6 months ago

I have the following configuration in Strimzi:

userNameClaim: ""
fallbackUserNameClaim: "test"
fallbackUserNamePrefix: "prefix_"

I assume this corresponds to:

oauth.username.claim = ""
oauth.fallback.username.claim = "test"
oauth.fallback.username.prefix = "prefix_"

I would have thought that based on documentation if oauth.username.claim is not set then the default sub claim would be used but it seems that when explicitly setting it to "" then the fallback is selected directly.

Well unless my tokens don't even have the sub claim (will check).

nkostoulas commented 6 months ago

Nope - sub is populated on the JWT.

mstruk commented 6 months ago

This is the algorithm which the code should agree with:

The addition of oauth.username.prefix has not changed current behavior of existing configurations in any way (since they are not using it).

To comment on your example configuration specifically ...

You setting the oauth.username.claim makes it possible for oauth.fallback.username.claim to take effect. With the newly added oauth.username.prefix you could as well rewrite your configuration into:

oauth.username.claim = "test"
oauth.username.prefix = "prefix_"

If you want to use sub claim but also have it prefixed, then you would configure the sub claim explicitly rather than leave it as the final fallback:

oauth.username.claim = "test"
oauth.username.prefix = "prefix_"
oauth.fallback.username.claim = "sub"
oauth.fallback.username.prefix = "prefix_"

Alternatively, we could think here about changing oauth.username.prefix behavior in such a way that it is also applied to the final fallback to sub, but then if oauth.fallback.username.prefix is used, why not use that one when falling back to sub. That isn't intuitive, so I prefer usage of oauth*.username.prefix to be linked to the corresponding oauth*.username with sub fallback completely separate.

In the future the new option will be integrated into Strimzi Operator as userNamePrefix.

nkostoulas commented 6 months ago

ok, thanks!

I only want to use the fallback for now and until the Strimzi Operator supports the userNamePrefix.

I wasn't sure whether setting userNameClaim to "" would cause it to be ignored and look for the sub claim instead or just look for a "" claim that won't exist. It seems to be the latter and that is what I wanted to confirm. I suppose it's not possible to use empty claim names in a JWT token.

nkostoulas commented 3 months ago

@mstruk I think https://github.com/strimzi/strimzi-kafka-oauth/commit/10d3c0e32fe655c078063435ec160e69582e55ac might have not fixed the issue. I've just upgraded to the 0.40 Strimzi Operator which uses the 0.15 version of this lib and the fallback prefix is still failing.

nkostoulas commented 3 months ago

If oauth.fallback.username.claim is configured, but not the oauth.username.claim, it is ignored.

This might be the reason? I'm trying to validate now.

Before this was introduced I would set oauth.username.claim to "" and the fallback would still work.

nkostoulas commented 3 months ago

Ok it seems setting oauth.username.claim to a random value does the trick 🙂