Add Django CAS authentication support
Introduce support for Central Authentication Service (CAS) alongside existing OIDC and SAML by integrating a new CAS server app and custom CAS authentication user model. Streamline sign-in infrastructure with updated URL patterns. As part of the update, refactor user model `username` resolution to leverage the email field directly. Includes necessary Django migrations to support new authentication features and removes a deprecated OIDC provider dependency.
This commit is contained in:
parent
28e7cf8e5b
commit
da49ddabcc
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Python: Django",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/manage.py",
|
||||||
|
"args": [
|
||||||
|
"runserver",
|
||||||
|
"8087"
|
||||||
|
],
|
||||||
|
"django": true,
|
||||||
|
"justMyCode": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
12
authentication/cas.py
Normal file
12
authentication/cas.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from cas_server.auth import DjangoAuthUser
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
class KumiDCAuthUser(DjangoAuthUser):
|
||||||
|
def __init__(self, username):
|
||||||
|
User = get_user_model()
|
||||||
|
try:
|
||||||
|
self.user = User.objects.get_by_natural_key(username)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
pass
|
||||||
|
super(DjangoAuthUser, self).__init__(username)
|
64
authentication/migrations/0003_appkey_appsession.py
Normal file
64
authentication/migrations/0003_appkey_appsession.py
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# Generated by Django 5.0 on 2023-12-19 20:19
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("authentication", "0002_alter_totpsecret_user"),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="AppKey",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.UUIDField(
|
||||||
|
default=uuid.uuid4,
|
||||||
|
editable=False,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("device", models.CharField(max_length=255)),
|
||||||
|
("key", models.TextField()),
|
||||||
|
("active", models.BooleanField(default=True)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="AppSession",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.UUIDField(
|
||||||
|
default=uuid.uuid4,
|
||||||
|
editable=False,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("created", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("used", models.DateTimeField(blank=True, null=True)),
|
||||||
|
("approved", models.BooleanField(default=False)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -8,7 +8,6 @@ import django.db.models.deletion
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('oidc_provider', '0027_auto_20220810_0605'),
|
|
||||||
('core', '0005_profile_last_name'),
|
('core', '0005_profile_last_name'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,14 @@ class User(AbstractBaseUser, PermissionsMixin):
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
date_joined = models.DateTimeField(auto_now_add=True)
|
date_joined = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
USERNAME_FIELD = 'email'
|
USERNAME_FIELD = "email"
|
||||||
REQUIRED_FIELDS = []
|
REQUIRED_FIELDS = []
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def username(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.email
|
return self.email
|
||||||
|
|
|
@ -48,6 +48,7 @@ INSTALLED_APPS = [
|
||||||
|
|
||||||
'oidc_provider',
|
'oidc_provider',
|
||||||
'djangosaml2idp',
|
'djangosaml2idp',
|
||||||
|
'cas_server',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -238,6 +239,10 @@ DEFAULT_SPCONFIG = {
|
||||||
'show_user_agreement_screen': SAML_IDP_SHOW_USER_AGREEMENT_SCREEN
|
'show_user_agreement_screen': SAML_IDP_SHOW_USER_AGREEMENT_SCREEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CAS Settings
|
||||||
|
|
||||||
|
CAS_AUTH_CLASS = "authentication.cas.KumiDCAuthUser"
|
||||||
|
|
||||||
# Session Timeouts
|
# Session Timeouts
|
||||||
|
|
||||||
REVERIFY_AFTER_INACTIVITY_MINUTES = 5
|
REVERIFY_AFTER_INACTIVITY_MINUTES = 5
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, re_path, include, reverse_lazy
|
from django.urls import path, include, reverse_lazy
|
||||||
from django.views.generic import RedirectView
|
from django.views.generic import RedirectView
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r'^openid/', include('oidc_provider.urls', namespace='oidc_provider')),
|
path('openid/', include('oidc_provider.urls', 'oidc_provider')),
|
||||||
|
path('saml/', include('djangosaml2idp.urls', 'djangosaml2idp')),
|
||||||
re_path(r'^saml/', include('djangosaml2idp.urls')),
|
path('cas/', include('cas_server.urls', "cas_server")),
|
||||||
|
|
||||||
path('admin/login/', RedirectView.as_view(url=reverse_lazy("auth:login"), query_string=True)),
|
path('admin/login/', RedirectView.as_view(url=reverse_lazy("auth:login"), query_string=True)),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
Django
|
Django
|
||||||
|
|
||||||
git+https://kumig.it/kumitterer/django-oidc-provider/
|
git+https://kumig.it/kumitterer/django-oidc-provider/
|
||||||
|
git+https://kumig.it/kumitterer/django-cas-server/
|
||||||
git+https://github.com/OTA-Insight/djangosaml2idp/
|
git+https://github.com/OTA-Insight/djangosaml2idp/
|
||||||
|
|
||||||
dbsettings
|
dbsettings
|
||||||
|
|
Loading…
Reference in a new issue