Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation about PKCE #492

Closed
gargrag opened this issue Jul 8, 2020 · 23 comments
Closed

Improve documentation about PKCE #492

gargrag opened this issue Jul 8, 2020 · 23 comments

Comments

@gargrag
Copy link
Contributor

gargrag commented Jul 8, 2020

Hi, we are trying to adopt the tool, and we are struggling trying to configure PKCE with google auth, PKCE it's kind of new, we may not be fully getting it. But is it possible that you guys can help us configure that, so that we can contribute to the docs?

The issue now, is that without an auth provider, the app is not usable. We also detected that may be an inconsistency between the docs and the code with this env var

I also asked on a separate issue, and I tried reading the docs, but is still not clear, and I think this may be the case for the majority of the users.

Thanks

@johnbuhay
Copy link

johnbuhay commented Jul 9, 2020

Is anyone successfully using the PKCE plugin? We are getting 401 responses but no redirect or log detailing why. Here is what we have tried so far and what we have learned:

I have not confirmed yet what Authorized redirect URIs to list on the IDP side of things. Can you point us to this? What I have found is

window.location.protocol + "//" + window.location.host + "/implicit/callback"

dispatch configuration

DISPATCH_AUTHENTICATION_PROVIDER_SLUG=dispatch-auth-provider-pkce
DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS=https://www.googleapis.com/oauth2/v3/certs
VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT=https://accounts.google.com/.well-known/openid-configuration
VUE_APP_DISPATCH_AUTHENTICATOIN_PROVIDER_PKCE_CLIENT_ID=<IDP generated>.apps.googleusercontent.com

According to the documentation DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWK is necessary. I think you meant DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS and the type is incorrect/not specified? Although this URL is available in the .well-known/openid-configuration response

other resources:

@kevgliss
Copy link
Contributor

kevgliss commented Jul 9, 2020

Unfortunately, I believe every IDP will be a little bit different. I haven't personally tried to integrate with the Google IDP itself (we have an internal IDP based on Ping) so I don't have explicit directions however our hope is that in choosing PKCE as a standard we should be able to support any IDP that supports PKCE.

A few thoughts:

@gargrag @johnbuhay -- Yes, you're correct, the docs should say DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWKS not DISPATCH_AUTHENTICATION_PROVIDER_PKCE_JWK. See here

As far as what redirectURI to list, it's up to your IDP what they allow, some allow wildcarding i.e. you could whitelist the root of the app https://dispatch.example.net/* others will require a known callback so you would use https://dispatch.example.net/implicit/callback that should then forward you along.

You said you're receiving a 401, are you being forwarded to your IDP provider? Some things you could check:

Are you seeing successful requests to your openIdConnect issuer in your network tab? This call happends here

If you are getting redirected to your IDP, are you getting a code_verifier query parameter back? This is a query parameter unique to PKCE, if not it could point to a configuration issue on the IDP.

If it helps this is what the console looks like for a valid PKCE handshake:
2020-07-09_09-33

One last thing, looking at the google docs it looks like this is a lot closer to what I would expect:
https://developers.google.com/identity/protocols/oauth2/native-app

I know it's listed as a native app (which is confusing), but that's only because that is where folks typically use PKCE.

cc @willbengtson

@johnbuhay
Copy link

No, we do not get redirected to the IDP

I have verified the IDP configuration successfully using the /implicit/callbackauthorized_uri and https://github.com/aaronpk/pkce-vanilla-js

*Note: wildcard substitution for paths are not supported by Google OAuth clients

Screen Shot 2020-07-09 at 1 47 59 PM

@kevgliss
Copy link
Contributor

kevgliss commented Jul 9, 2020

Can you set a breakpoint here:
https://github.com/Netflix/dispatch/blob/develop/src/dispatch/static/dispatch/src/router/index.js#L27

And verify that you're entering the PKCE auth flow?

@kevgliss
Copy link
Contributor

kevgliss commented Jul 9, 2020

If you're building the JS app separately (i.e. not having the dispatch install do it for you). There are a few things you will have to do to get the var set correctly. Essentially you will need a .env available at build time for the frontend (it needs to exist in that dir). See: https://github.com/Netflix/dispatch/blob/develop/src/dispatch/static/dispatch/.env.example_vue_app

It could be we also need to specify VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_SLUG=dispatch-auth-provider-pkce in that particular file (to trigger that auth flow).

@willbengtson
Copy link
Contributor

VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_SLUG=dispatch-auth-provider-pkce is needed and verified we use the dispatch-auth-provider-pkce plugin here

@johnbuhay
Copy link

We are building using the provided Dockerfile. Adding the .env and updating the vars solved our issue where the PKCE flow was not being initiated. I missed that.

We now have a new issue where process.env.VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL in the debugger is unknown and AuthorizationServiceConfiguration fails to build the url.

Screen Shot 2020-07-09 at 3 57 14 PM

Now,
the /.env file looks like

DISPATCH_AUTHENTICATION_PROVIDER_SLUG="dispatch-auth-provider-pkce"
VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL="https://accounts.google.com"
VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_CLIENT_ID="<REDACTED>.apps.googleusercontent.com"

the /src/dispatch/static/dispatch/.env file looks like:

