OIDC Configuration
In this example of OIDC configuration, Authentik is used as an authentification backend. A custom pipeline will also be setup to automatically created groups and assign users to groups they belong as well as setting appropriate staff/superuser properties.
The following steps assume that:
- Peering Manager is located at
https://peeringmanager.example.net/
- Authentik is located at
https://authentik.example.net/
In Authentik
In the admin interface, under the Applications -> Providers menu, an OAuth2/OpenID provider must be created with the following parameters:
- Client Type: Confidential
- Redirect URIs: https://peeringmanager.example.net/oauth/complete/oidc/
- Scopes: OpenID, Email and Profile
- Signing Key: Any available key that already exists
The "Client ID" and "Client Secret" values must be kept to be used at a later
stage. An application with the slug peering-manager
can now be created
using the provider you've created above.
Peering Manager Configuration
The configuration of Peering Manager must be adjusted to use the following variables:
REMOTE_AUTH_ENABLED = True
REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth"
SOCIAL_AUTH_BACKEND_ATTRS = {"oidc": ("Authentik", "fa-fw fa-brands fa-openid")}
SOCIAL_AUTH_OIDC_ENDPOINT = "https://authentik.example.net/application/o/peering-manager/"
SOCIAL_AUTH_OIDC_KEY = "<Client ID>"
SOCIAL_AUTH_OIDC_SECRET = "<Client Secret>"
SOCIAL_AUTH_OIDC_SCOPE = ["openid", "profile", "email", "roles"]
LOGOUT_REDIRECT_URL = "https://authentik.example.net/application/o/peering-manager/end-session/"
This will add a new button on the login page that will redirect a user to authenticate by using Authentik.
Managing Groups
To manage groups in Peering Manager custom social auth pipelines are required.
To create them the SOCIAL_AUTH_PIPELINE
setting must be set like below.
SOCIAL_AUTH_PIPELINE = (
###################
# Default pipelines
###################
# Get the information we can about the user and return it in a simple
# format to create the user instance later. In some cases the details are
# already part of the auth response from the provider, but sometimes this
# could hit a provider API.
"social_core.pipeline.social_auth.social_details",
# Get the social uid from whichever service we're authing thru. The uid is
# the unique identifier of the given user in the provider.
"social_core.pipeline.social_auth.social_uid",
# Verifies that the current auth process is valid within the current
# project, this is where emails and domains whitelists are applied (if
# defined).
"social_core.pipeline.social_auth.auth_allowed",
# Checks if the current social-account is already associated in the site.
"social_core.pipeline.social_auth.social_user",
# Make up a username for this person, appends a random string at the end if
# there's any collision.
"social_core.pipeline.user.get_username",
# Send a validation email to the user to verify its email address.
# Disabled by default.
# 'social_core.pipeline.mail.mail_validation',
# Associates the current social details with another user account with
# a similar email address. Disabled by default.
# 'social_core.pipeline.social_auth.associate_by_email',
# Create a user account if we haven't found one yet.
"social_core.pipeline.user.create_user",
# Create the record that associates the social account with the user.
"social_core.pipeline.social_auth.associate_user",
# Populate the extra_data field in the social record with the values
# specified by settings (and the default ones like access_token, etc).
"social_core.pipeline.social_auth.load_extra_data",
# Update the user record with any changed info from the auth service.
"social_core.pipeline.user.user_details",
###################
# Custom pipelines
###################
# Set authentik Groups
"peering_manager.custom_pipeline.add_groups",
"peering_manager.custom_pipeline.remove_groups",
# Set Roles
"peering_manager.custom_pipeline.set_roles",
)
The last lines refer to a Python module named custom_pipeline
which contains
the logic to manage groups and roles for users. A working example of this
module is given below and can be used in a file located in
peering_manager/custom_pipeline.py
.
import contextlib
from django.contrib.auth.models import Group
def add_groups(response, user, backend, *args, **kwargs):
with contextlib.suppress(KeyError):
groups = response["groups"]
# Add all groups from oauth token
for g in groups:
group, _ = Group.objects.get_or_create(name=g)
group.user_set.add(user)
def remove_groups(response, user, backend, *args, **kwargs):
try:
groups = response["groups"]
except KeyError:
# Remove all groups if no groups in oauth token
user.groups.clear()
# Get all groups of user
user_groups = [item.name for item in user.groups.all()]
# Get groups of user which are not part of oauth token
delete_groups = list(set(user_groups) - set(groups))
# Delete non oauth token groups
for g in delete_groups:
group = Group.objects.get(name=g)
group.user_set.remove(user)
def set_roles(response, user, backend, *args, **kwargs):
try:
groups = response["groups"]
# Set roles is role (superuser or staff) is in groups
user.is_superuser = "superusers" in groups
user.is_staff = "staff" in groups
except KeyError:
user.is_superuser = False
user.is_staff = False
user.save()
In Peering Manager, the special user roles "superuser" and "staff" can be assigned. With the above code, they will be set based on the superusers or staff groups set in authentik.