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

WWW-Authenticate with the server's SPNEGO token isn't sent if "satisfy any" and basic auth are used together with SPNEGO #146

Open
artli opened this issue Feb 8, 2024 · 0 comments

Comments

@artli
Copy link

artli commented Feb 8, 2024

Adding satisfy any; and configuring basic auth breaks the SPNEGO mutual authentication flow because the WWW-Authenticate header isn't sent in the server's response after the user is successfully authenticated.

$ cat nginx.conf 
daemon off;
error_log nginx_error.log warn;
pid nginx.pid;

events { }

http {
    client_body_temp_path tmp/client_body;
    proxy_temp_path tmp/proxy;
    fastcgi_temp_path tmp/fastcgi;
    scgi_temp_path tmp/scgi;
    uwsgi_temp_path tmp/uwsgi;

    satisfy any;
    auth_basic "Basic auth prompt";
    auth_basic_user_file basic-auth.conf;

    auth_gss on;
    auth_gss_keytab /path/to/keytab...;
    auth_gss_allow_basic_fallback off;

    server {
        listen 11111 default_server;
        access_log nginx_access.log combined;

        location / {
            try_files "" @auth_success;
        }

        location @auth_success {
            return 200 'OK\n';
        }
    }
}
$ ./nginx-1.25.3 -p . -e nginx_error.log -c nginx.conf
...

$ # In a different terminal: both basic auth and SPNEGO auth work:
$ curl -u user:password http://$(hostname):11111/
OK
$ curl -u: --negotiate http://$(hostname):11111/
OK
$ # We see that after successful authentication we're not getting any server tokens in the response:
$ curl -u: --negotiate http://$(hostname):11111/ -I
HTTP/1.1 401 Unauthorized
Server: nginx/1.25.3
Date: Thu, 08 Feb 2024 15:27:53 GMT
Content-Type: text/html
Content-Length: 179
Connection: keep-alive
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="Basic auth prompt"

HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Thu, 08 Feb 2024 15:27:53 GMT
Content-Type: text/plain
Content-Length: 3
Connection: keep-alive

$ # Now let's stop nginx and comment out "satisfy any" and the basic auth config:
$ cat nginx.conf 
daemon off;
error_log nginx_error.log warn;
pid nginx.pid;

events { }

http {
    client_body_temp_path tmp/client_body;
    proxy_temp_path tmp/proxy;
    fastcgi_temp_path tmp/fastcgi;
    scgi_temp_path tmp/scgi;
    uwsgi_temp_path tmp/uwsgi;

    # satisfy any;
    # auth_basic "Basic auth prompt";
    # auth_basic_user_file basic-auth.conf;

    auth_gss on;
    auth_gss_keytab /path/to/keytab...;
    auth_gss_allow_basic_fallback off;

    server {
        listen 11111 default_server;
        access_log nginx_access.log combined;

        location / {
            try_files "" @auth_success;
        }

        location @auth_success {
            return 200 'OK\n';
        }
    }
}
$ ./nginx-1.25.3 -p . -e nginx_error.log -c nginx.conf
...

$ # In a different terminal: SPNEGO auth still works:
$ curl -u: --negotiate http://$(hostname):11111/
OK
$ # Now we're getting an appropriate WWW-Authenticate header in the second response from the server, as expected:
$ curl -u: --negotiate http://$(hostname):11111/ -I
HTTP/1.1 401 Unauthorized
Server: nginx/1.25.3
Date: Thu, 08 Feb 2024 15:32:54 GMT
Content-Type: text/html
Content-Length: 179
Connection: keep-alive
WWW-Authenticate: Negotiate

HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Thu, 08 Feb 2024 15:32:54 GMT
Content-Type: text/plain
Content-Length: 3
Connection: keep-alive
WWW-Authenticate: Negotiate <redacted-base64-token>

Also tried this with a simple proxy_pass reverse proxy setup instead of an @auth_success location with a return; that didn't make a difference.

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

No branches or pull requests

1 participant