Outdated Google Endpoints can prevent authentication and token refresh
Hi,
I set up a proxy yesterday, as a backend behind a internal Traefik proxy to transparently handle Google OIDC authentication to the Kubernetes Dashboard. After some searching and using the fork discussed in https://github.com/bitly/oauth2_proxy/pull/621 to provide the Authentication Bearer header to the dashboard, I managed to get the token into the Kubernetes dashboard.
However, it gave me an "Unauthorized error". Decoding the JWT, I noticed that the token provided by the oauth2_proxy had a payload with "iss": "accounts.google.com" while the Kubernetes API was expecting an issuer with value https://accounts.google.com. (Kubernetes does not allow you to set issuers with a non-https scheme, nor is it supported in the OIDC spec I learned afterwards). Setting my Issuer URL manually to -oidc-issuer-url=https://accounts.google.com fixed this and made the authentication work seamlessly.
I noticed throughout the day though that once my token expired, I would have to fully refresh the page to get a new login screen, similar to what was discussed in https://github.com/bitly/oauth2_proxy/issues/218. I started digging and noticed that in my logs, it looked like the refresh of the token never happened, nor that my session even had a refresh token. My log looked like this:
2018/07/17 15:06:14 oauthproxy.go:727: 100.96.11.156:53926 ("100.96.11.1") refreshing 1h16m18s old session cookie for Session{email:[email protected] user:bruno token:true id_token:true expires:2018-07-17 14:49:55 +0000 UTC} (refresh after 1h0m0s)
2018/07/17 15:06:15 oauthproxy.go:741: 100.96.11.156:53926 ("100.96.11.1") removing session. token expired Session{email:[email protected] user:bruno token:true id_token:true expires:2018-07-17 14:49:55 +0000 UTC}
Note the absence of refresh_token:true, something you can also see in several logs posted in issue 218. Digging further, I realized that by overriding the issuer-url, the login URL also switched to the auto-discovered one (https://github.com/bitly/oauth2_proxy/blob/master/options.go#L152-L161) which lacks the access_type=offline necessary for Google to provide a refresh token (https://github.com/bitly/oauth2_proxy/blob/master/providers/google.go#L37-L38).
Doing some searches online, it looks like Google did not stick to the OIDC spec very closely with their endpoints:
- https://github.com/coreos/go-oidc/pull/132
- https://github.com/kubernetes/kubernetes/pull/58544#issuecomment-360680560
However, the latest endpoints have this fixed:
- https://stackoverflow.com/a/40800830
So a few issues:
- Overriding the Issuer URL kicks in the auto-discovery, which might impact the RedeemURL and ValidateURL in ways you do not expect it.
- The endpoints used in the Google provider are outdated and do not stick to the OIDC spec. In my own usecase, overriding the RedeemURL and ValidateURL to the latest endpoints (
-redeem-url=https://www.googleapis.com/oauth2/v4/tokenand-validate-url=https://www.googleapis.com/oauth2/v3/tokeninfo) instead of the IssuerURL seemingly fixes my refresh and authentication issues, with no side-effects so far. However, I would think other users might expect the issuer to not have the https scheme by now?
I am happy to open a PR to update the endpoints, but wanted to get some eyes on my findings first.