int128/kubelogin

Flag to force PKCE

g-psantos opened this issue · 7 comments

Purpose of the feature (why)

The purpose of this feature request is to enable authentication against OIDC providers that support the Authorization Code+PKCE flow but fail to publish the code_challenge_methods_supported value in their metadata document.

While the failure to publish this value is non-compliant with RFC8414, at least one major identity provider, Azure AD, is in this situation. As documented here, Azure AD does in fact support PKCE.

As a result of #283, kubelogin does not use PKCE when the value is missing from the metadata document, even if the --oidc-use-pkce flag is used.

Your idea (how)

Because PKCE is so important when authenticating with public clients such as kubelogin, I would propose that the --oidc-use-pkce flag be updated as follows:

  • The default behavior would remain as is, where kubelogin looks up the metadata document and determines if PKCE is supported and which PKCE method to use.
  • An additional behavior would be introduced, where the user could specify the challenge method manually, e.g. --oidc-use-pkce=S256. In this case, kubelogin would ignore what is said in the metadata document and accept the user's instruction.

Would be really nice if it s possible to use PKCE flow with Azure-AD. Client-Secrets in kubeconfigs aren't beautiful. 😥

It seems that auth code + pkce can't be used on Azure with this plugin in that case. I think, new flag(e.g. --oidc-force-pkce) can be introduced to force pkce usage. WDYT? @int128. Thanks.

ch9hn commented

We digged a bit in the deeper into this issue and found out that the PKCE flags are actually send in the version of Kubelogin oidc-login v1.28.0.

When we do the oidc setup with the following command:

kubectl oidc-login setup -v1 \
--oidc-use-pkce \
--oidc-issuer-url https://login.microsoftonline.com/<tenant-id>/v2.0 \
--oidc-client-id <client-id> \
--skip-open-browser

we get the following URL:

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?
access_type=offline&
client_id=<client-id>&
code_challenge=<code challenge>&
code_challenge_method=S256&
nonce=<nonce>&
redirect_uri=http%3A%2F%2Flocalhost%3A8000&
response_type=code&
scope=openid&
state=<state>

You see that code_challenge_method=S256 is sent.

The following line also supports this:
https://github.com/int128/kubelogin/blob/master/pkg/oidc/client/factory.go#L63

But something in the back is not working properly, which we did not find out yet.

That is very good news. Thanks for investigating this @ch9hn !

ch9hn commented

Can someone of you test, if setting the application as "SPA - Single Web Application" works then with the PKCE ?

According to that blog entry it should work.
https://medium.com/@shoaib.alam/part-4-oauth-2-0-pkce-flow-with-azure-ad-cc225c0ed9f6

When I follow the flow of the blog with Postman, I get the same error as in kubelogin:

{
    "error": "invalid_client",
    "error_description": "AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. Trace ID: xxxxx Correlation ID: fce85109-9798-48c1-87a4-c6cc9804a711 Timestamp: xxxxxx",
    "error_codes": [
        7000218
    ],
    "timestamp": "2023-11-23 17:28:06Z",
    "trace_id": "xxxxx",
    "correlation_id": "xxxxx",
    "error_uri": "https://login.microsoftonline.com/error?code=7000218"
}

@ch9hn
image

kubectl oidc-login get-token --oidc-issuer-url=https://login.microsoftonline.com/<tenant_id>/v2.0 --oidc-client-id=<client_id> --oidc-use-pkce
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" "AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests. Trace ID: f7bf1c57-5044-4499-9350-9ca5db0d2400 Correlation ID: e1ff0cc8-d1b9-43a0-ae8e-4eb0e7cb2fe7 Timestamp: 2024-01-18 13:11:56Z"
Error: exit status 1

I am getting the same error as @oskarm93 when using kubelogin with an Azure AD "Single Page Application" and PKCE. I believe the error can be resolved by including an Origin header in the HTTP request (based off AzureAD/microsoft-authentication-library-for-js#2482 and some other online resources).

Can we add this header to these requests to resolve this issue? How should we go about configuring this? Add a config flag to support CORS overall (not sure how much effort this would take)? Add a config flag to add the Origin header on this request (and maybe others)? Just always include the Origin header on this requests (and maybe others)?

I opened #1048 for this issue in particular. It appears that I was able to workaround this limitation my changing the Azure application from a "Single Page Application" to a "Mobile and desktop applications". See #1048 (comment) for some more details.