Custom Backends

The CASBackend class is heavily inspired from Django’s own RemoteUserBackend and allows for some configurability through subclassing. If you need more control than django-cas-ng’s settings provide. For instance, here is an example backend that only allows some users to login through CAS:

from django_cas_ng.backends import CASBackend

class MyCASBackend(CASBackend):
    def user_can_authenticate(self, user):
        if user.has_permission('can_cas_login'):
            return True
        return False

If you need more control over the authentication mechanism of your project than django-cas-ng’s settings provide, you can create your own authentication backend that inherits from django_cas_ng.backends.CASBackend and override these attributes or methods:

  • CASBackend.clean_username(username)

  • CASBackend.user_can_authenticate(user)

    Returns whether the user is allowed to authenticate. For consistency with Django’s own behavior, django-cas-ng will allow all users to authenticate through CAS on Django versions lower than 1.10; starting with Django 1.10 however, django-cas-ng will prevent users with is_active=False from authenticating. See also django.contrib.auth.backends.RemoteUserBackend.

  • CASBackend.configure_user(user)

  • CASBackend.bad_attributes_reject(request, username, attributes)

Example

For example, to accept a user belonging to departmentNumber 421 only, define in mysite/settings.py the key-value constant:

MY_ATTRIBUTE_CONTROL = ('departmentNumber', '421')

and the authentication backends:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'mysite.backends.MyCASBackend',
]

and create a file mysite/backends.py containing:

from django_cas_ng.backends import CASBackend
from django.contrib import messages
from django.conf import settings


class MyCASBackend(CASBackend):
    def user_can_authenticate(self, user):
        return True

    def bad_attributes_reject(self, request, username, attributes):
        attribute = settings.MY_ATTRIBUTE_CONTROL[0]
        value = settings.MY_ATTRIBUTE_CONTROL[1]

        if attribute not in attributes:
            message = 'No \''+ attribute + '\' in SAML attributes'
            messages.add_message(request, messages.ERROR, message)
            return message

        if value not in attributes[attribute]:
            message = 'User ' + str(username) + ' is not in ' + value + ' ' + attribute + ', should be one of ' + str(attributes[attribute])
            messages.add_message(request, messages.ERROR, message)
            return message

        return None

CASBackend API Reference

class django_cas_ng.backends.CASBackend[source]

Bases: django.contrib.auth.backends.ModelBackend

CAS authentication backend

authenticate(request: django.http.request.HttpRequest, ticket: str, service: str) → django.contrib.auth.models.User[source]

Verifies CAS ticket and gets or creates User object

Returns

[User] Authenticated User object or None if authenticate failed.

bad_attributes_reject(request: django.http.request.HttpRequest, username: str, attributes: Mapping[str, str])[source]

Rejects a user if the returned username/attributes are not OK.

Returns

[boolean] True/False. Default is False.

clean_username(username: str) → str[source]

Performs any cleaning on the username prior to using it to get or create the user object.

By default, changes the username case according to settings.CAS_FORCE_CHANGE_USERNAME_CASE.

Parameters

username – [string] username.

Returns

[string] The cleaned username.

configure_user(user: django.contrib.auth.models.User) → django.contrib.auth.models.User[source]

Configures a user after creation and returns the updated user.

This method is called immediately after a new user is created, and can be used to perform custom setup actions.

Parameters

user – User object.

Returns

[User] The user object. By default, returns the user unmodified.

get_user_id(attributes: Mapping[str, str]) → str[source]

For use when CAS_CREATE_USER_WITH_ID is True. Will raise ImproperlyConfigured exceptions when a user_id cannot be accessed. This is important because we shouldn’t create Users with automatically assigned ids if we are trying to keep User primary key’s in sync.

Returns

[string] user id.