oauth2-proxy / oauth2-proxy

A reverse proxy that provides authentication with Google, Azure, OpenID Connect and many more identity providers.
https://oauth2-proxy.github.io/oauth2-proxy
MIT License
9.74k stars 1.59k forks source link

Endless redirect to provider login screen #707

Closed ba1dr closed 4 years ago

ba1dr commented 4 years ago

What I see: upon opening website I get redirected to /start endpoint and then immediately to Google "Sign In" page. After logging in with google I am redirected to /callback?state=blabla page with positive record in the log (I see my email in the oauth2-proxy's log). But then I immediately get redirected to /start and to Google "Sign In" page again and so on. If I enter my website's address I can open its pages and I am logged in. Just redirect does not work. Cookies seem to be set correctly.

Version: commit bbf00bc92b6c5ab8906c14021a1a4eecf44407c3 from master (by Wed Jul 29 12:23:08 2020 +0100) Ubuntu 20.04

Cookies from /callback:

Set-Cookie: _oauth2_proxy_csrf=; Path=/; Domain=domain2.com; Expires=Sat, 01 Aug 2020 19:16:49 GMT; HttpOnly; Secure; SameSite
Set-Cookie: _oauth2_proxy=X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596313009|UG31lT1RBxfHphLCChCku7kkM81E5MrWQvcqQt3HlQQ=; Path=/; Domain=domain2.com; Expires=Sat, 08 Aug 2020 20:16:49 GMT; HttpOnly; Secure; SameSite

From /start there is only cookie _oauth2_proxy_csrf:

Set-Cookie: _oauth2_proxy_csrf=f8f3d76cbff82238c8c375ec1cb01c00; Path=/; Domain=domain2.com; Expires=Sat, 08 Aug 2020 20:16:49 GMT; HttpOnly; Secure; SameSite

oauth2-proxy.cfg:

http_address = "127.0.0.1:4180"
reverse_proxy = true
provider = "google"
set_xauthrequest = true
session_store_type = "redis"
redis_connection_url = "redis://127.0.0.1:6379/10"

standard_logging = true
request_logging = true
auth_logging = true

pass_basic_auth = true
pass_user_headers = true
pass_host_header = true
email_domains = [
    "custom.domain"
]
client_id = "blabla.apps.googleusercontent.com"
client_secret = "XXXXXXXXXX"
pass_access_token = true
authenticated_emails_file = "authenticated_emails_file"  # contains only "myuser.name@gmail.com"
custom_templates_dir = "/opt/somepath/web/static/login"
ssl_insecure_skip_verify = false
cookie_secret = "xxxxx$%xx%xxx$xxxxxx"
cookie_domains = [".domain2.com", ".domain9.com"]
whitelist_domains = [".domain2.com", ".domain9.com"]
cookie_expire = "168h"
cookie_refresh = "1h"
cookie_secure = true
cookie_httponly = true

nginx config:


log_format mylogname '$remote_addr - $email [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$cookie__oauth2_proxy"';
proxy_cache_path        /var/run/cache levels=1:2 keys_zone=authentication:10m inactive=300s;

server {
    ...
    access_log  /var/log/nginx/access.log mylogname;
    error_log  /var/log/nginx/error.log;

    set $oauth2_proxy 127.0.0.1:4180;

    location /oauth2/ {
        proxy_pass       http://$oauth2_proxy;
        proxy_set_header Host                    $host;
        proxy_set_header X-Real-IP               $remote_addr;
        proxy_set_header X-Scheme                $scheme;
        proxy_set_header X-Auth-Request-Redirect $request_uri;
    }
    location = /oauth2/auth {
        proxy_pass       http://$oauth2_proxy;
        proxy_set_header Host             $host;
        proxy_set_header X-Real-IP        $remote_addr;
        proxy_set_header X-Scheme         $scheme;
        proxy_set_header Content-Length   "";
        proxy_pass_request_body           off;

        proxy_cache                   authentication;
        proxy_cache_key               $cookie__oauth2_proxy;
        proxy_cache_valid             202 401 300s;
        proxy_cache_lock              on;
        proxy_buffer_size 8k;
        proxy_ignore_headers  Cache-Control Expires Set-Cookie;
    }

    location / {
        auth_request /oauth2/auth;
        error_page 401 = /oauth2/sign_in;
        auth_request_set $user   $upstream_http_x_auth_request_user;
        auth_request_set $username   $upstream_http_x_auth_request_preferred_username;
        auth_request_set $email  $upstream_http_x_auth_request_email;
        auth_request_set $token  $upstream_http_x_auth_request_access_token;
        auth_request_set $auth_cookie $upstream_http_set_cookie;
        add_header Set-Cookie $auth_cookie;
        auth_request_set $auth_cookie_name_upstream_1 $upstream_cookie_auth_cookie_name_1;
        if ($auth_cookie ~* "(; .*)") {
            set $auth_cookie_name_0 $auth_cookie;
            set $auth_cookie_name_1 "auth_cookie_name_1=$auth_cookie_name_upstream_1$1";
        }
        if ($auth_cookie_name_upstream_1) {
            add_header Set-Cookie $auth_cookie_name_0;
            add_header Set-Cookie $auth_cookie_name_1;
        }
        try_files $uri @gunicorn;
    }

    location @gunicorn {
        proxy_pass http://127.0.0.1:5001;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header X-Username  $username;
        proxy_set_header X-User  $user;
        proxy_set_header X-Email $email;
        proxy_set_header X-Access-Token $token;

        proxy_read_timeout 600;
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_buffering off;
        proxy_connect_timeout 600;
        fastcgi_read_timeout 600s;

        client_max_body_size 1m;
    }
}

nginx-access.log:

127.0.0.1 -  [01/Aug/2020:22:43:29 +0300] "GET /ccgt HTTP/1.1" 200 1457 "-" "-"
127.0.0.1 - - [01/Aug/2020:22:43:31 +0300] "GET /oauth2/start HTTP/1.1" 302 1204 "https://domain1.domain2.com/ccgt" "-"
127.0.0.1 - - [01/Aug/2020:22:57:50 +0300] "GET /oauth2/callback?state=bf1723ed552b4413f28a3b072f2103c0%3A%2Foauth2%2Fstart&code=4%2F2gFyJuJoABCeDq_v_Vto1-_HfCjdBdOVfx54evm8eU6ScYLpzFMbR64qJv1_STbSCJsDpdXMTjzoETAYJ_zWDBk&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=consent HTTP/1.1" 302 783 "https://accounts.google.com/" "X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596311038|X6t54HS3aLLD5pVzjPKwZTp0N2dnTYMMZDAJY0LhFMg="
127.0.0.1 - - [01/Aug/2020:22:57:50 +0300] "GET /oauth2/start HTTP/1.1" 302 1204 "https://accounts.google.com/" "X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596311870|1lb_2ZHYoa94tK8D3Cz1Bq8kQvbQomn7KNFhZavQ--c="
127.0.0.1 - - [01/Aug/2020:22:57:53 +0300] "GET /oauth2/callback?state=ab21fd3de77a7ce54902b9f055a3151a%3A%2Foauth2%2Fstart&code=4%2F2gGFn8229XybAUOJ-5JO8hgeVKPeTFeYqtM5DyUmWrZv14RweF5nf34JWw1A27mvCE4b3QebmvjbFakNJkV56mE&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=consent HTTP/1.1" 302 783 "https://accounts.google.com/" "X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596311870|1lb_2ZHYoa94tK8D3Cz1Bq8kQvbQomn7KNFhZavQ--c="
127.0.0.1 - - [01/Aug/2020:22:57:53 +0300] "GET /oauth2/start HTTP/1.1" 302 1204 "https://accounts.google.com/" "X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596311873|O7HHIMOLJDSkkZg3ran0P1mQWof_dXcScXKsxyz9IPI="
127.0.0.1 - - [01/Aug/2020:22:58:09 +0300] "GET /oauth2/callback?state=0fc860dcf7d61216aada90a0e7989aca%3A%2Foauth2%2Fstart&code=4%2F2gEAVsaZBHJGwtAZFfKe-YCJAU6fn6ZC6rQ28FYs0oVu0dsZjV-GUIcLRCySftDb5WFVvUcolHx2c9DfVR3hSJE&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=consent HTTP/1.1" 302 783 "https://accounts.google.com/" "X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596311873|O7HHIMOLJDSkkZg3ran0P1mQWof_dXcScXKsxyz9IPI="
127.0.0.1 - - [01/Aug/2020:22:58:09 +0300] "GET /oauth2/start HTTP/1.1" 302 1204 "https://accounts.google.com/" "X29hdXRoMl5wxm94eS1hNjFiM2RkMzYyvGMzZWYwMjIzYzE0ZzQ5ZGQ0MWY2Mi5ENkdYG3HdLX0JEQ3prTFBPY0U3eWpn|1596311889|SputK5hkaCL0XK3CWkJ-zoNO7Chzek37CHc0qWtDuJc="

oauth2-proxy log:

127.0.0.1 - myuser.name@gmail.com [2020/08/01 22:57:53] [AuthSuccess] Authenticated via OAuth2: Session{email:myuser.name@gmail.com user:110730624193233073775 PreferredUsername: token:true id_token:true created:2020-08-01 22:57:53.887575649 +0300 MSK m=+9.025163984 expires:2020-08-01 23:57:52 +0300 MSK refresh_token:true}
127.0.0.1 - - [2020/08/01 22:57:53] domain1.domain2.com GET - "/oauth2/callback?state=ab21fd3de77a7ce54902b9f055a3151a%3A%2Foauth2%2Fstart&code=4%2F2gGFn8229XybAUOJ-5JO8hgeVKPeTFeYqtM5DyUmWrZv14RweF5nf34JWw1A27mvCE4b3QebmvjbFakNJkV56mE&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=consent" HTTP/1.0 "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" 302 36 0.112
127.0.0.1 - - [2020/08/01 22:57:53] domain1.domain2.com GET - "/oauth2/start" HTTP/1.0 "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" 302 378 0.001
127.0.0.1 - myuser.name@gmail.com [2020/08/01 22:58:09] [AuthSuccess] Authenticated via OAuth2: Session{email:myuser.name@gmail.com user:110730624193233073775 PreferredUsername: token:true id_token:true created:2020-08-01 22:58:09.952652236 +0300 MSK m=+25.090240709 expires:2020-08-01 23:58:08 +0300 MSK refresh_token:true}
127.0.0.1 - - [2020/08/01 22:58:09] domain1.domain2.com GET - "/oauth2/callback?state=0fc860dcf7d61216aada90a0e7989aca%3A%2Foauth2%2Fstart&code=4%2F2gEAVsaZBHJGwtAZFfKe-YCJAU6fn6ZC6rQ28FYs0oVu0dsZjV-GUIcLRCySftDb5WFVvUcolHx2c9DfVR3hSJE&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=consent" HTTP/1.0 "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" 302 36 0.094
127.0.0.1 - - [2020/08/01 22:58:09] domain1.domain2.com GET - "/oauth2/start" HTTP/1.0 "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" 302 378 0.001
ba1dr commented 4 years ago

Well, it seems I figured this out. The line below causes this redirect:

location /oauth2/ {
...
proxy_set_header X-Auth-Request-Redirect $request_uri;
}

Removing this line from that location fixes the main issue. But after login I get redirected to /. This refers us to #695 - is it fixed right?

NickMeves commented 4 years ago

/oauth2/start can take a rd redirect parameter to get you redirected back to the right spot. I have something similar to the above using this annotation in a Kubernetes nginx ingress:

nginx.ingress.kubernetes.io/auth-signin: https://<HOSTNAME>/oauth2/start?rd=https%3A%2F%2F$host$escaped_request_uri

In my case, I'm hosting the oauth2 proxy on a separate domain, so I have $host in the rd parameter (and have whitelist-domains option set appropriately for the security precaution of a redirect to a different domain).

Otherwise you can do /oauth2/start?rd=$escaped_request_uri

ba1dr commented 4 years ago

Well, ok, but I do not manage /oauth2/start URL. Redirect is made by oauth2-proxy itself. I only put auth_request /oauth2/auth; in nginx's config. oauth2-proxy is in action where it receives a callback after google login. It looks like it does not handle it properly.

NickMeves commented 4 years ago

Try replacing this error_page 401 = /oauth2/sign_in; with error_page 401 = /oauth2/start?rd=$escaped_request_uri

Either rd or the header you removed controls the redirect process, see here: https://github.com/oauth2-proxy/oauth2-proxy/blob/7b21f53aad1aa2490c124b703ee4b3522d07712e/oauthproxy.go#L260

You can also try adding rd as a parameter to the /oauth2/sign_in URL, it looks like it is valid there too upon looking at the code.

ba1dr commented 4 years ago

Thanks! That seems to work.

rshiva777 commented 1 year ago

Hello @ba1dr , @NickMeves ,

I am using below ingress on kubernetes, whenever i login with htppass credentials, i am getting redirect to login page again. could you please help

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  namespace: oauth2
  annotations:
    nginx.ingress.kubernetes.io/auth-signin: http://oauth2.test.shiva.com/oauth2/start?rd=http://nginx.test.shiva.com
    nginx.ingress.kubernetes.io/auth-url: http://oauth-oauth2-proxy.oauth2.svc.cluster.local/oauth2/auth
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.test.shiva.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80

When i open the nginx.test.shiva.com url initially from browser, it is redirecting to http://oauth2.test.shiva.com/oauth2/sign_in?rd=http://nginxnew.test.shiva.com. here i am entering the htpasswd credentials and after signing in it is again redirecting to http://oauth2.test.shiva.com/oauth2/sign_in?rd=http://nginxnew.test.shiva.com page in a loop

How can i make it work. after login is succeeded it should redirect to my FQDN correctly without asking to signin again

JoelSpeed commented 1 year ago

@rshiva777 The infinite redirect issue is normally a result of misconfigured cookie domains, can you check that the cookie domain is configured to allow access to both OAuth2 Proxy and the nginx instance, you'll probably want .test.shiva.com based on your examples