Skip to content

Conversation

@gysel
Copy link
Contributor

@gysel gysel commented Dec 16, 2022

Some Identity Providers do not issue an updated ID Token when call the refresh endpoint.

This causes problems with the OIDC provider as it uses the ID Token to validate a session after a refresh.

I propose to validate the access token instead when --validate-url is set.

Description

Another solution would be to validate the ID token only during the initial session creation and skip the validation after the refresh. This seems to be the case with versions < v7.2.0.

Motivation and Context

Fixes #1640

How Has This Been Tested?

I use a similar version of this patch in production for several weeks now.

I will perform more tests on our side in the coming days.

Checklist:

  • My change requires a change to the documentation or CHANGELOG.
  • I have updated the documentation/CHANGELOG accordingly.
  • I have created a feature (non-master) branch for my PR.

@gysel gysel requested a review from a team as a code owner December 16, 2022 12:04
@gysel
Copy link
Contributor Author

gysel commented Dec 16, 2022

I will do more testing and update the CHANGELOG next week.

@JoelSpeed
Copy link
Member

I was under the impression that the whole point of a refresh token was to refresh the ID Token, which provider are you using out of interest?

@gysel
Copy link
Contributor Author

gysel commented Dec 23, 2022

I was under the impression that the whole point of a refresh token was to refresh the ID Token,

It is valid, according to the specification, to only refresh the access token and not the ID Token.

Upon successful validation of the Refresh Token, the response body is the Token Response of Section 3.1.3.3 except that it might not contain an id_token.
Source: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse

which provider are you using out of interest?

We use oauth2-proxy with multiple customer and several IdPs. We found this problem so far only with Ping Identity.

@ghost
Copy link

ghost commented Dec 29, 2022

@r-kotagudem
Copy link

r-kotagudem commented Jan 5, 2023

@gysel gysel could you help with docker image of binary built from your fix branch hosted on docker hub?

@gysel
Copy link
Contributor Author

gysel commented Jan 6, 2023

