Browse Source

Adds middlware that enables automatic login based on HTTP headers

pull/297/head
rbinrais 5 years ago
parent
commit
00d1f5ea3a
6 changed files with 124 additions and 0 deletions
  1. 9
      app/app/settings.py
  2. 42
      app/server/middleware.py
  3. 27
      app/server/tests/test_middleware.py
  4. 13
      authproxy/Dockerfile
  5. 23
      authproxy/nginx.conf
  6. 10
      authproxy/proxy.conf

9
app/app/settings.py

@ -143,6 +143,15 @@ AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
]
HEADER_AUTH_USER_NAME = env('HEADER_AUTH_USER_NAME', '')
HEADER_AUTH_USER_GROUPS = env('HEADER_AUTH_USER_GROUPS', '')
HEADER_AUTH_ADMIN_GROUP_NAME = env('HEADER_AUTH_ADMIN_GROUP_NAME', '')
HEADER_AUTH_GROUPS_SEPERATOR = env('HEADER_AUTH_GROUPS_SEPERATOR', default=',')
if HEADER_AUTH_USER_NAME and HEADER_AUTH_USER_GROUPS and HEADER_AUTH_ADMIN_GROUP_NAME:
MIDDLEWARE.append('server.middleware.HeaderAuthMiddleware')
AUTHENTICATION_BACKENDS.append('django.contrib.auth.backends.RemoteUserBackend')
SOCIAL_AUTH_GITHUB_KEY = env('OAUTH_GITHUB_KEY', None)
SOCIAL_AUTH_GITHUB_SECRET = env('OAUTH_GITHUB_SECRET', None)
GITHUB_ADMIN_ORG_NAME = env('GITHUB_ADMIN_ORG_NAME', None)

42
app/server/middleware.py

@ -0,0 +1,42 @@
from django.conf import settings
from django.contrib.auth.middleware import RemoteUserMiddleware
def to_django_header(header):
return f"HTTP_{header.replace('-', '_').upper()}"
class HeaderAuthMiddleware(RemoteUserMiddleware):
header = to_django_header(settings.HEADER_AUTH_USER_NAME)
def process_request(self, request):
if request.user.is_authenticated:
return
username = request.META.get(self.header)
if not username:
return
super().process_request(request)
self.process_user_groups(request.user, request.META)
@classmethod
def process_user_groups(cls, user, headers):
if not user.is_authenticated:
return
groups = cls.parse_user_groups_from_header(headers)
is_superuser = settings.HEADER_AUTH_ADMIN_GROUP_NAME in groups
if user.is_superuser != is_superuser:
user.is_superuser = is_superuser
user.save()
@classmethod
def parse_user_groups_from_header(cls, headers):
try:
groups_header = headers[to_django_header(settings.HEADER_AUTH_USER_GROUPS)]
except KeyError:
return []
else:
return groups_header.split(settings.HEADER_AUTH_GROUPS_SEPERATOR)

27
app/server/tests/test_middleware.py

@ -0,0 +1,27 @@
from django.test import TestCase, override_settings
from django.contrib.auth.models import User
from ..middleware import HeaderAuthMiddleware
@override_settings(HEADER_AUTH_USER_GROUPS='X-AuthProxy-Groups')
@override_settings(HEADER_AUTH_ADMIN_GROUP_NAME='Admin')
@override_settings(HEADER_AUTH_GROUPS_SEPERATOR=';')
class HeaderAuthMiddlewareTest(TestCase):
def test_process_user_groups_is_super(self):
user = User.objects.create_user(username='TestUser')
user.is_superuser = False
middleware = HeaderAuthMiddleware()
middleware.process_user_groups(user, {'HTTP_X_AUTHPROXY_GROUPS': 'Admin;Reader'})
self.assertTrue(user.is_superuser)
def test_process_user_groups_is_not_super(self):
user = User.objects.create_user(username='TestUser')
user.is_superuser = True
middleware = HeaderAuthMiddleware()
middleware.process_user_groups(user, {'HTTP_X_AUTHPROXY_GROUPS': 'Guest;Reader'})
self.assertFalse(user.is_superuser)

13
authproxy/Dockerfile

@ -0,0 +1,13 @@
FROM nginx:stable-alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY proxy.conf /app/proxy.conf
ENV PORT=8888
ENV PROXY_PASS=""
ENV USER_NAME=""
ENV USER_GROUPS=""
EXPOSE ${PORT}
CMD envsubst < /app/proxy.conf > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'

23
authproxy/nginx.conf

@ -0,0 +1,23 @@
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /app/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}

10
authproxy/proxy.conf

@ -0,0 +1,10 @@
server {
listen ${PORT};
location / {
proxy_pass ${PROXY_PASS};
proxy_set_header X-Auth-UserName ${USER_NAME};
proxy_set_header X-Auth-Groups ${USER_GROUPS};
}
}
Loading…
Cancel
Save