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

JWT bearer passthrough #65

Merged
merged 18 commits into from
Jun 21, 2019
Merged

Conversation

brianv0
Copy link
Contributor

@brianv0 brianv0 commented Feb 14, 2019

Description

Adds support to skip JWT bearer tokens, when the issuer is either the configured issuer (if using an OIDC issuer) or a set of additional JWT issuers.

Motivation and Context

This is an implementation for #18.

How Has This Been Tested?

Tested in a kubernetes environment.

You need to get your token. An easy thing to do is to deploy an application behind oauth2_proxy that just prints it, then you can grab that token and re-request the same URL. Other than that, you can get it from the oauth2_proxy container, if it's running. For example, in kubernetes:

kubectl exec -it oauth2-proxy-4444444444-qrstu /bin/sh
apk add --update tcpdump
tcpdump -A -s 0 'tcp and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -i eth0

...then look for X-Auth-Request-Token, assuming you configured oauth2_proxy with -pass-authorization-header.

From there, you can just do something like the following:

curl --header "Authorization: Bearer $TOKEN" https://example.com/my-protected-page

Checklist:

  • My change requires a change to the documentation or CHANGELOG.
  • I have updated the documentation/CHANGELOG accordingly.
  • I have created a feature (non-master) branch for my PR.

@brianv0 brianv0 force-pushed the jwt_bearer_passthrough branch from 6e31fb3 to fac781b Compare February 14, 2019 23:22
@brianv0 brianv0 marked this pull request as ready for review February 14, 2019 23:39
@brianv0 brianv0 requested a review from a team February 14, 2019 23:39
@JoelSpeed
Copy link
Member

Looks like some tests are failing, could you try rebasing onto our master branch and see if that fixes the issue?

@brianv0 brianv0 force-pushed the jwt_bearer_passthrough branch from 9372ff3 to 9470608 Compare March 2, 2019 21:02
@GuillaumeSmaha
Copy link

GuillaumeSmaha commented Mar 3, 2019

@brianv0 By the way, you did a great work. I tried it, it is perfect and -extra-jwt-issuers is very useful.

@meastman
Copy link

meastman commented Mar 5, 2019

I tried this as well and it worked great. However, I'm using -provider=google (with client id specified in an environment variable if it matters), and I did have to explicitly add -extra-jwt-issuers=https://accounts.google.com=$OAUTH2_PROXY_CLIENT_ID rather than it automatically using my configured provider.

@GuillaumeSmaha
Copy link

GuillaumeSmaha commented Mar 5, 2019

@meastman It seems the o.oidcVerifier is only defined when o.OIDCIssuerURL is defined with -oidc-issuer-url.
https://github.com/pusher/oauth2_proxy/blob/9470608c4ca9c2a3d9e153fc8cbd35d491954f5b/options.go#L167-L181

Try to add -oidc-issuer-url https://accounts.google.com instead of -extra-jwt-issuers=https://accounts.google.com=$OAUTH2_PROXY_CLIENT_ID

But maybe oidc should be automatically defined for google provider

@meastman
Copy link

meastman commented Mar 5, 2019

Try to add -oidc-issuer-url https://accounts.google.com instead of -extra-jwt-issuers=https://accounts.google.com=$OAUTH2_PROXY_CLIENT_ID

👍 That worked great.

But maybe oidc should be automatically defined for google provider

Agreed. I just wanted to mention it so it could at least be considered.

@brianv0
Copy link
Contributor Author

brianv0 commented Mar 8, 2019

I've been meaning to get back to this soon, I don't understand what the travis error was - it looks like it was transient.

I think it's the case that Google, Azure are both technically OIDC providers but under a different name. Since Google is sort of special it could be considered so you don't have to explicitly list it.

@logicfox
Copy link

@brianv0 Have you had a chance to look into this PR? I'd love to get this merged to master and start securing my API endpoint with oauth2_proxy. This is a feature that many people have been waiting for for a long time. Let me know if you need help with testing it.

@brianv0 brianv0 force-pushed the jwt_bearer_passthrough branch from 9470608 to 21e10a9 Compare April 27, 2019 02:42
@brianv0
Copy link
Contributor Author

brianv0 commented Apr 27, 2019

I've done a new round on this and also added some unit tests. @JoelSpeed if you wouldn't mind re-reviewing this?

@vidaks
Copy link

vidaks commented Apr 29, 2019

Will this patch make it possible to authenticate using only a "bearer token" (JWT) from an Authorization header, e.g no cookies?

I built a custom image with this patch, but get Cookie "_oauth2_proxy" not present. Seems like it still requires cookies? I have added the proxy in front of an API and want to authenticate using the Authorization header and not rely on cookies for backend services.

@brianv0
Copy link
Contributor Author

brianv0 commented Apr 29, 2019

