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

I can't get Authorization: Bearer <token> to work with version 6.1.1 . It works with 5.1.1 #773

Closed
ieugen opened this issue Sep 10, 2020 · 22 comments

Comments

@ieugen
Copy link

ieugen commented Sep 10, 2020

I've tried for several hours to make it work without success.

I've used it with keycloak provider and oidc provider.
I've tested with echoserver to see the Authorization: Bearer <> header and no luck.
I think it's broken.

I am working to configure authentication for kubernetes dashboard.

extraArgs:
  provider: 'oidc'
  upstream: http://echoserver.default
  pass-authorization-header: true
  pass-basic-auth: false
  skip-jwt-bearer-tokens: true
  ssl-upstream-insecure-skip-verify: true
  email-domain: '*'
  skip-provider-button: true
  oidc-issuer-url: "https://REDACTED/auth/realms/gpi-infra"
  login-url: "https://REDACTED/auth/realms/gpi-infra/protocol/openid-connect/auth"
  redeem-url: "https://REDACTED/realms/gpi-infra/protocol/openid-connect/token"
  validate-url: "https://REDACTED/auth/realms/gpi-infra/protocol/openid-connect/userinfo"
@NickMeves
Copy link
Member

Hmmm, 6.1.1 is working fine for me with bearer headers.

Some things I potentially see missing in your configuration that might be the source of your issue:

Even though you don't use it (since you want bearer header auth). cookie_secret is a required parameter. I believe the server won't start if you don't have a valid one set. You also have oidc set as your provider, so client_secret is also required (even though the mode you are about to use does use that either if you are getting IDTokens out of band). You can set both of those to dummy values.

You'll need a client_id that matches the audience claim of your token. In bearer header mode with the oidc provider, the code will first get a valid JWKS to validate your token from you oidc-issuer-url .well-known/openid-configuration or .well-known/jwks.json. Then it will verify your JWT against the appropriate JWKS (the single one in your case) based on the issuer+audience pair. Those being valid is a requirement of the upstream OIDC library's IDToken verify method if I recall.

Hopefully that helps -- I can't fully visualize your architecture or how you get the IDToken you send in the bearer header, but those are the settings I use to send IDTokens in bearer headers.

@ieugen
Copy link
Author

ieugen commented Sep 12, 2020

Hi,

Thannks for looking into this. I did pass client and cookie secret via kubernetes secrets

I did not realize this was not clear.
Like I mentioned it works with version 5 almost unchanged.
When i get back I will see if I can post the full yaml deployment.

@ghost
Copy link

ghost commented Sep 23, 2020

I ran in the same issue using oidc as a provider. IdP is an internal hosted keycloak instance.

You'll need a client_id that matches the audience claim of your token.

Do you refer to the id or access token?

Once I try to send a previously retrieved access or ID token as "Authorization: Bearer $token" I get:
The client ID created is "iap".
[2020/09/23 10:28:58] [oauthproxy.go:871] Error loading cookied session: Cookie "iap" not present ::1 - - [2020/09/23 10:28:58] localhost:8081 GET - "/" HTTP/1.1 "python-requests/2.24.0" 403 2621 0.000
The response is the "Sign-in" login page and not dispatching to the upstream.

The access token has the following aud set:
"aud": [ "iap, "broker", "account" ]

The ID token has the following aud set:
"aud": "iap"

@ghellings
Copy link

I'm having basically the same problem. Config works in v6.0.0 and doesn't after v6.1.0.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
      - args:
        - --client-id=REDACTED
        - --client-secret=REDACTED
        - --cookie-secure=false
        - --provider=google
        - --email-domain=*
        - --upstream=file:///dev/null
        - --http-address=0.0.0.0:4180
        - --cookie-refresh=1h
        - --skip-jwt-bearer-tokens=true
        - --request-logging=true
        - --auth-logging=true
        - --standard-logging=true
        - --redirect-url=https://REDACTED/oauth2/callback
        - --oidc-issuer-url=https://accounts.google.com
        - --pass-authorization-header=true
        - --whitelist-domain=.REDACTED

        env:
        - name: OAUTH2_PROXY_CLIENT_ID
          value: REDACTED.apps.googleusercontent.com
        - name: OAUTH2_PROXY_CLIENT_SECRET
          value: REDACTED
        - name: OAUTH2_PROXY_COOKIE_SECRET
          value: REDACTED
        image: quay.io/oauth2-proxy/oauth2-proxy:v6.0.0
        imagePullPolicy: Always
        name: oauth2-proxy
        ports:
        - containerPort: 4180
          protocol: TCP

V6.1.0 and above give me the following output, while v6.0.0 to v5.1.0 work

2020/09/30 22:54:41] [logger.go:488] mapping path "/dev/null" => file system "/dev/null"
[2020/09/30 22:54:41] [logger.go:488] Skipping JWT tokens from configured OIDC issuer: "https://accounts.google.com"
[2020/09/30 22:54:41] [logger.go:488] OAuthProxy configured for Google Client ID: REDACTED.apps.googleusercontent.com
[2020/09/30 22:54:41] [logger.go:488] Cookie settings: name:_oauth2_proxy secure(https):false httponly:true expiry:168h0m0s domains: path:/ samesite: refresh:after 1h0m0s
[2020/09/30 22:54:41] [logger.go:488] HTTP: listening on 0.0.0.0:4180
[2020/09/30 22:54:49] [logger.go:506] Error retrieving session from token in Authorization header: not implemented
[2020/09/30 22:54:49] [logger.go:506] Error loading cookied session: cookie "_oauth2_proxy" not present, removing session
100.119.128.9:33638 - - [2020/09/30 22:54:49] REDACTED GET - "/oauth2/auth" HTTP/1.1 "Ruby" 401 21 0.012

@NickMeves
Copy link
Member

Hmmm - there might be odd interactions with non-oidc providers (you have google set). It was the only Provider where the contributer implemented the CreateSessionStateFromBearerToken.

I'll need to dig, I believe that is ahead in the middleware chain before the generic extra JWT handlers (that assume OIDC and look for .well-known/openid-configuration). I don't fully know what the Google provider did with tokens in a bearer session pre-v6 (I'm not a google provider user)

Thanks for the details!

@knordum
Copy link

knordum commented Oct 20, 2020

Can also confirm I'm seeing the same issue where provider=keycloak.
Version 5.1.0 - 6.0.0 works ok, but version 6.1.1 gives error: Error retrieving session from token in Authorization header: not implemented

@NickMeves
Copy link
Member

I have a theory what's happening:

Because keycloak also uses some of the OIDC parameters, it goes down this codepath:

if o.OIDCIssuerURL != "" {

This results in SetOIDCVerifier being called (which makes the first extra-jwt issuer the provider instead of the generic extras):

o.SetOIDCVerifier(provider.Verifier(&oidc.Config{

If that's the case, the first provider in the chain is Keycloak's CreateSessionStateFromBearerToken:

if opts.GetOIDCVerifier() != nil {

Which isn't implemented.

As a workaround you can set the OIDC details you want to use to validate your sessions --extra-jwt-issuers (if anything in the chain passes, auth is valid, so it will just move past the Not Implemented).

Long term, a Keycloak user will need to implement CreateSessionStateFromBearerToken and submit a PR. If Keycloak is close to OIDC - the implementation will likely mirror that Provider

func (p *ProviderData) CreateSessionStateFromBearerToken(_ context.Context, _ string, _ *oidc.IDToken) (*sessions.SessionState, error) {

CC: @JoelSpeed - In case you have any other thoughts since you spearheaded the middlware auth chain refactor.

@NickMeves
Copy link
Member

Long term I have this as a vision for Bearer auth to avoid issues like this: #835

@NickMeves
Copy link
Member

I think the unifying point in all these cases is they have oidc-issuer-url + skip-jwt-bearer-tokens set on non OIDC providers that didn't implement the method (Google & Keycloak in the 2 submitted example bugs).

@harshitmahapatra
Copy link

harshitmahapatra commented Oct 21, 2020

I can confirm I got keycloak + v6.1.1 + skip-jwt-bearer-tokens working by removing --oidc-issuer-url from my config and adding --extra-jwt-issuers along with --oidc-jwks-url.

@JoelSpeed
Copy link
Member

I wonder if instead of ensuring providers implement CreateSessionStateFromBearerToken we could create a second interface that would allow us to identify the the provider supported this feature/had it implement. If they supported but hadn't implemented then we could use the default implementation. That or each provider should implement it themselves 🤔

Ultimately I think we want to support multiple providers and ensure that each provider has their own ability to create a session from a header token. Then users could access all of the provider options for the provider and we could potentially make these token only as well. I think we need some deeper thought about this feature as it's been mentioned a lot recently.

@NickMeves
Copy link
Member

Fixed in #869

@jonkerj
Copy link

jonkerj commented Feb 5, 2021

I really want to swap out keycloak-gatekeeper/louketo-proxy for something that actually is maintained, but I can't get oauth2-proxy to work with Kubernetes Dashboard, which is blocking this transition. Now that v7.0.0 is out, which contains #869, I still cannot get oauth2-proxy to pass the authorization bearer. Could very well be that I'm doing something wrong.

This is my config:

extraArgs:
  email-domain: "REDACTED"
  provider: "keycloak"
  login-url: "https://REDACTED/auth/realms/REDACTED/protocol/openid-connect/auth"
  redeem-url: "https://REDACTED/auth/realms/REDACTED/protocol/openid-connect/token"
  validate-url: "https://REDACTED/auth/realms/REDACTED/protocol/openid-connect/userinfo"
  upstream: "http://echo-server/"
  scope: "email"
  skip-provider-button: true
  skip-jwt-bearer-tokens: true
  pass-basic-auth: false
  pass-authorization-header: true

I randomly changed provider: "keycloak" to provider: "oidc" (and included an extra URL) but that did not help. I also tried with and without skip-jwt-bearer-tokens.

Am I missing something? Or is it still broken?

@Electrofenster
Copy link

Electrofenster commented Feb 14, 2021

@harshitmahapatra could you provide us which urls you used?

I struggle a lot because I don't know what I should put in --extra-jwt-issuers.
As everyone else I use keycloak and the newest version of oauth2-proxy.

When I don't use the --extra-jwt-issuers option I'll get this error:
[2021/02/14 10:23:13] [jwt_session.go:51] Error retrieving session from token in Authorization header: [unable to verify bearer token, oidc: expected audience "CLIENT_ID" got ["account"]]

below is my config what I'm currently running.

config:

command:
  - --provider=oidc
  - --client-id=CLIENT_ID
  - --client-secret=CLIENT_SECRET
  - --oidc-issuer-url=https://auth.domain.tld/auth/realms/MY_REALM
  - --login-url=https://auth.domain.tld/auth/realms/MY_REALM/protocol/openid-connect/auth
  - --redeem-url=https://auth.domain.tld/auth/realms/MY_REALM/protocol/openid-connect/token
  - --profile-url=https://auth.domain.tld/auth/realms/MY_REALM/protocol/openid-connect/userinfo
  - --validate-url=https://auth.domain.tld/auth/realms/MY_REALM/protocol/openid-connect/userinfo
  - --keycloak-group=/admin
  - --pass-basic-auth=false
  - --pass-access-token=true
  - --set-xauthrequest=true
  - --set-authorization-header=true
  - --pass-authorization-header=true
  - --skip-provider-button=true
  - --skip-auth-preflight=true
  - --pass-host-header=true
  - --skip-jwt-bearer-tokens=true
  - --oidc-jwks-url=https://auth.domain.tld/auth/realms/MY_REALM/protocol/openid-connect/certs
  - --extra-jwt-issuers=https://auth.domain.tld/auth/realms/MY_REALM

When I switch to version 6.1.1 I'll get without --extra-jwt-issuers the following error:

[2021/02/14 10:28:57] [logger.go:508] Error retrieving session from token in Authorization header: unable to verify jwt token: "Bearer MY_ACCESS_TOKEN"

EDIT: //
I've got it working with latest proxy

@mteodor
Copy link

mteodor commented Oct 12, 2021

@Electrofenster I dont get it how did you make it work with these configurations.
I wanted to configure oauth2-proxy with access token from Keycloak , so if I pass that token in authorization header when making and API request I expected to pass through however that didnt happen.
Here is my token that I got from keycloak

{
  "exp": 1634065121,
  "iat": 1634029121,
  "jti": "xxxxxx",
  "iss": "https://myauth.domain.com/auth/realms/master",
  "sub": "880628fa-70fa-4dd6-a1d0-7f2169f45613",
  "typ": "Bearer",
  "azp": "my.domain.com",
  "session_state": "3ade821d-374f-48d7-94c5-d82c78e3fbe5",
  "acr": "1",
  "allowed-origins": [
    "https://my.domain.com"
  ],
  "scope": "openid email profile",
  "sid": "3ade821d-374f-48d7-94c5-d82c78e3fbe5",
  "email_verified": true,
  "name": "My Name",
  "preferred_username": "my_username",
  "given_name": "name ",
  "family_name": "surname",
  "email": "name.surname@email.com"
}

when I set it as you did I get the following error

[2021/10/12 10:10:46] [main.go:54] invalid configuration:
invalid jwt verifier uri=audience spec: https://myauth.domain.com/auth/realms/master

when I changed to

--extra-jwt-issuers=issuer=https://auth.domain.tld/auth/realms/MY_REALM

then I get the following error:

[2021/10/12 10:09:39] [main.go:54] invalid configuration:
error building verifiers: error performing request: Get "issuer/.well-known/jwks.json": unsupported protocol scheme ""

it is not clear to me why adding an already specified issuer to a list of -extra-jwt-issuers should make it work

@pavan-pn
Copy link

pavan-pn commented Nov 3, 2021

@Electrofenster I dont get it how did you make it work with these configurations. I wanted to configure oauth2-proxy with access token from Keycloak , so if I pass that token in authorization header when making and API request I expected to pass through however that didnt happen. Here is my token that I got from keycloak

{
  "exp": 1634065121,
  "iat": 1634029121,
  "jti": "xxxxxx",
  "iss": "https://myauth.domain.com/auth/realms/master",
  "sub": "880628fa-70fa-4dd6-a1d0-7f2169f45613",
  "typ": "Bearer",
  "azp": "my.domain.com",
  "session_state": "3ade821d-374f-48d7-94c5-d82c78e3fbe5",
  "acr": "1",
  "allowed-origins": [
    "https://my.domain.com"
  ],
  "scope": "openid email profile",
  "sid": "3ade821d-374f-48d7-94c5-d82c78e3fbe5",
  "email_verified": true,
  "name": "My Name",
  "preferred_username": "my_username",
  "given_name": "name ",
  "family_name": "surname",
  "email": "name.surname@email.com"
}

when I set it as you did I get the following error

[2021/10/12 10:10:46] [main.go:54] invalid configuration:
invalid jwt verifier uri=audience spec: https://myauth.domain.com/auth/realms/master

when I changed to

--extra-jwt-issuers=issuer=https://auth.domain.tld/auth/realms/MY_REALM

then I get the following error:

[2021/10/12 10:09:39] [main.go:54] invalid configuration:
error building verifiers: error performing request: Get "issuer/.well-known/jwks.json": unsupported protocol scheme ""

it is not clear to me why adding an already specified issuer to a list of -extra-jwt-issuers should make it work

did you get this working?

@Electrofenster
Copy link

@pavan-pn as it's a very long time ago, I can't remember what I've done.

But I switched to https://github.com/travisghansen/external-auth-server because with oauth2-proxy it's not possible to check on every request if an accessToken is valid or not.

@J3m5
Copy link

J3m5 commented Nov 3, 2021

@Electrofenster Would the #1397 PR meet your needs ?

@lknite
Copy link

lknite commented Apr 11, 2022

Running into this with keycloak, everything latest and greatest:

[2022/04/11 00:44:04] [oauthproxy.go:730] Error creating session during OAuth2 callback: oidc: expected audience "kubernetes-dashboard" got ["account"]

snippit from kubernetes deployment:

    spec:
      containers:
      - args:
        #- --upstream="file:///dev/null"
        - --http-address=0.0.0.0:4180
        - --provider=keycloak-oidc
        - --client-id=kubernetes-dashboard
        - --client-secret=<client-secret>
        - --redirect-url=https://dashboard.<domain>/oauth2/callback
        - --oidc-issuer-url=https://keycloak.<domain>/auth/realms/<realm>
        - --provider-ca-file=/etc/ssl/certs/ca-certificates.crt
        - --email-domain=*
        - --insecure-oidc-allow-unverified-email
        - --scope=openid

Is the solution still to use extra-jwt-issuers?

@lasith011
Copy link

lasith011 commented Apr 28, 2022

Came across a similar issue with the newest version but was able to work it out. (keycloak:17.0.1)

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
      - args:
        - --provider=keycloak-oidc
        - --client-id=mlflow_ts
        - --client-secret=0UHvqmD1t2LZ5nymgr8DiFWsYRE80V0D
        - --email-domain=*
        - --upstream=file:///dev/null
        - --http-address=0.0.0.0:4180
        - --ssl-insecure-skip-verify=true
        - --oidc-issuer-url=https://keycloak.192.168.64.2.nip.io/realms/mlflow
        - --login-url=https://keycloak.192.168.64.2.nip.io/realms/mlflow/protocol/openid-connect/auth
        - --redeem-url=https://keycloak.192.168.64.2.nip.io/realms/mlflow/protocol/openid-connect/token
        - --profile-url=https://keycloak.192.168.64.2.nip.io/realms/mlflow/protocol/openid-connect/userinfo
        - --validate-url=https://keycloak.192.168.64.2.nip.io/realms/mlflow/protocol/openid-connect/userinfo
        - --keycloak-group=/admin
        - --pass-basic-auth=false
        - --pass-access-token=true
        - --set-xauthrequest=true
        - --set-authorization-header=true
        - --pass-authorization-header=true
        - --skip-provider-button=true
        - --skip-auth-preflight=true
        - --pass-host-header=true
        - --pass-user-headers=true
        - --cookie-secret=T0F1dGhLaWJhbmFUZXN0cw==
        - --oidc-jwks-url=https://keycloak.192.168.64.2.nip.io/realms/mlflow/protocol/openid-connect/certs
        - --skip-jwt-bearer-tokens=true
        - --request-logging=true
        - --auth-logging=true
        - --standard-logging=true
        image: quay.io/oauth2-proxy/oauth2-proxy:latest
        imagePullPolicy: Always
        name: oauth2-proxy
        ports:
        - containerPort: 4180
          protocol: TCP

@karlschriek
Copy link

karlschriek commented May 5, 2022

I attempted to use the spec @lasith011 posted above, but I sitll get the same error: [2022/05/05 16:01:21] [oauthproxy.go:730] Error creating session during OAuth2 callback: oidc: expected audience "demo" got ["account"]

@lasith011
Copy link

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

No branches or pull requests