Add support for TLS certificate authentication

This commit is contained in:
Quantum 2024-10-08 00:18:14 -04:00
parent 7b51c69038
commit 48b6cdb79b
2 changed files with 32 additions and 1 deletions

View file

@ -89,6 +89,27 @@ the client does not support Kerberos. To use this, configure:
There should be one `%s` symbol in this string, which will be replaced by the
username.
### TLS Client Certificate
It's also possible to use client certificates on machines that have them for
authentication purposes instead of using LDAP or Kerberos. To do this, set
the environment variable `KRBAUTH_TLS_CERT_AUTH` to `1` or `yes`.
Then, pass the WSGI environment variable `NGINX_SSL_CLIENT_VERIFY` from `nginx`,
setting it to the value of `$ssl_client_verify`, like this:
```nginx
uwsgi_param NGINX_SSL_CLIENT_VERIFY "$ssl_client_verify";
```
You most likely want to make client certificate verification optional if you
are using it with `nginx-krbauth`:
```nginx
ssl_client_certificate /path/to/ca.crt;
ssl_verify_client optional;
```
## Example `nginx.conf`
```nginx

View file

@ -41,6 +41,7 @@ else:
gssapi_creds = None
COOKIE_SECURE = os.environ.get('KRBAUTH_SECURE_COOKIE', '1').lower() not in ('0', 'no')
TLS_CERT_AUTH = os.environ.get('KRBAUTH_TLS_CERT_AUTH', '0').lower() in ('1', 'yes')
class Context:
@ -170,12 +171,21 @@ def auth_basic(context: Context, next_url: str) -> Response:
return auth_success(context, next_url)
def check_tls() -> bool:
if not TLS_CERT_AUTH:
return False
return request.environ.get('NGINX_SSL_CLIENT_VERIFY') == 'SUCCESS'
@app.endpoint('krbauth.auth')
def auth() -> Response:
next_url = request.args.get('next', '/')
context = Context.from_request()
authorization = request.headers.get('Authorization', '')
if check_tls():
return auth_success(context, next_url)
if authorization.startswith('Negotiate '):
return auth_spnego(context, next_url)
if LDAP_USER_DN and authorization.startswith('Basic '):
@ -186,6 +196,6 @@ def auth() -> Response:
@app.endpoint('krbauth.check')
def check() -> Response:
if verify_cookie(request.cookies.get('krbauth'), Context.from_request()):
if check_tls() or verify_cookie(request.cookies.get('krbauth'), Context.from_request()):
return Response(status=200)
return Response(status=401)