# Authentication
VUE_APP_DISPATCH_OPEN_ID_CONNECT_URL="https://accounts.google.com"
VUE_APP_DISPATCH_CLIENT_ID="<REDACTED>.apps.googleusercontent.com"
VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_SLUG="dispatch-auth-provider-pkce"

thanks for your help

@johnbuhay
Copy link

johnbuhay commented Jul 9, 2020

@kevgliss
Copy link
Contributor

kevgliss commented Jul 9, 2020

I wonder if we're missing a COPY for the ENV file at some point. I would have thought this would be enough:

https://github.com/Netflix/dispatch/blob/develop/docker/Dockerfile#L89

@johnbuhay
Copy link

I have discovered this VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT is unused.

It should be: VUE_APP_DISPATCH_AUTHENTICATION_PROVIDER_PKCE_OPEN_ID_CONNECT_URL

And the keys in .env.example_vue_app are only referenced in that file?

VUE_APP_DISPATCH_OPEN_ID_CONNECT_URL=""
VUE_APP_DISPATCH_CLIENT_ID=""

@johnbuhay
Copy link

johnbuhay commented Jul 9, 2020

I wonder if we're missing a COPY for the ENV file at some point. I would have thought this would be enough:

https://github.com/Netflix/dispatch/blob/develop/docker/Dockerfile#L89

It is enough and to verify I added RUN ls -lah /usr/src/dispatch/ && ls -lah /usr/src/dispatch/src/dispatch/static/dispatch/ && exit 1 to look for the .env during the build

@johnbuhay
Copy link

Status update:

After baking the client_id and oidc_url into a new container we are triggering the pkce plugin and redirect to the IDP for login.
We now get stuck on the /implicit/callback?...&prompt=consent.

Furthermore it seems the Google token retrieval requires client_secret, and I do not see anywhere we are providing that to dispatch.

Otherwise, it seems we will need to author a plugin to work with Google IDP...
https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#request-parameter-response_type

@kevgliss
Copy link
Contributor

We could add the ability to set the client_secret easily enough, according to the library we use to handle this flow (AppAuth) that "secret" isn't really a secret: openid/AppAuth-JS#46

Again, each IDP is a bit different. If you do wish to go down the road of having a different auth flow, I would be happy to merge something in if it makes it easier for folks to use the app.

@johnbuhay
Copy link

A few things to note

1 - I will try to get a PR merged in the openid/appauth library, that will probably take some time as other PR's seem to have stalled on the project. Currently, it is missing support for passing the optional client_secret to requests. I can understand why as the RFC6749#section-4.1.3 outlines.

2 - Creating Google OAuth credentials with Desktop type does not allow you to specify redirect_uri and are intentionally limited to "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"].

@johnbuhay
Copy link

johnbuhay commented Jul 15, 2020

Status update...

I have updated a private copy of the PKCEAuthPlugin to include the clientSecret option as an item in extras:{client_secret: xyz} for TokenRequest and it now does retrieve tokens from Google

EDIT: This now stands out as the access_token retrieved is not base64 decodable.

https://github.com/Netflix/dispatch/blob/develop/src/dispatch/static/dispatch/src/auth/pkceAuthProvider.js#L76

from the error thrown here

https://github.com/auth0/jwt-decode/blob/f904effc98e7555609cc22b994df5e2a4cb25455/lib/index.js#L19-L23

@mclueppers
Copy link

mclueppers commented Jul 28, 2020

@johnbuhay I'm trying to get Google OAuth2 working as well. Thanks for the advice so far. I got past successful login by changing access_token to id_token in the application:
https://github.com/Netflix/dispatch/blob/develop/src/dispatch/static/dispatch/src/auth/pkceAuthProvider.js#L76 becomes response.idToken

But now backend is failing authorisation with a valid JWT (verified signature etc. at jwt.io). I'm adding some debug logging to investigate further.

@mclueppers
Copy link

Alright, I finally got Google auth working after setting DISPATCH_JWT_AUDIENCE and disabling verify_at_hash JWT decode option. By the looks of it Google is adding at_hash in the response. I'm now trying to store somehow access_token that's required to verify at_hash. Cookie seems the best approach so far.

@gargrag
Copy link
Contributor Author

gargrag commented Aug 19, 2020

@mclueppers Can you please describe the steps you took to make google auth work?

@mclueppers
Copy link

@gargrag I've opened a PR #535 with the changes I had to make inside the application.

@gargrag
Copy link
Contributor Author

gargrag commented Aug 31, 2020

Thanks! @mclueppers It's working for me now. I think I'm going to implement this as a separate auth provider on our fork.

@mclueppers
Copy link

Thanks! @mclueppers It's working for me now. I think I'm going to implement this as a separate auth provider on our fork.

Great news. I'm waiting for the separate adapter, sounds like the best implementation approach.

@patcable
Copy link
Contributor

Just wanted to stop by and say this thread + PR #535 was indispensable in getting PKCE/OIDC working in my environment. I'll write up a blog post soon about it, but thanks for your help folks.

@kevgliss
Copy link
Contributor

Thanks to @patcable, I think we are in a better place re: pkce configuration. Closing this now, please open a new issue if you find any other gaps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants