-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify main vs extra JWT bearers differently #596
Verify main vs extra JWT bearers differently #596
Conversation
5b26754
to
a547010
Compare
if err != nil { | ||
logger.Printf("failed to verify bearer token: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this and defaulted to the logging happening only if all verifiers failed. My users have been confused with error messages when 1st or 2nd verifiers on the array fail and the 3rd extraJwt Verifier succeeded (seeing the failed
words even though it succeeded was confusing)
assert.Equal(t, rawIDToken, session.AccessToken) | ||
assert.Equal(t, rawIDToken, session.IDToken) | ||
assert.Equal(t, "", session.RefreshToken) | ||
assert.Equal(t, "123456789", session.Email) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the overall architectural rationale for forcing a session.Email
to a claim.Subject
when an email
claim is missing? And not using the claim.Subject
at all in the session and setting both the session.Email
and session.User
to the Email?
oauth2-proxy/providers/provider_default.go
Line 155 in f7b28cb
if claims.Email == "" { |
I left the existing logic untouched -- but shouldn't session.User
== claim.Subject
(That's what my OIDC provider results in going the normal route).
oauth2-proxy/providers/provider_default.go
Line 165 in f7b28cb
User: claims.Email, |
And should we allow session.Email
to be "" if the IDToken is missing the claim? And adjust the email domains validator to accept it if its set to *
(if set to anything else it would fail since it is missing a @
character)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User ID claim was added so that we could make sure that a particular claim was added, to be considered the user, but the work hasn't been completed so it's only half way through
As for falling back, I'm not sure why we are doing that, i think we currently require all sessions to have a user and email field that's not empty, so I guess that's why? I think I need to do some archaeology on this
On further reflection, I think this is definitely a bug? oauth2-proxy/providers/provider_default.go Line 165 in a17c488
I had a user make a web app that used this proxy for use with CLI tools that did OIDC via PKSE and passed the IDToken as the bearer. He got the I was very confused at the time, but this is definitely why. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had a read through, looks pretty good so far, left a couple of comments
Please fixup the conflicts and add a changelog entry
assert.Equal(t, rawIDToken, session.AccessToken) | ||
assert.Equal(t, rawIDToken, session.IDToken) | ||
assert.Equal(t, "", session.RefreshToken) | ||
assert.Equal(t, "123456789", session.Email) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User ID claim was added so that we could make sure that a particular claim was added, to be considered the user, but the work hasn't been completed so it's only half way through
As for falling back, I'm not sure why we are doing that, i think we currently require all sessions to have a user and email field that's not empty, so I guess that's why? I think I need to do some archaeology on this
I still owe you an interactive test on this, I haven't dockerized this branch yet to test how it all works deployed as a sidecar in a local kubernetes environment that is setup for OIDC projected service account tokens. |
Should I make the |
b08147b
to
f2bf5a3
Compare
@JoelSpeed Let me know what you find out as far as the history of the forced This commit is my take on allowing it: 1dd6ba5 I can ditch it if needed (or cherry pick it to a separate PR to keep this PR purely about the bearer bugs). |
f2bf5a3
to
1dd6ba5
Compare
This is done, looks good in a kubernetes environment allowing both OneLogin IDTokens (configured provider) OR kubernetes projected service account tokens (extra bearer JWT):
|
I had the OneLogin OIDC Human IDToken:
Kubernetes Projected Service Account IDToken:
|
So I did some archaeology today, my conclusion is that, if the scope contained As far as I can tell, the OAuth2 Proxy doesn't require the email to be returned from the provider anywhere, so I think we can get away with not setting it. It's probably better that I rework this into #560 This will likely be a breaking change, though, technically better than the existing behaviour. |
I can remove that commit, isn't the end of the world to have a I'm not sure this is best handled in the #560 -- its that weird middle ground for how do we agnostically treat extra JWT bearers that aren't from the main provider in a generic way. IE my case, I like my OIDC provider settings have the user-id claim to |
09df48d
to
7d5c8ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickMeves Can you just confirm this is good to go from your perspective, I believe it is and have no further comments
@steakunderscore I'd appreciate if you could also review this one before merging
rawIDToken, err := jwt.NewWithClaims(jwt.SigningMethodRS256, minimalIDToken).SignedString(key) | ||
assert.NoError(t, err) | ||
// Pass to a dummy Verifier to get an oidc.IDToken from the rawIDToken for our actual test below | ||
idToken, err := verifier.Verify(context.Background(), rawIDToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's got to be a cleaner way to get an oidc.IDToken
from a rawIDToken string...? Getting it through a dummy oidc.NewVerifier
worked, but just feels sloppy to me -- but nothing stood out to me when I tried to dig through oidc
🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is just a struct at the end of the day, you could theoretically construct it, but then you can't set the private methods. I think what you've done is probably the best we can do sadly
Yup, ready to go. I ran some manual tests in a local kubernetes environment and it looked good. Only area I had a lingering question is the new unit test I added that feels a little sloppy. |
7d5c8ff
to
3d29d24
Compare
3d29d24
to
0d190e9
Compare
Give me the heads up when we're ready and I'll rebase before the merge. I think I keep dismissing your reviews when I push up rebases 😄 |
I think let's just get this merged, can you rebase? |
When using the configured provider JWT Verifier, it makes sense to use the provider `CreateSessionStateFromBearerToken` method. For any extra JWT Issuers, they should use a generic default verifier.
0d190e9
to
a3eef17
Compare
When using the configured provider JWT Verifier, it makes
sense to use the provider
CreateSessionStateFromBearerToken
method. For any extra JWT Issuers, they should use a generic
default verifier.
#592
How Has This Been Tested?
Unit tests added for legacy/generic bearer IDToken -> SessionState.
TODO: deploy to a local kubernetes cluster and validate standard human OIDC with k8s service account tokens as an extra jwt issuer. UPDATE: DONE
Checklist: