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

Feature Request - Add keycloak as a provider #127

Closed
vikas027 opened this issue Apr 13, 2019 · 16 comments
Closed

Feature Request - Add keycloak as a provider #127

vikas027 opened this issue Apr 13, 2019 · 16 comments

Comments

@vikas027
Copy link

It would be awesome to add support for Keycloak provider.

@Just-Insane
Copy link

Keycloak should be supported as an OIDC provider, however the docs are lacking, in that half the arguments you are supposed to pass appear to be unavailable, such as --oidc-issuer-url.

@JoelSpeed
Copy link
Member

@vikas027 Did you get this working?

@vikas027
Copy link
Author

vikas027 commented May 2, 2019

Hey @JoelSpeed ,

Nope, I want to try this out but was too busy in other stuff and AWS Summit :). It would be great if someone can add a little doco for keycloak. Thanks.

@kfox1111
Copy link

kfox1111 commented May 2, 2019

I haven't had time to polish up anything, but got something working a month or two ago with something like this:

cat > oauth-proxy-values.yaml <<"EOF"
# Oauth client configuration specifics
config:
  clientID: "keycloak-dashboard"
  clientSecret: "<REPLACE ME>"
  # Create a new secret with the following command
  # python -c 'import os,base64; print base64.b64encode(os.urandom(16))'
  cookieSecret: "XXX"
  configFile: |-
    pass_authorization_header = true
    set_authorization_header = true
    ssl_insecure_skip_verify = true
    oidc_issuer_url = "https://keycloak.192.168.39.199.xip.io/auth/realms/kubernetes"
extraArgs:
  upstream: "file:///dev/null"
  http-address: "0.0.0.0:4180"
ingress:
  enabled: true
  path: /oauth2
  hosts:
  - foo.bar.com
  annotations:
    kubernetes.io/ingress.class: nginx
#    certmanager.k8s.io/issuer: letsencrypt
  tls:
  - hosts:
    - foo.bar.com
    secretName: foo-bar-com-tls
EOF
helm install stable/oauth2-proxy --namespace=kube-system -f oauth-proxy-values.yaml --name=k8s-dash-oauth2
```bash

@iso70x
Copy link

iso70x commented May 27, 2019

I haven't had time to polish up anything, but got something working a month or two ago with something like this:

cat > oauth-proxy-values.yaml <<"EOF"
# Oauth client configuration specifics
config:
  clientID: "keycloak-dashboard"
  clientSecret: "<REPLACE ME>"
  # Create a new secret with the following command
  # python -c 'import os,base64; print base64.b64encode(os.urandom(16))'
  cookieSecret: "XXX"
  configFile: |-
    pass_authorization_header = true
    set_authorization_header = true
    ssl_insecure_skip_verify = true
    oidc_issuer_url = "https://keycloak.192.168.39.199.xip.io/auth/realms/kubernetes"
extraArgs:
  upstream: "file:///dev/null"
  http-address: "0.0.0.0:4180"
ingress:
  enabled: true
  path: /oauth2
  hosts:
  - foo.bar.com
  annotations:
    kubernetes.io/ingress.class: nginx
#    certmanager.k8s.io/issuer: letsencrypt
  tls:
  - hosts:
    - foo.bar.com
    secretName: foo-bar-com-tls
EOF
helm install stable/oauth2-proxy --namespace=kube-system -f oauth-proxy-values.yaml --name=k8s-dash-oauth2
```bash

