You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8.3 KiB

RUG website template and single signon for django

Template and for creating a website in the University of Groningen style, which also helps you to get single sign-on
to work.

Getting started


Make sure these packages are installed on the webhost serving your website.

  • centos yum install libxml2-devel libxslt-devel python34-devel xmlsec1-devel libmcrypt libmcrypt-devel xmlsec1-openssl
  • ubuntu sudo apt-get install libxml2-dev libxslt1-dev libxmlsec1-dev python3-dev


I would suggest you use a virtualenv, this is a directory which contains the python executables and all python
packages, like django, python3-saml, etc.

mkdir rugwebsite && cd rugwebsite
virtualenv --python=/usr/bin/python3.5 venv
source venv/bin/activate
pip3 install -U gunicorn git+ssh://

Settings and X509 certificate

Create a file rugwebsite/, with settings like these:

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '....'
DEBUG = True




	'BACKEND': 'django.template.backends.django.DjangoTemplates',
	'DIRS': [],
	'APP_DIRS': True,
	    'context_processors': [

    'default': {
	'ENGINE': 'django.db.backends.sqlite3',
	'NAME': os.path.join(BASE_DIR, '..', 'db.sqlite3'),

TIME_ZONE = 'Europe/Amsterdam'
USE_I18N = True
USE_L10N = True
USE_TZ = True

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

SAML_ROUTE = 'sso/saml/'


Make sure to fill in something random for SECRET_KEY, consult the dango documentation to make sure you're super

Then you can use django-admin to complete the settings with SAML2 metadata, inclusing a private key and x509
certificate. Run the following and append the output to rugwebsite/

PYTHONPATH=. DJANGO_SETTINGS_MODULE=settings django-admin init-saml2-settings --country NL --city Groningen \
     --organisation 'University of Groningen' --organisation-unit 'Research and Innovation Support' \
     --common-name '' --state Groningen \
     --support-name 'Research and Innovation Support' --support-email '' \
     --technical-name 'Research and Innovation Support' --technical-email '' \
     --base-url '' \
     --entity-id ''

You can change these settings if you like. Make sure to choose these correctly for your situation:

  • entity-id
  • common-name
  • base-url, including http or https and a prefix to all paths, make sure base-url + "/sso/saml/metadata?provider=RuG"
    is a working url.
  • support-name, support-email, technical-name, technical-email

Database and static files

Create the database

PYTHONPATH=. DJANGO_SETTINGS_MODULE=settings django-admin migrate

And collect all static files (javascript, css, etc). Recall what the absolute path of rugwebsite/static is.

PYTHONPATH=. DJANGO_SETTINGS_MODULE=settings django-admin collectstatic

Host the website using Gunicorn

Create a rugwebsite/

import os, sys

sys.path.insert(0, 'absolute-path-to/rugwebsite/venv/lib/python3.5/site-packages/')
sys.path.insert(0, 'absolute-path-to/rugwebsite/venv/lib64/python3.5/site-packages/')
sys.path.insert(0, 'absolute-path-to/rugwebsite/')

from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")

application = get_wsgi_application()

You can test-run the website with gunicorn like, but it won't host the static files (javascript, css, etc). Decide on
what port it should run, for example 8890.

absolute-path-to/rugwebsite/venv/bin/gunicorn --bind wsgi

you can run this in a sceen, but it might be better to create a service like, in centos you create a
/usr/lib/systemd/system/yourwebsite.service like this

Description=your website gunicorn deamon description

ExecStart=absolute-path-to/rugwebsite/venv/bin/gunicorn --pid /run/gunicorn/yourwebsitepid --bind wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID


You can start your service using sudo service yourwebsite start (or restart, status, stop, ...)

nginx proxy

You can use nginx to proxy your website, and add https-support (instead of plain http), but also to server the static
files efficiently. Make sure nginx is installed and configure the website, for example by creating the
/etc/nginx/conf.d/yourwebsite.conf file on centos:

# Make sure the port matches
upstream yourwebsiteupstream {

# Forward http to https
server {
    listen 80;
    return 301 https://$host$request_uri;

server {
    client_max_body_size 64M;
    proxy_connect_timeout       300;
    proxy_send_timeout          300;
    proxy_read_timeout          300;
    send_timeout                300;
    listen              443 ssl;
    ssl_certificate     /etc/nginx/conf.d/;
    ssl_certificate_key /etc/nginx/conf.d/;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/conf.d/dhparams.pem;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        alias absolute-path-to/rugwebsite/static/;

    location / {
        proxy_pass http://yourwebsiteupstream/;
        proxy_set_header Host  ;
        proxy_set_header X-Forwarded-For $remote_addr;

        # This setting is important, it allows SAML2 to verify the provider url, whithout getting into trouble because
        # the https-part is handled by nginx, and hence not seen by the django SAML2 code.
        proxy_set_header X_FORWARDED_PROTO https;

Restart nginx to load the settings sudo service nginx restart (or reload, to only reload the settings instaed of a
full restart)