Authentication
Besides the normal django username and password authentication this application supports multiple methods of central account management and authentication.
Allauth
Django Allauth is an awesome project that allows you to use a huge number of different authentication providers.
They basically explain everything in their documentation, but the following is a short overview on how to get started.
Public Providers
If you choose Google, Github or any other publicly available service as your authentication provider anyone with an account on that site can create an account on your installation. A new account does not have any permission but it is still not recommended to give public access to your installation.
Choose a provider from the list and install it using the environment variable SOCIAL_PROVIDERS
as shown
in the example below.
When at least one social provider is set up, the social login sign in buttons should appear on the login page. The example below enables Nextcloud and the generic OpenID Connect providers.
SOCIAL_PROVIDERS=allauth.socialaccount.providers.openid_connect,allauth.socialaccount.providers.nextcloud
Formatting
The exact formatting is important so make sure to follow the steps explained here!
Configuration, via environment
Depending on your authentication provider you might need to configure it. This needs to be done through the settings system. To make the system flexible (allow multiple providers) and to not require another file to be mounted into the container the configuration ins done through a single environment variable. The downside of this approach is that the configuration needs to be put into a single line as environment files loaded by docker compose don't support multiple lines for a single variable.
The line data needs to either be in json or as Python dictionary syntax.
Take the example configuration from the allauth docs, fill in your settings and then inline the whole object
(you can use a service like www.freeformatter.com for formatting).
Assign it to the additional SOCIALACCOUNT_PROVIDERS
variable.
The example below is for a generic OIDC provider with PKCE enabled. Most values need to be customized for your specifics!
SOCIALACCOUNT_PROVIDERS = "{ 'openid_connect': { 'OAUTH_PKCE_ENABLED': True, 'APPS': [ { 'provider_id': 'oidc', 'name': 'My-IDM', 'client_id': 'my_client_id', 'secret': 'my_client_secret', 'settings': { 'server_url': 'https://idm.example.com/oidc/recipes' } } ] } }"
Improvements ?
There are most likely ways to achieve the same goal but with a cleaner or simpler system. If you know such a way feel free to let me know.
Configuration, via Django Admin
Instead of defining SOCIALACCOUNT_PROVIDERS
in your environment, most configuration options can be done via the Admin interface. PKCE for openid_connect
cannot currently be enabled this way.
Use your superuser account to configure your authentication backend by opening the admin page and do the following
- Select
Sites
and edit the default site with the URL of your installation (or create a new). - Create a new
Social Application
with the required information as stated in the provider documentation of allauth. - Make sure to add your site to the list of available sites
Now the provider is configured and you should be able to sign up and sign in using the provider.
Use the superuser account to grant permissions to the newly created users, or enable default access via SOCIAL_DEFAULT_ACCESS
& SOCIAL_DEFAULT_GROUP
.
WIP
I do not have a ton of experience with using various single signon providers and also cannot test all of them. If you have any Feedback or issues let me know.
Third-party authentication example
Keycloak is a popular IAM solution and integration is straight forward thanks to Django Allauth. This example can also be used as reference for other third-party authentication solutions, as documented by Allauth.
At Keycloak, create a new client and assign a Client-ID
, this client comes with a Secret-Key
. Both values are required later on. Make sure to define the correct Redirection-URL for the service, for example https://tandoor.example.com/*
. Depending on your Keycloak setup, you need to assign roles and groups to grant access to the service.
To enable Keycloak as a sign in option, set those variables to define the social provider and specify its configuration:
SOCIAL_PROVIDERS=allauth.socialaccount.providers.openid_connect
SOCIALACCOUNT_PROVIDERS='{"openid_connect":{"APPS":[{"provider_id":"keycloak","name":"Keycloak","client_id":"KEYCLOAK_CLIENT_ID","secret":"KEYCLOAK_CLIENT_SECRET","settings":{"server_url":"https://auth.example.org/realms/KEYCLOAK_REALM/.well-known/openid-configuration"}}]}}
'
You are now able to sign in using Keycloak after a restart of the service.
Linking accounts
To link an account to an already existing normal user go to the settings page of the user and link it. Here you can also unlink your account if you no longer want to use a social login method.
LDAP
LDAP authentication can be enabled in the .env
file by setting LDAP_AUTH=1
.
If set, users listed in the LDAP instance will be able to sign in without signing up.
These variables must be set to configure the connection to the LDAP instance:
AUTH_LDAP_SERVER_URI=ldap://ldap.example.org:389
AUTH_LDAP_BIND_DN=uid=admin,ou=users,dc=example,dc=org
AUTH_LDAP_BIND_PASSWORD=adminpassword
AUTH_LDAP_USER_SEARCH_BASE_DN=ou=users,dc=example,dc=org
AUTH_LDAP_USER_SEARCH_FILTER_STR=(uid=%(user)s)
AUTH_LDAP_USER_ATTR_MAP={'first_name': 'givenName', 'last_name': 'sn', 'email': 'mail'}
AUTH_LDAP_ALWAYS_UPDATE_USER=1
AUTH_LDAP_CACHE_TIMEOUT=3600
AUTH_LDAP_START_TLS=1
AUTH_LDAP_TLS_CACERTFILE=/etc/ssl/certs/own-ca.pem
External Authentication
Security Impact
If you just set REMOTE_USER_AUTH=1
without any additional configuration, anybody can authenticate with any username!
Community Contributed Tutorial
This tutorial was provided by a community member. We are not able to provide any support! Please only use, if you know what you are doing!
In order use external authentication (i.e. using a proxy auth like Authelia, Authentik, etc.) you will need to:
- Set
REMOTE_USER_AUTH=1
in the.env
file - Update your nginx configuration file
Using any of the examples above will automatically generate a configuration file inside a docker volume.
Use docker volume inspect recipes_nginx
to find out where your volume is stored.
Configuration File Volume
The nginx config volume is generated when the container is first run. You can change the volume to a bind mount in the
docker-compose.yml
, but then you will need to manually create it. See section Volumes vs Bind Mounts
below
for more information.
Configuration Example for Authelia
server {
listen 80;
server_name localhost;
client_max_body_size 16M;
# serve static files
location /static/ {
alias /static/;
}
# serve media files
location /media/ {
alias /media/;
}
# Authelia endpoint for authentication requests
include /config/nginx/auth.conf;
# pass requests for dynamic content to gunicorn
location / {
proxy_set_header Host $host;
proxy_pass http://web_recipes:8080;
# Ensure Authelia is specifically required for this endpoint
# This line is important as it will return a 401 error if the user doesn't have access
include /config/nginx/authelia.conf;
auth_request_set $user $upstream_http_remote_user;
proxy_set_header REMOTE-USER $user;
}
# Required to allow user to logout of authentication from within Recipes
# Ensure the <auth_endpoint> below is changed to actual the authentication url
location /accounts/logout/ {
return 301 http://<auth_endpoint>/logout;
}
}
Please refer to the appropriate documentation on how to set up the reverse proxy, authentication, and networks.
Ensure users have been configured for Authelia, and that the endpoint recipes is pointed to is protected but available.
There is a good guide to the other additional files that need to be added to your nginx set up at the Authelia Docs.
Remember to add the appropriate environment variables to .env
file (example for nginx proxy):
VIRTUAL_HOST=
LETSENCRYPT_HOST=
LETSENCRYPT_EMAIL=
PROXY_HEADER=