Django SCIM 2.0 Service Provider
A partial implementation of the SCIM 2.0 provider specification for use with Django. It enables automatic provisioning and deprovisioning of user accounts and groups, facilitating identity synchronization across various identity providers and applications. The current stable version, as listed on PyPI, is 0.19.1, with development being stable and new releases occurring periodically, often focusing on Fridays.
Warnings
- breaking Version 0.20.0 (released April 2025) removed the `USE_L10N` setting, which impacts projects using Django 5+ as this setting is deprecated/removed in newer Django versions. Ensure your project is compatible or handle the removal.
- breaking In version 0.18.0, `SCIMAuthCheckMiddleware` transitioned from a global `MIDDLEWARE` setting to a decorator directly applied to SCIM view functions. It should no longer be listed in `MIDDLEWARE`. Customization is now done via the `AUTH_CHECK_MIDDLEWARE` key in `SCIM_SERVICE_PROVIDER`.
- breaking Version 0.16.0 introduced two significant breaking changes: SCIM IDs are now required to be unique across all objects of a specific model, and compatibility with Django versions before 2.2.13 was dropped.
- gotcha The library explicitly states that it does not implement authorization and authentication itself. These tasks are left for other Django apps (e.g., Django OAuth Toolkit) to provide. The `SCIMAuthCheckMiddleware` (or its decorator equivalent) simply checks `request.user.is_anonymous()` by default.
- gotcha The `SCIMAuthCheckMiddleware` (or the underlying decorator logic) must be processed *after* your primary Django authentication middleware. Otherwise, `request.user` might still be `AnonymousUser` when the SCIM check occurs, leading to unintended access denials.
- gotcha Currently, the only supported database for `django-scim2` is PostgreSQL. Using other database backends may lead to unexpected behavior or errors.
Install
-
pip install django-scim2
Imports
- SCIMAuthCheckMiddleware
from django_scim.middleware import SCIMAuthCheckMiddleware
- urls
from django.urls import path, include path('scim/v2/', include('django_scim.urls')) - SCIMUser
from django_scim.adapters import SCIMUser
- SCIMGroup
from django_scim.adapters import SCIMGroup
Quickstart
import os
# settings.py example
INSTALLED_APPS = [
# ... other Django apps
'django_scim',
]
# Note: As of 0.18.0, SCIMAuthCheckMiddleware is applied as a decorator
# to SCIM views and typically no longer needs to be in MIDDLEWARE.
# If you need custom auth check middleware, specify it in SCIM_SERVICE_PROVIDER.
MIDDLEWARE = [
# ... your authentication middleware (e.g., 'django.contrib.auth.middleware.AuthenticationMiddleware')
# 'django_scim.middleware.SCIMAuthCheckMiddleware', # DEPRECATED: See warning for 0.18.0
# Make sure your actual authentication middleware comes BEFORE this one if you add it directly.
# The SCIMAuthCheckMiddleware checks request.user.is_anonymous() by default.
]
# Required SCIM settings
SCIM_SERVICE_PROVIDER = {
'NETLOC': os.environ.get('SCIM_NETLOC', 'localhost:8000'), # E.g., 'your-domain.com'
'AUTHENTICATION_SCHEMES': [
{
'type': 'oauth2',
'name': 'OAuth 2',
'description': 'OAuth 2 implemented with bearer token',
},
],
# Optional: Customize the authentication check middleware
# 'AUTH_CHECK_MIDDLEWARE': 'your_app.middleware.CustomSCIMAuthMiddleware',
# Optional: Expose SCIM exceptions to clients (defaults to False for security)
# 'EXPOSE_SCIM_EXCEPTIONS': os.environ.get('SCIM_EXPOSE_EXCEPTIONS', False),
}
# urls.py example
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('scim/v2/', include('django_scim.urls')), # Namespace 'scim' is mandatory
]