int128 / kubelogin

kubectl plugin for Kubernetes OpenID Connect authentication (kubectl oidc-login)
Apache License 2.0
1.66k stars 191 forks source link

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

Open haarchri opened 3 years ago

haarchri commented 3 years ago

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

arodindev commented 3 months ago

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?

markush81 commented 1 month ago

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 commented 1 month ago

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 https://github.com/golang/oauth2/issues/734. But i have no clue if this change can be added to https://github.com/golang/oauth2 easily, because i am not sure about the offical API (just see how Azure behaves, not sure if right or not).

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