kubelogin icon indicating copy to clipboard operation
kubelogin copied to clipboard

could not refresh the token: id_token is missing in the token response

Open haarchri opened this issue 5 years ago • 4 comments

Describe the question

could not refresh the token: id_token is missing in the token response:

When I perform the code exchange on my oidc provider endpoint after successful authentication, I do correctly get back a response with the access_token, id_token and refresh_token that I require.

However, when I make a request for refresh_token, I only ever get back an access_token, not an id_token - is there a solution to skip id_token for refresh or is it really needed ?

Your environment

  • OS: macOS
  • kubelogin version v1.23.0
  • kubectl version: v1.21.0
  • OpenID Connect provider: F5

haarchri avatar Apr 19 '21 07:04 haarchri

We are facing the same issue: could not refresh the token: id_token is missing in the token response.

Our setup is as follows: We use a confidential Azure App registration that issue an ID token. The app is registered as "Mobile and Desktop application" because we want to avoid client secrets and use PKCE. This token is used to authenticate to an AWS EKS cluster. The kubeconfig looks like this:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <REDACTED>
    server: <REDACTED>
  name: testcluster
contexts:
- context:
    cluster: testcluster
    user: oidc
  name: testcluster
current-context: testcluster
kind: Config
preferences: {}
users:
- name: oidc
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=<REDACTED>
      - --oidc-client-id=<REDACTED>
      - --oidc-use-pkce
      - -v1
      command: kubectl
      env: null
      interactiveMode: IfAvailable
      provideClusterInfo: false

When the ID token expires, kubelogin is unable to refresh it when using --oidc-use-pkce. If we use --oidc-client-secret instead it works fine. A workaround is to manually delete the cache under ~/.kube/cache/oidc-login but thats not very practical. Here is the log:

I0522 08:51:03.631883    8239 get_token.go:52] WARNING: log may contain your secrets such as token or password
I0522 08:51:03.631911    8239 get_token.go:59] acquiring a lock get-token-8000-18000
I0522 08:51:03.631927    8239 get_token.go:71] finding a token from cache directory /home/testuser/.kube/cache/oidc-login
I0522 08:51:03.632068    8239 authentication.go:81] checking expiration of the existing token
I0522 08:51:03.632154    8239 authentication.go:96] you have an expired token at 2024-05-21 16:09:55 +0200 CEST
I0522 08:51:03.632161    8239 authentication.go:100] initializing an OpenID Connect client
I0522 08:51:03.882211    8239 authentication.go:107] refreshing the token
I0522 08:51:04.214676    8239 authentication.go:112] could not refresh the token: id_token is missing in the token response: &oauth2.Token{AccessToken:"...", TokenType:"Bearer", RefreshToken:"...", Expiry:time.Date(2024, time.May, 22, 9, 51, 3, 214475233, time.Local), raw:map[string]interface {}{"access_token":"...", "expires_in":"3599", "expires_on":"1716364264", "ext_expires_in":"3599", "refresh_token":"...", "token_type":"Bearer"}, expiryDelta:0}
I0522 08:51:04.214731    8239 browser.go:35] starting the authentication code flow using the browser
I0522 08:51:04.215158    8239 browser.go:104] opening http://localhost:8000 in the browser
I0522 08:51:04.215172    8239 server.go:36] oauth2cli: starting a server at 127.0.0.1:8000
Opening in existing browser session.
I0522 08:51:04.278777    8239 server.go:135] oauth2cli: sending redirect to https://login.windows.net/REDACTED/oauth2/authorize?access_type=offline&client_id=REDACTED&code_challenge=REDACTED&code_challenge_method=S256&nonce=REDACTED&redirect_uri=http%3A%2F%2Flocalhost%3A8000&response_type=code&scope=openid&state=REDACTED
I0522 08:51:05.083111    8239 server.go:66] oauth2cli: shutting down the server
I0522 08:51:05.083234    8239 server.go:47] oauth2cli: stopped the server
I0522 08:51:05.584299    8239 server.go:70] oauth2cli: force-closing the server: shutdown failed: context deadline exceeded
I0522 08:51:05.584555    8239 oauth2cli.go:156] oauth2cli: exchanging the code and token
error: get-token: authentication error: authcode-browser error: authentication error: authorization code flow error: oauth2 error: could not exchange the code and token: oauth2: "invalid_request" "AADSTS900144: The request body must contain the following parameter: 'client_id'. Trace ID: ... Timestamp: 2024-05-22 06:51:05Z" "https://login.windows.net/error?code=900144"
...

@int128 can you support on this?

  • OS: Ubuntu 22.04.4
  • kubelogin version: v1.28
  • kubectl version: v1.29.3
  • OpenID Connect provider: Azure

arodindev avatar May 22 '24 11:05 arodindev

OpenID Connect provider: Azure AD/ EntraID.

same situation ... any ideas/solutions?

I'd prefer --oidc-use-pkce, cause i do not need to create/update tokens and share them with a huge bunch of people.

markush81 avatar Aug 02 '24 10:08 markush81

OpenID Connect provider: Azure AD/ EntraID.

same situation ... any ideas/solutions?

I'd prefer --oidc-use-pkce, cause i do not need to create/update tokens and share them with a huge bunch of people.

Found a solution.

diff --git a/oauth2.go b/oauth2.go
index 09f6a49..591a4d9 100644
--- a/oauth2.go
+++ b/oauth2.go
@@ -224,6 +224,7 @@ func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOpti
        v := url.Values{
                "grant_type": {"authorization_code"},
                "code":       {code},
+               "client_id":     {c.ClientID},
        }
        if c.RedirectURL != "" {
                v.Set("redirect_uri", c.RedirectURL)
@@ -280,6 +281,7 @@ func (tf *tokenRefresher) Token() (*Token, error) {
        tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{
                "grant_type":    {"refresh_token"},
                "refresh_token": {tf.refreshToken},
+               "client_id":     {tf.conf.ClientID},
        })
 
        if err != nil {

As patch to https://pkg.go.dev/golang.org/x/oauth2

Plus .kube/config

- name: oidc
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://sts.windows.net/.../
      - --oidc-client-id=..
      - --oidc-extra-scope=offline_access # <<< 
      - --oidc-extra-scope=openid # <<<
      - --oidc-use-pkce
      command: kubectl
      env: null
      interactiveMode: IfAvailable
      provideClusterInfo: false

markush81 avatar Aug 02 '24 12:08 markush81

We switched using https://azure.github.io/kubelogin/topics/k8s-oidc-aad.html

markush81 avatar Feb 23 '25 06:02 markush81