Commit effd19d7 authored by Lukas Burgey's avatar Lukas Burgey

Add direct auth redirect using query parameters

This resolves #2
parent e9dddd00
......@@ -5,7 +5,7 @@ map $http_upgrade $connection_upgrade {
}
upstream django {
server unix://home/feudal/backend/feudal.sock;
server unix://home/feudal/feudalBackend/feudal.sock;
}
upstream websocket {
......@@ -23,37 +23,37 @@ server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name hdf-portal.data.kit.edu;
server_name hdf-portal-dev.data.kit.edu;
charset utf-8;
client_max_body_size 75M;
ssl on;
ssl_certificate /etc/ssl/hdf-portal.data.kit.edu/chain.pem;
ssl_trusted_certificate /etc/ssl/hdf-portal.data.kit.edu/fullchain.pem;
ssl_certificate_key /etc/ssl/hdf-portal.data.kit.edu/key.pem;
ssl_certificate /etc/ssl/hdf-portal-dev.data.kit.edu/chain.pem;
ssl_trusted_certificate /etc/ssl/hdf-portal-dev.data.kit.edu/fullchain.pem;
ssl_certificate_key /etc/ssl/hdf-portal-dev.data.kit.edu/key.pem;
ssl_dhparam /etc/nginx/cert/dhparam.pem;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 180m;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_dhparam /etc/nginx/cert/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
resolver 141.3.175.65 141.3.175.66;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /home/feudal/webpage/dist;
root /home/feudal/feudalWebpage/dist;
index index.html;
location /backend/static {
alias /home/feudal/backend/static;
alias /home/feudal/feudalBackend/static;
}
location /backend {
uwsgi_pass django;
include /home/feudal/backend/example-config/uwsgi_params;
include /home/feudal/config/uwsgi_params;
}
location /frontend {
......@@ -68,6 +68,9 @@ server {
}
location / {
if ($arg_idp) {
return 301 /backend/auth/v1/request$is_args$args;
}
rewrite "^$" /frontend;
}
}
......
import json
import logging
import urllib
from django.contrib.auth import authenticate, login, logout
from django.core.exceptions import ImproperlyConfigured
from django.shortcuts import redirect
from django.views import View
from oic import rndstr
......@@ -21,39 +23,63 @@ LOGGER = logging.getLogger(__name__)
IDP_COOKIE_NAME = 'idp_id'
def idp_id_from_request(request):
class AuthException(Exception):
pass
def select_oidc_config(request):
issuer_uri_urlenc = request.GET.get('idp', None)
idp_id = request.COOKIES.get(IDP_COOKIE_NAME, None)
if idp_id is not None:
return idp_id
LOGGER.info('idp_id cookie was not set on request %s', request)
return default_idp().id
# IdP selection using the 'idp' url parameter
try:
if issuer_uri_urlenc is not None:
issuer_uri = urllib.parse.unquote(issuer_uri_urlenc)
return OIDCConfig.objects.get(issuer_uri=issuer_uri)
class AuthException(Exception):
pass
# IdP selection using a cookie
elif idp_id is not None:
return OIDCConfig.objects.get(id=idp_id)
return default_idp()
except OIDCConfig.DoesNotExist:
LOGGER.error("Failed to select IdP. Serving default IdP")
return default_idp()
class Auth(View):
def get(self, request):
try:
state = rndstr()
idp_id = idp_id_from_request(request)
oidc_config = OIDCConfig.objects.get(id=idp_id)
utils.set_session(request, 'state', state)
utils.set_session(request, 'idp_id', idp_id)
# select an idp according to query parameters / cookies
oidc_config = select_oidc_config(request)
# store the idp used for the authentication in the users session
utils.set_session(request, 'idp_id', oidc_config.id)
# construct the auth redirect
auth_redirect = oidc_config.get_auth_request(
oidc_config.oidc_client,
state,
)
LOGGER.debug('Auth: redirecting %s to IdP %s', state, oidc_config)
# include query parameters in the redirect to the idp
if request.GET.items().length > 1:
urlparams = request.GET.copy()
if 'idp' in urlparams:
del urlparams['idp']
return redirect(auth_redirect+'&'+urlparams.urlencode())
return redirect(auth_redirect)
except OIDCConfig.DoesNotExist:
LOGGER.error('OIDCConfig is not available')
except ImproperlyConfigured:
LOGGER.error('No OIDCConfig is not available')
# the error is deleted from the session when the state is delivered
request.session['error'] = 'Server Error'
......@@ -64,7 +90,9 @@ class AuthCallback(View):
def get(self, request):
try:
state = utils.get_session(request, 'state', None)
idp_id = utils.get_session(request, 'idp_id', default_idp().id)
idp_id = utils.get_session(request, 'idp_id', None)
if idp_id is None:
LOGGER.error("Session for %s does not contain an idp_id. Hence we don't now which idp authenticated the user", state)
oidc_config = OIDCConfig.objects.get(id=idp_id)
oidc_client = oidc_config.oidc_client
......@@ -79,8 +107,7 @@ class AuthCallback(View):
raise AuthException('Erroneous callback from IdP {}'.format(oidc_config))
if not state == aresp['state']:
LOGGER.error('AuthCallback: states do not match')
raise AuthException('AuthCallbackStates do not match')
raise AuthException('AuthCallback: States do not match')
ac_token_response = (
oidc_client.do_access_token_request(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment