Skip to content
This repository has been archived by the owner on Jan 24, 2019. It is now read-only.

Add support for a list of Whitelisted domains #464

Closed
wants to merge 36 commits into from

Conversation

JoelSpeed
Copy link
Contributor

I wrote this on Friday to fix #399

Tidied it up this morning and went to create PR noticing #461 had been created.

I think this better fixes #399 as it looks for domain suffixes rather than explicit domains which I think was the point of the discussion.

Take from this what you will

@madmod madmod mentioned this pull request Dec 1, 2017
main.go Outdated
@@ -43,6 +44,7 @@ func main() {
flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")

flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
flagSet.Var(&whitelistDomains, "whitelist-domains", "allowed domains for redirection after authentication")
Copy link
Contributor

Choose a reason for hiding this comment

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

the variable is plural, but the option name string should be singular "whitelist-domain" because it will be used like --whitelist-domain=.first.com --whitelist-domain=.second.com

oauthproxy.go Outdated
redirect = strings.TrimPrefix(redirect, "https://")
redirect = strings.Split(redirect, "/")[0]
for _, domain := range p.whitelistDomains {
if strings.HasSuffix(redirect, domain) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic is repetitive with the case above. You could consider using url.Parse()

You could also consider protecting users from a silly mistake by only doing a suffix match if the whitelisted domain starts with ., otherwise doing an exact match.

@JoelSpeed
Copy link
Contributor Author

@ploxiln I have addressed your feedback and rebased onto the current master branch. Thanks for your comments

@ploxiln
Copy link
Contributor

ploxiln commented Dec 11, 2017

This looks like a reasonable implementation to me. I'm not a maintainer though, I just try to help out. I think we'll have to wait for @hlhendy's judgement.

The test failures appear to not be related, they're in TestValidatorOverwriteEmailListVia...

One other thing that is typically asked of PRs in this project is that you squash down your commits into one.

@bouk
Copy link

bouk commented Dec 22, 2017

It would be nice if you could add support for setting it though the env also

@JoelSpeed
Copy link
Contributor Author

@bouk Happy to add environment support, looks to me like I just need to add an env struct tag for the new flag, something like OAUTH2_PROXY_WHITELIST_DOMAINS?

However it looks at the moment as if the environment loader can only load strings where this needs to load a list of strings, unless I've missed something?

if v != "" {
cfg[cfgName] = v
}

@bouk
Copy link

bouk commented Jan 8, 2018

The underlying library has support for string slices, so adding the appropriate tag should just work

main.go Outdated
@@ -43,6 +44,7 @@ func main() {
flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")

flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
flagSet.Var(&whitelistDomains, "whitelist-domain", "allowed domains for redirection after authentication")

Choose a reason for hiding this comment

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

s/whitelist-domain/whitelist-domains/?

Copy link
Contributor

Choose a reason for hiding this comment

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

See "email-domain" just above. It's singular because you specify one at a time: --whitelist-domain=first.com --whitelist-domain=second.com

options.go Outdated
@@ -32,6 +32,7 @@ type Options struct {
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
AzureTenant string `flag:"azure-tenant" cfg:"azure_tenant"`
EmailDomains []string `flag:"email-domain" cfg:"email_domains"`
WhitelistDomains []string `flag:"whitelist-domains" cfg:"whitelist_domains"`
Copy link

@Quentin-M Quentin-M Jan 15, 2018

Choose a reason for hiding this comment

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

If https://github.com/bitly/oauth2_proxy/pull/464/files#r161420105, then s/flag:"whitelist-domains/flag:"whitelist-domain/

oauth2_proxy -whitelist-domain=localhost
2018/01/15 02:13:20 options.go:74: ERROR: flag "whitelist-domains" does not exist
panic: ERROR: flag "whitelist-domains" does not exist

goroutine 1 [running]:
log.Panicf(0x90f438, 0x1d, 0xc420035ca0, 0x1, 0x1)
	/usr/local/go/src/log/log.go:333 +0xda
github.com/mreiferson/go-options.Resolve(0x86e180, 0xc420086e00, 0xc4200f2360, 0xc42006f200)
	/go/src/github.com/mreiferson/go-options/options.go:74 +0xb11
main.main()
	/go/src/github.com/bitly/oauth2_proxy/main.go:103 +0x146b

@JoelSpeed
Copy link
Contributor Author

I've pushed a commit that fixes the panic identified by @Quentin-M and adds the ability to set the whitelist domains from the environment with OAUTH2_PROXY_WHITELIST_DOMAINS as suggested by @bouk

Copy link

@bouk bouk left a comment

Choose a reason for hiding this comment

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

looks great!

@smitchelus
Copy link

What's the plan for this PR? It solves the exact issue we've been fighting when attempting to use the oauth2_proxy as part of our k8s ingress infrastructure.

@Quentin-M
Copy link

@smitchelus Pretty sure it'll get merged. In the meantime: https://hub.docker.com/r/qmachu/oauth2_proxy/

@JoelSpeed
Copy link
Contributor Author

JoelSpeed commented Jan 28, 2018

@smitchelus I'm hoping this PR will get merged soon and I've also raised another PR that might interest you given your running K8s. #534 Adds support for the Authorization: Bearer <JWT> headers that the K8s dashboard expects.

The two PRs combined make the proxy perfect for authentication across multiple K8s clusters

@smitchelus
Copy link

Thanks for the update @JoelSpeed, @Quentin-M, and thanks for the image link as well. I've built it locally to confirm it worked for our scenario, but obviously look forward to getting it into an official release soon.

@smitchelus
Copy link

@Quentin-M, just now getting back to this. I tried pulling your image qmachu/oauth2_proxy, but it is telling me flag provided but not defined: -whitelist-domains. It doesn't appear that there's a particular tag I should be pulling. Thoughts on what I'm doing wrong?

@JoelSpeed
Copy link
Contributor Author

@smitchelus try -whitelist-domain (singular) instead? It was changed between opening the PR and that image being built I believe

@smitchelus
Copy link

Good thought, but no dice: flag provided but not defined: -whitelist-domain

@JoelSpeed
Copy link
Contributor Author

@smitchelus I've just built an image and tested the flag from this PR, try this image quay.io/joelspeed/oauth2_proxy:whitelist-domains-1

@smitchelus
Copy link

Thanks @JoelSpeed! I appreciate the help.

@Quentin-M
Copy link

Here is what I use fwiw:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: oauth2-proxy
  namespace: kube-system
  labels:
    k8s-app: oauth2-proxy
spec:
  replicas: 2
  selector:
    matchLabels:
      k8s-app: oauth2-proxy
  template:
    metadata:
      labels:
        k8s-app: oauth2-proxy
    spec:
      containers:
      - name: oauth2-proxy
        image: qmachu/oauth2_proxy:kubernetes
        args:
        - -provider=oidc
        - -client-id=oauth2_proxy
        - -oidc-issuer-url=https://ingress.{{ .domain }}/identity
        - -redirect-url=http://ingress.{{ .domain }}/oauth2/callback
        - -ssl-insecure-skip-verify=true
        - -whitelist-domain=ingress.{{ .domain }}
        - -email-domain=*
        - -cookie-name=_oauth2_{{ .name }}
        - -cookie-expire=24h
        #- -cookie-refresh=1h (https://github.com/bitly/oauth2_proxy/issues/523)
        - -cookie-secure=true
        - -cookie-domain=ingress.{{ .domain }}
        - -tls-cert=/etc/oauth2/tls/tls.crt
        - -tls-key=/etc/oauth2/tls/tls.key
        - -skip-provider-button=true
        - -footer=-
        env:
        - name: OAUTH2_PROXY_CLIENT_SECRET
          valueFrom:
            secretKeyRef:
              name: oauth2-proxy
              key: client.secret
        - name: OAUTH2_PROXY_COOKIE_SECRET
          valueFrom:
            secretKeyRef:
              name: oauth2-proxy
              key: cookie.secret
        volumeMounts:
        - name: tls
          mountPath: /etc/oauth2/tls
        ports:
        - name: https
          containerPort: 443
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /ping
            port: 443
            scheme: HTTPS
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
      - key: CriticalAddonsOnly
        operator: Exists
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: k8s-app
                  operator: In
                  values:
                  - oauth2-proxy
              topologyKey: kubernetes.io/hostname
      volumes:
      - name: tls
        secret:
          secretName: oauth2-proxy

@simonvanderveldt
Copy link

simonvanderveldt commented Feb 26, 2018

First of all thanks for this PR! Would really like to just have a single oauth2 proxy for several internal applications :)
I've just tried out this PR, in this case on oauth2proxy.somedomain.com, that should handle signin for multiple applications.
For the internal application I'm using someapp.localhost as a testcase, so I added whitelist_domains = [ ".localhost" ] to my oauth2_proxy.cfg.

I'm using nginx as described in the readme to handle authentication using the auth_request directive with the following changes:

  • Replaced proxy_pass http://127.0.0.1:4180; with proxy_pass oauth2proxy.somedomain.com;
  • Changed changed error_page 401 = /oauth2/sign_in; to error_page 401 = /oauth2/start?rd=http://$host$request_uri;

The whole flow through my OAuth provider (GitHub) works and the redirect url is being passed correctly in the state parameter.
Unfortunately once I'm redirected to oauth2proxy.somedomain.com/oauth2/callback I'm presented with a 403 and the message http: named cookie not present even though the _oauth2_proxy cookie is present for that domain.

Am I doing something wrong? Could it be because of the different domain name?
Or is there still something missing on the oauth2_proxy side?

@JoelSpeed
Copy link
Contributor Author

@simonvanderveldt What values do you have for cookie_domain, cookie_name and cookie_secure? By my reckoning the cookie_domain=.somedomain.com and cookie_name is presently the default? You might need to set cookie_secure as well if your oauth2_proxy is behind https

@JoelSpeed
Copy link
Contributor Author

Now that @pusher have taken over the repository maintenance, I am closing this in favour of pusher#15

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

Successfully merging this pull request may close these issues.

Support for a whitelist of --redirect-domains