@r-kotagudem I would not use binaries built by random strangers on the internet ;) You can easily build your own images, the Docker command to do so is in the Makefile (https://github.com/oauth2-proxy/oauth2-proxy/blob/master/Makefile#L55).

@r-kotagudem
Copy link

@r-kotagudem I would not use binaries built by random strangers on the internet ;) You can easily build your own images, the Docker command to do so is in the Makefile (https://github.com/oauth2-proxy/oauth2-proxy/blob/master/Makefile#L55).

thanks, my system had some docker related environment issues. and wanted to test with your changes.

@github-actions
Copy link
Contributor

This pull request has been inactive for 60 days. If the pull request is still relevant please comment to re-activate the pull request. If no action is taken within 7 days, the pull request will be marked closed.

@github-actions github-actions bot added the Stale label Mar 11, 2023
@gysel
Copy link
Contributor Author

gysel commented Mar 17, 2023

this is still relevant to us

@JoelSpeed JoelSpeed removed the Stale label Mar 23, 2023
@mjgp2
Copy link

mjgp2 commented May 3, 2023

Can we get this merged?

@gysel gysel force-pushed the oidc-validate-session branch from a4b1856 to ce03d76 Compare May 23, 2023 09:02
@gysel
Copy link
Contributor Author

gysel commented May 23, 2023

This is ready to be merged IMHO. Please let me know in case I should do any other changes.

@github-actions
Copy link
Contributor

This pull request has been inactive for 60 days. If the pull request is still relevant please comment to re-activate the pull request. If no action is taken within 7 days, the pull request will be marked closed.

@github-actions github-actions bot added the Stale label Jul 24, 2023
@gysel
Copy link
Contributor Author

gysel commented Jul 24, 2023

still relevant

@github-actions github-actions bot removed the Stale label Jul 25, 2023
CHANGELOG.md Outdated
- [#1988](https://github.com/oauth2-proxy/oauth2-proxy/pull/1988) Ensure sign-in page background is uniform throughout the page
- [#2013](https://github.com/oauth2-proxy/oauth2-proxy/pull/2013) Upgrade alpine to version 3.17.2 and library dependencies (@miguelborges99)
- [#2047](https://github.com/oauth2-proxy/oauth2-proxy/pull/2047) CVE-2022-41717: DoS in Go net/http may lead to DoS (@miguelborges99)
- [#2047](https://github.com/oauth2-proxy/oauth2-proxy/pull/1933) Validate a session using the access token in the OIDC provider (@gysel)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do a rebase of your branch with the master and move this to the latest changes since section

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

err := p.checkNonce(s)
if err != nil {
logger.Errorf("nonce verification failed: %v", err)
return false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i personally would prefer the direct return

Copy link
Contributor Author

@gysel gysel Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a direct return but then code climate complained about too many returns. (see 64dd780) Should I change it back?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A yes you are right code climate is quite strict at the moment. Leave it as is for now!

@tuunit
Copy link
Member

tuunit commented Sep 9, 2023

I was under the impression that the whole point of a refresh token was to refresh the ID Token, which provider are you using out of interest?

According to the OIDC specification the refresh tokens are used to refresh the access tokens.
https://openid.net/specs/openid-connect-core-1_0.html#RefreshingAccessToken

Furthermore, as described in section 12.2 Successful Refresh Response the Token Response might not contain an id_token. My understanding is that their currently is not enforced specification in place on how to refresh the id_token. Some providers might provide new id_tokens but some might need to retrigger the authentication flow once more.

Therefore, the solution in this PR seems like kind of a workaround to me. Should the refresh empty the id_token in the current session if no new id_token has been provided? I think we might need to change the refresh flow instead of switching between the access or id token for validation.

@tuunit
Copy link
Member

tuunit commented Sep 9, 2023

@gysel do you by any chance still have a record or know which error you got after the refresh during the token validation?

@gysel
Copy link
Contributor Author

gysel commented Sep 11, 2023

@gysel do you by any chance still have a record or know which error you got after the refresh during the token validation?

I added the error message here: #1640 (comment)

I just verified it again, we only use the access_token for this customer and hence do not care when the id_token is expired.

Therefore, the solution in this PR seems like kind of a workaround to me. Should the refresh empty the id_token in the current session if no new id_token has been provided? I think we might need to change the refresh flow instead of switching between the access or id token for validation.

Good question... I think I'd rather have an expired id_token in the backend than none - but I'm not certain what makes more sense. A solution would also be to print a warning in the log and remove the id_token from the session.
Maybe a validation of the id_token is the wrong approach when the standard does not guarantee that you always have a valid ID token.

@gysel gysel force-pushed the oidc-validate-session branch from 5c894c3 to 92a8814 Compare September 11, 2023 09:58
@tuunit
Copy link
Member

tuunit commented Sep 19, 2023

According to the OIDC specification the refresh tokens are used to refresh the access tokens.
https://openid.net/specs/openid-connect-core-1_0.html#RefreshingAccessToken

Furthermore, as described in section 12.2 Successful Refresh Response the Token Response might not contain an id_token. My understanding is that their currently is not enforced specification in place on how to refresh the id_token. Some providers might provide new id_tokens but some might need to retrigger the authentication flow once more.

Therefore, the solution in this PR seems like kind of a workaround to me. Should the refresh empty the id_token in the current session if no new id_token has been provided? I think we might need to change the refresh flow instead of switching between the access or id token for validation.

Error:

2022-06-27 09:00:37.070 CEST
xxx - 7ff73c70-1a39-40fb-afe4-1164b7a0b700 - xxx@xxx.com [2022/06/27 07:00:37] [AuthSuccess] Authenticated via OAuth2: Session{email:xxx@xxx.com user: PreferredUsername: token:true id_token:true created:2022-06-27 07:00:37.069415957 +0000 UTC m=+325920.006154842 expires:2022-06-27 08:00:36.026393118 +0000 UTC m=+329518.963131992 refresh_token:true}
2022-06-27 10:00:40.317 CEST
[2022/06/27 08:00:40] [stored_session.go:189] Refreshing session - User: ; SessionAge: 1h0m2.930584043s
2022-06-27 10:00:40.471 CEST
[2022/06/27 08:00:40] [oidc.go:87] id_token verification failed: failed to verify token: oidc: token is expired (Token Expiry: 2022-06-27 08:00:36 +0000 UTC)

So the issue occurs when the id_token expires because Ping ID doesn't refresh the id_token with the refresh endpoint. Therefore, the proper solution would be to invalidate / delete the current session to enforce the authentication flow once more. What are your thoughts on this @JoelSpeed @gysel @braunsonm ?

@gysel
Copy link
Contributor Author

gysel commented Sep 19, 2023

Therefore, the proper solution would be to invalidate / delete the current session to enforce the authentication flow once more.

In this particular case the access_token is a JWT and we don't use the id_token at all. I believe this is a valid scenario and the IdP just confirmed the session to be still valid. Why would we want to do a full authentication flow?

@kvanzuijlen kvanzuijlen requested a review from tuunit October 25, 2023 17:10
@github-actions
Copy link
Contributor

This pull request has been inactive for 60 days. If the pull request is still relevant please comment to re-activate the pull request. If no action is taken within 7 days, the pull request will be marked closed.

@github-actions
Copy link
Contributor

This pull request has been inactive for 60 days. If the pull request is still relevant please comment to re-activate the pull request. If no action is taken within 7 days, the pull request will be marked closed.

@github-actions github-actions bot added the Stale label Mar 31, 2024
@tuunit tuunit removed the Stale label Mar 31, 2024
@github-actions
Copy link
Contributor

github-actions bot commented Jun 1, 2024

This pull request has been inactive for 60 days. If the pull request is still relevant please comment to re-activate the pull request. If no action is taken within 7 days, the pull request will be marked closed.

@github-actions github-actions bot added the Stale label Jun 1, 2024
@alexeytokar
Copy link

Bump

@github-actions github-actions bot removed the Stale label Jun 6, 2024
@github-actions
Copy link
Contributor

This pull request has been inactive for 60 days. If the pull request is still relevant please comment to re-activate the pull request. If no action is taken within 7 days, the pull request will be marked closed.

@github-actions github-actions bot added the Stale label Aug 24, 2024
@github-actions github-actions bot closed this Sep 2, 2024
@tuunit tuunit reopened this Sep 15, 2024
@tuunit tuunit removed the Stale label Sep 15, 2024
@timmalich
Copy link

Still relevant for us too

@tuunit
Copy link
Member

tuunit commented Sep 30, 2024

Reminder to myself to finally get this merged and done once for all.

@tuunit

@tuunit tuunit added this to the next milestone Jan 4, 2025
@tuunit tuunit removed this from the next milestone Jan 12, 2025
Copy link
Member

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of interest, do we have a link to the appropriate place in the OIDC spec that allows IDPs to not return a new ID Token? I believe it's there but would be useful to link to in a code comment I think

Comment on lines 108 to 127
if !validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) {
logger.Errorf("access token is invalid")
return false
}
return true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the log here? Or should we just return?

Suggested change
if !validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) {
logger.Errorf("access token is invalid")
return false
}
return true
return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken))

@Orange-Rabbit
Copy link

Out of interest, do we have a link to the appropriate place in the OIDC spec that allows IDPs to not return a new ID Token? I believe it's there but would be useful to link to in a code comment I think

@JoelSpeed
I found this part of the OIDC specification: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse
I looked at the latest final version of OpenID Connect Core from openid.net

I would love to see this fixed, but I am not confident enough with GO unfortunately :/

@jholt96
Copy link

jholt96 commented Apr 9, 2025

Is this still being worked? My company is being blocked by this issue and would love to see this merged. Happy to assist in any way

…IDC provider

Signed-off-by: Jan Larwig <jan@larwig.com>
@tuunit tuunit force-pushed the oidc-validate-session branch from 5f06a29 to 5d9c175 Compare November 8, 2025 12:43
@tuunit
Copy link
Member

tuunit commented Nov 8, 2025

Hi all,

really sorry this was open for years. To be honest I just lost track of it over and over again. As @JoelSpeed and me are only working on the project voluntarily and don't have any allotted time from our employers it is hard to keep things on track. With OAuth2 Proxy joining the CNCF, we try to get an initiative started to get the project more streamlined and more people on board to triage and review issues and PRs.

For now this PR is finally merged.

@tuunit tuunit merged commit 22053dc into oauth2-proxy:master Nov 8, 2025
4 checks passed
@gysel
Copy link
Contributor Author

gysel commented Nov 20, 2025

Hey @tuunit,

Many thanks for wrapping up this change.

I tested this now and found two issues:

  1. s.Refreshed is always false and hence the new refresh handling is never used.
  2. ValidateURL is, by default, not configured for OIDC providers. This makes the access token validation fail unless you configure a token validation change.

I opened #3267 with a proposed fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

9 participants