Yes, do you have the proper flags set by chance? What Provider are you using?

I started adding some more complete tests to make sure I’m sane, but it seems fine to me.

@vidaks
Copy link

vidaks commented Apr 30, 2019

Hi, I am using an OIDC provider (keycloak) and have set skip_jwt_bearer_tokens = true in the configuration for the API.

My setup is like this. I got an OAuth2 proxy setup protecting the frontend which basically follows the Nginx example in the README. But with an additional "location" for an "upstream" API (this is setup in k8s). This OAuth2 proxy is configured to "pass" the authorization header on a call to upstream (nginx). The idea was to have another OAuth2 proxy in front of the (nginx) upstream API and use a bearer token only validation. In order to ensure that the proxy in front of the API only authenticates using validation of the JWT I have explicitly removed the "oauth2" cookies issued by the frontend proxy before proxying traffic to the upstream API (I hope that explanation made sense).

@brianv0
Copy link
Contributor Author

brianv0 commented Apr 30, 2019

I added what should be a more realistic test case for that in b3135e8, and it seems to be working just fine. I will be testing this out today on my own environment (it's been a little slow on this I need some other unrelated patches).

Copy link
Member

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @brianv0, there's a few comments outstanding on this one, please take a look

@brianv0 brianv0 force-pushed the jwt_bearer_passthrough branch from 1574ed9 to a526126 Compare May 1, 2019 17:22
@brianv0
Copy link
Contributor Author

brianv0 commented May 1, 2019

Okay I think addressed all the relevant issues and I did a rebase to pull in the new logging changes

@vidaks
Copy link

vidaks commented May 3, 2019

This patch works for me, but only in "proxy" mode. I could not figure out why neither refresh tokens or JWT validation did not work in "auth_request" mode despite following suggested work arounds for header size limits, but it's indicative that the issue I had was outside the scope of this patch.

@brianv0
Copy link
Contributor Author

brianv0 commented May 3, 2019

Ah okay, so this is something I didn’t touch. The Authorization headed is only forwarded on proxy requests, and includes the Bearer prefix. In auth_request mode, you get a X-Auth-Request-Token back, without the prefix. Presumably most people are fine with this because it’s easy to add the header from the upstream (oauth2_proxy response):

auth_request_set $auth_token $upstream_http_x_auth_request_token;       
proxy_set_header Authorization "Bearer $auth_token";

I would note that this is useful when other backends also expect some kind of header.

I could add code to return the authorization header too, I will have to look and see if there was a reason why they didn’t do that originally though.

@JoelSpeed
Copy link
Member

The Authorization headed is only forwarded on proxy requests, and includes the Bearer prefix.

Just to chip in here as I authored the Authorization header stuff; If you set -pass-authorization-header then you get the Authorization: Bearer <token> header on requests to proxied services; If you set -set-authorization-header then it should be set on the response headers so will be available in the Nginx auth_request mode.
https://github.com/pusher/oauth2_proxy/blob/8519e7ccae466bac8722411cc7cf43ef7bd6f56e/oauthproxy.go#L934-L936

@GuillaumeSmaha
Copy link

@brianv0 Can you update for the conflict ?
@JoelSpeed Will it be possible to merge this after the conflict resolution ?

@brianv0 brianv0 mentioned this pull request May 20, 2019
3 tasks
Copy link
Member

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brianv0 I've left a comment below about a security concern when decoding the JWT, could you please verify and fix if my concerns are correct. Otherwise I'm happy with this PR and we should be good to merge soon

@brianv0 brianv0 force-pushed the jwt_bearer_passthrough branch from 311a220 to 5a50f62 Compare June 17, 2019 19:59
@brianv0
Copy link
Contributor Author

brianv0 commented Jun 21, 2019

@JoelSpeed - I added an extra check to always validate the groups, if possible, of the token, based on #141, in bd651df.

It's not clear to me if this check will actually ever be executed - only the Google provider does a group check and I'm not sure if there's an easy way to get a bearer token from Google in any case, but I figured it might be surprising if that was the case.

(PS - this shows a change is requested, but I believe the previous changes were already applied)

Copy link
Member

@JoelSpeed JoelSpeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good now, thanks for all your work on this @brianv0!!!

@JoelSpeed JoelSpeed merged commit 317f09f into oauth2-proxy:master Jun 21, 2019
Jing-ze pushed a commit to Jing-ze/oauth2-proxy that referenced this pull request Nov 19, 2024
T-vK pushed a commit to T-vK/oauth2-proxy that referenced this pull request Nov 20, 2024
* fix google service-account.json secret generation

* bump chart version to 5.0.3

* base64 encode the secret value as expected by k8s

* bump chart version to 5.0.4
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

Successfully merging this pull request may close these issues.

7 participants