Thanks for posting this, it helped me get my own test k8s / oidc / keycloak lab working, and I had spent hours on it also. :( It would be really nice if oauth2-proxy did have a built-in provider mode for keycloak rather than having to tweak the oidc one, but at least it's doable. oauth2-proxy seems a lot easier to use and more flexible than keycloak-gatekeeper/proxy, great tool.

For what it's worth, I isolated the settings that were definitely needed from your config and integrated them all into a single yaml file which deploys the proxy, the 2 ingresses, and the service. This is now repeatable and seems stable. I have done this on the Canonical deployment of kubernetes (CDK), and used the default dashboard service which runs on https/443.

Not sure anyone still needs this info, but just in case, here are the complete set of oauth2-proxy args and ingress annotations I think are the critical ones for keycloak. The rest of the options mentioned in your post don't seem to be required (at least from my testing and trial/error). On the CDK kubernetes, the ingress proxy-buffer size of 8k is too small and needed to be raised via an annotation.

INGRESS (external-auth-oauth2) deployment:
annotations:
nginx.ingress.kubernetes.io/auth-response-headers: Authorization
nginx.ingress.kubernetes.io/auth-signin: https://$host/oauth2/start?rd=$escaped_request_uri
nginx.ingress.kubernetes.io/auth-url: https://$host/oauth2/auth
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: 16k

INGRESS (oauth2-proxy) deployment:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: 16k

DEPLOYMENT (oauth2-proxy) args:
- --provider=oidc
- --oidc-issuer-url=https://keycloak.yourdomain.lan:8443/auth/realms/yourrealm
- --cookie-secure=true
- --cookie-domain=.yourdomain.lan
- --whitelist-domain=.yourdomain.lan
- --email-domain=*
- --upstream=file:///dev/null
- --http-address=0.0.0.0:4180
- --ssl-insecure-skip-verify # Needed for self-signed cert
- --set-authorization-header
env:
- name: OAUTH2_PROXY_CLIENT_ID
value: kubernetes
- name: OAUTH2_PROXY_CLIENT_SECRET
value: xxxx
- name: OAUTH2_PROXY_COOKIE_SECRET
value: xxxx

The docker image used was:
image: quay.io/pusher/oauth2_proxy

I can share the deployment yaml file if anyone wants it, but all the important settings are those listed above.

@Ofinka
Copy link

Ofinka commented Jul 25, 2019

Hi I found this pull request back in original repository: bitly/oauth2_proxy#366
Today I merged it locally into latest version of pusher/oauth2_proxy and built a docker image from it.

I then tried to setup proxy with keycloak and it looked cool (I got authenticated but sadly the /oauth2/callback returns 500 - this is probably just my bad understanding of keycloak's oauth process and lack of knowledge when it comes to env variables which need to be satisfied and has nothing to do with quality of the PR)

@mannp
Copy link

mannp commented Jul 25, 2019

@Ofinka sounds cool, thanks for the info and motivation, as i am trying to get his to work without much success yet.

I have the proxy configured as above but must be missing something trivial, as its not even redirecting to my keycloak instance.

I am trying to link it behind my letsencrypt reverse proxy.

I will see if I can do a similar thing as you have done.

Or perhaps @FlorinPeter would consider recreating his PR against the lastest code, for those of us less familiar with the keycloak configs :)

@Ofinka
Copy link

Ofinka commented Jul 26, 2019

Hi finally I've made it working with bitly/oauth2_proxy#366 PR.

Basically I just needed to specify correctly --redeem-url --validate-url and --login-url.

I put my configuration in case someone else wants to use keycloak provider.
In my example I tried to secure management UI of rabbitmq which is internally accessible at ch-rabbitmq:15672. Note that I host my Rabbit at infrastructure namespace and oauth2-proxy at oauth2 namespace.

#oauth2-proxy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: oauth2
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
        - args:
            - --provider=keycloak
            - --email-domain=*
            - --upstream=file:///dev/null
            - --http-address=0.0.0.0:4180
            - --login-url=https://my.domain.com/auth/realms/master/protocol/openid-connect/auth
            - --redeem-url=https://my.domain.com/auth/realms/master/protocol/openid-connect/token
            - --validate-url=https://my.domain.com/auth/realms/master/protocol/openid-connect/userinfo
          env:
            - name: OAUTH2_PROXY_CLIENT_ID
              value: kubernetes
            - name: OAUTH2_PROXY_CLIENT_SECRET
              value: ec900c4c-27d1-4257-bb77-5492fccac99f
            # docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));'
            - name: OAUTH2_PROXY_COOKIE_SECRET
              value: rXPajRXVoIINCXz/xJIC1w==
          # my image - fork of pusher/oauth2_proxy:master + PR containing keycloak provider
          image: dregistry.local.com/oauth2_proxy
          imagePullPolicy: Always
          name: oauth2-proxy
          ports:
            - containerPort: 4180
              protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: oauth2-proxy
  name: oauth2-proxy
  namespace: oauth2
spec:
  ports:
    - name: http
      port: 4180
      protocol: TCP
      targetPort: 4180
  selector:
    k8s-app: oauth2-proxy
#rabbit-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/auth-url: "https://my.domain.com/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://my.domain.com/oauth2/start?rd=$escaped_request_uri"
  name: external-auth-oauth2
  namespace: infrastructure
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: ch-rabbitmq
              servicePort: 15672
            path: /lol/(.*)

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: oauth2-proxy
  namespace: oauth2
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: oauth2-proxy
              servicePort: 4180
            path: /oauth2

Here are screenshots of everything I had to configure in keycloak UI.

@mannp
Copy link

mannp commented Jul 27, 2019

Getting some errors building the previous PR, maybe missed something.

Hopeful someone with fresher skills can recreate the PR :)

Edit: Specifically this error -> providers/keycloak.go:51:47: undefined: SessionState

@Ofinka Ofinka mentioned this issue Jul 28, 2019
3 tasks
@Just-Insane
Copy link

@Ofinka I followed your steps and built my own container with the added/modified files from your PR, and was able to get Keycloak working.

In terms of use, since each proxy can only support one client in Keycloak, it would be better to have a proxy for each service you want to protect, correct? Then you could set proper redirect URIs and whatnot within Keycloak.

@hanikesn
Copy link

hanikesn commented Sep 3, 2019

Keycloack worked perfectly fine for me when using the oidc discovery url no need for manual configuration at all.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2020

This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.

@yaakov-berkovitch
Copy link

yaakov-berkovitch commented Jun 22, 2020

Hi,

i'm still falling with keycloak as OIDC server. After successful authentication, the redirection to oauth2/callback failed as below:

<!DOCTYPE html>
<html lang="en" charset="utf-8">
<head>
	<title>500 Internal Error</title>
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>
<body>
	<h2>500 Internal Error</h2>
	<p>Internal Error</p>
	<hr>
	<p><a href="/oauth2/sign_in">Sign In</a></p>
</body>

This is the URL that failed: https://192.168.56.104/oauth2/callback?state=496a4cb7f81dc6c4d9649570d900e8ad%3A%2Fhello%2Fworld&session_state=3abcecfb-0b30-4bb7-960e-3c15c469d491&code=d468cdfb-f394-45b4-8fd0-b5353f577c2f.3abcecfb-0b30-4bb7-960e-3c15c469d491.7dd26498-4491-4d67-bd65-aa493b791038

Any idea about how to fix it ?

Thanks.

@JoelSpeed
Copy link
Member

@yaakov-berkovitch Please open a new issue about this rather than using an old one. Please also check the logs at the time of the authentication, that is the internal server error page for OAuth2 Proxy so it should have logged that there was an error and that should help narrow down the problem

@yaakov-berkovitch
Copy link

you are correct - I opened a new issue related to error "http: named cookie not present". That's the real issue i'm facing now.

@anthonyvk
Copy link

Setting OAUTH2_PROXY_COOKIE_SECURE=false environment variable or --cookie-secure=false argument worked for me.

See :
#866 (comment)
#26 (comment)

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

10 participants