Luzifer / nginx-sso

SSO authentication provider for the auth_request nginx module
Apache License 2.0
286 stars 41 forks source link

Can access sso protected webapp after logout. not sure why #71

Closed fyvfy closed 2 years ago

fyvfy commented 2 years ago
Hi!
i'm trying to use simple auth.

nginx as reverse proxy on host machine:
  nas.home.arpa

some containers in rootless podman:
  login.nas.home.arpa - nginx-sso
  banner.nas.home.arpa - serving short ascii banner for tests
  speed.nas.home.arpa - librespeed

on nas.home.arpa there are some links to my containerized services,
  nothing fancy, just simple html + css page.

#########################################

step 1:
  goto nas.home.arpa, press sso protected link banner.nas.home.arpa (DON'T go to speed.nas.home.arpa)

step 2:
  nginx-sso login screen appears. enter correct username/password pair.
  opens my web app page. cool!

step 3:
  press "logout" link on nas.home.arpa

step 4:
  let's check.
  open speed.nas.home.arpa - nginx-sso login screen appears. good.
  open banner.nas.home.arpa - banner page loads. what?
  reload (F5) banner.nas.home.arpa - finally nginx-sso login screen.

so basically if you've visited that web app earlier you can load it again even after logging out.
you can load it a few times using links on page or by manually entering web app address in browser's addressbar.
am i doing something wrong?

about logs:
  first two entries in log shows me accessing web app while logged in
  third entry - logout
  nothing logged when succesfully accessing web app page after logout
  fourth entry - manually reloading web app page

#########################################

Here are my configs:
#1. nginx-sso config.yaml
#2. nginx-sso logs prettified
#3. nginx config
#4. nginx include config for nginx-sso

#####1. cat filesout/config.yaml

---
login:
  title: "Login to nas.home.arpa"
  default_method: "simple"
  default_redirect: "https://nas.home.arpa/"
  hide_mfa_field: true
  names:
    simple: "Username / Password"
cookie:
  domain: ".nas.home.arpa"
  authentication_key: "strippedfdhstfhgcnfht"
  expire: 3600
  prefix: "nginx-sso"
  secure: true
listen:
  addr: "0.0.0.0"
  port: 8082
audit_log:
  targets:
    - file:///data/log/sso_audit.jsonl
  events: ['access_denied', 'login_success', 'login_failure', 'logout', 'validate']
  headers: ['x-host', 'x-origin-uri', 'x-real-ip', 'x-forwarded-for']
  trusted_ip_headers: ["X-Forwarded-For", "RemoteAddr", "X-Real-IP"]
acl:
  rule_sets:
  - rules:
    - field: "x-host"
      equals: "speed.nas.home.arpa"
    allow: ["tuser", "@admins"]
  - rules:
    - field: "x-host"
      equals: "banner.nas.home.arpa"
    allow: ["tuser", "@admins"]
providers:
  simple:
    enable_basic_auth: false
    users:
      tuser: "$2y$10$strippedsdgkjhjasadgkflm"
    groups:
      admins: ["tuser"]
...

#####2. cat filesout/logs_sso_pretty

{
    "event_type": "validate",
    "headers": {
        "x-forwarded-for": "192.168.0.6",
        "x-host": "banner.nas.home.arpa",
        "x-origin-uri": "/",
        "x-real-ip": "192.168.0.6"
    },
    "remote_addr": "192.168.0.6",
    "result": "valid user found",
    "timestamp": "2022-05-27T01:07:21+03:00",
    "username": "tuser"
}

{
    "event_type": "validate",
    "headers": {
        "x-forwarded-for": "192.168.0.6",
        "x-host": "banner.nas.home.arpa",
        "x-origin-uri": "/",
        "x-real-ip": "192.168.0.6"
    },
    "remote_addr": "192.168.0.6",
    "result": "valid user found",
    "timestamp": "2022-05-27T01:07:23+03:00",
    "username": "tuser"
}

{
    "event_type": "logout",
    "headers": {},
    "remote_addr": "10.0.2.100",
    "timestamp": "2022-05-27T01:07:29+03:00"
}

{
    "event_type": "validate",
    "headers": {
        "x-forwarded-for": "192.168.0.6",
        "x-host": "banner.nas.home.arpa",
        "x-origin-uri": "/",
        "x-real-ip": "192.168.0.6"
    },
    "remote_addr": "192.168.0.6",
    "result": "no valid user found",
    "timestamp": "2022-05-27T01:09:40+03:00"
}

#####3. cat filesout/nginx.conf

user                    http;
worker_processes            4;
events {
    worker_connections      1024;
}
http {
    types_hash_max_size     4096;
    charset             utf-8;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    server_tokens           off;
    client_max_body_size        32M;
    proxy_cache         off;
    include             mime.types;
    default_type            application/octet-stream;
    error_log           /var/log/nginx/error.log notice;
    access_log          /var/log/nginx/access.log;
    keepalive_timeout       65;
    ssl_ciphers         "EECDH+AESGCM";
    ssl_protocols           TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers   on;
    ssl_certificate         /etc/nginx/keys/nascert.crt;
    ssl_certificate_key     /etc/nginx/keys/nascert.pem;
    server {
        listen          80 default_server;
        server_name     "";
        return          301 https://$host$request_uri;
    }
    server {
        listen          443 ssl;
        server_name     localhost;
        ssl_session_cache   shared:SSL:1m;
        ssl_session_timeout 5m;
        location / {
            root            /srv/http/general;
            index           index.html;
        }
        location /sso-logout {
            return          302 https://login.nas.home.arpa/logout?go=https://nas.home.arpa/;
        }
    }
    server {
        listen          443 ssl;
        server_name     login.nas.home.arpa;
        access_log      /var/log/nginx/site_login.nas.home.arpa_access.log;
        error_log       /var/log/nginx/site_login.nas.home.arpa_error.log;
        location / {
            proxy_pass      http://127.0.0.1:8082;
            proxy_cache     off;
        }
    }
    server {
        listen          443 ssl;
        server_name     speed.nas.home.arpa;
        include         /etc/nginx/ssoinclude.conf;
        access_log      /var/log/nginx/site_speed.nas.home.arpa_access.log;
        error_log       /var/log/nginx/site_speed.nas.home.arpa_error.log;
        location / {
            auth_request_set    $cookie $upstream_http_set_cookie;
            add_header      Set-Cookie $cookie;
            proxy_pass      http://127.0.0.1:8034;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    server {
        listen          443 ssl;
        server_name     banner.nas.home.arpa;
        include         /etc/nginx/ssoinclude.conf;
        access_log      /var/log/nginx/site_banner.nas.home.arpa_access.log;
        error_log       /var/log/nginx/site_banner.nas.home.arpa_error.log;
        location / {
            auth_request_set    $cookie $upstream_http_set_cookie;
            add_header      Set-Cookie $cookie;
            proxy_pass      http://127.0.0.1:1234;
        }
    }
}

#####4. cat filesout/ssoinclude.conf

auth_request /sso-auth;
error_page 401 = @error401;
location /sso-auth {
    internal;
    proxy_pass http://127.0.0.1:8082/auth;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Origin-URI $request_uri;
    proxy_set_header X-Host $http_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;
}
location /sso-logout {
    return 302 https://login.nas.home.arpa/logout?go=https://$http_host/;
}
location @error401 {
    return 302 https://login.nas.home.arpa/login?go=https://$http_host$request_uri;
}
Luzifer commented 2 years ago

nothing logged when succesfully accessing web app page after logout

So I assume you've loaded the site from browser-cache instead from the server…

Try opening the web-dev-tools (Ctrl+I) and enable "disable cache" and this should no longer happen… If so: Your browser cached the site and as the request is not reaching the server the login dialog will not be shown…

fyvfy commented 2 years ago

"web-dev-tools (Ctrl+I)" - is that "developer tools"? Probably correct shortcut would be ctrl+shift+i. Anyway, cannot find "disable cache" option. Quick googling found "disable http cache" in firefox, but this option only applies while "developer tools" are open on this particular page. I'm using chromium (v100.0.4896.75, but I encountered this bug when I tried to set up nginx-sso for the first time ~half a year ago), usually "incognito mode" (so no plugins/no extensions).

I found "expires -1;" option for nginx. Well, if i add it to "http" context in /etc/nginx/nginx.conf it fixes the bug.

Luzifer commented 2 years ago

Well, you can't prevent the browser from using its cache if you let the browser cache the site. If there is no request to the nginx server, nginx-sso cannot tell nginx to not fulfill the request.

If setting an expires header fixes the "bug" for you, you are exactly experiencing this: The browser cached a valid response and delivers it. Only when forced to refresh the cache through the server, nginx-sso is asked to validate the session and can deny delivering the site.

This is no "bug" in nginx-sso: nginx-sso wasn't even asked for the site to be displayed. If you want to validate the session on every request you need to make sure every request goes through the server instead to be handled by local browser cache.

As this is about general web mechanics and not an issue with nginx-sso I recommend reading on HTTP Caching and Cache-Control / Expires headers.