Skip to main content

DRF Keycloak Auth

Requirements

  • Python >= 3.10
  • Django
  • Django Rest Framework
  • Python Keycloak

Installation

$ pip install drf-keycloak-auth

Add the application to your project's INSTALLED_APPS in settings.py.

INSTALLED_APPS = [
    ...
    'drf_keycloak_auth',
]

In your project's settings.py, add this to the REST_FRAMEWORK configuration. Note that if you want to retain access to the browsable API, then you will want KeycloakSessionAuthentication too.

REST_FRAMEWORK = {
  ...
  'DEFAULT_AUTHENTICATION_CLASSES': [
    ...
    'drf_keycloak_auth.authentication.KeycloakSessionAuthentication',
    'drf_keycloak_auth.authentication.KeycloakAuthentication',
  ]
}

The drf_keycloak_auth application comes with the following settings as default, which can be overridden in your project's settings.py file. Make sure to nest them within DRF_KEYCLOAK_AUTH as below:

# should be comma separated string
KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF = \
    os.getenv('KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF')

DEFAULTS = {
    'KEYCLOAK_SERVER_URL': os.getenv('KEYCLOAK_SERVER_URL'),
    'KEYCLOAK_REALM': os.getenv('KEYCLOAK_REALM'),
    'KEYCLOAK_CLIENT_ID': os.getenv('KEYCLOAK_CLIENT_ID'),
    'KEYCLOAK_CLIENT_SECRET_KEY': os.getenv('KEYCLOAK_CLIENT_SECRET_KEY'),
    'KEYCLOAK_VERIFY_SSL': os.getenv('KEYCLOAK_VERIFY_SSL', True),
    'KEYCLOAK_AUTH_HEADER_PREFIX':
        os.getenv('KEYCLOAK_AUTH_HEADER_PREFIX', 'Bearer'),
    'KEYCLOAK_ROLE_SET_PREFIX':
        os.getenv('KEYCLOAK_ROLE_SET_PREFIX', 'role:'),
    'KEYCLOAK_MANAGE_LOCAL_USER':
        os.getenv('KEYCLOAK_MANAGE_LOCAL_USER', True),
    'KEYCLOAK_MANAGE_LOCAL_GROUPS':
        os.getenv('KEYCLOAK_MANAGE_LOCAL_GROUPS', False),
    'KEYCLOAK_DJANGO_USER_UUID_FIELD':
        os.getenv('KEYCLOAK_DJANGO_USER_UUID_FIELD', 'pk'),
    'KEYCLOAK_FIELD_AS_DJANGO_USERNAME':
        os.getenv('KEYCLOAK_FIELD_AS_DJANGO_USERNAME', 'preferred_username'),
    'KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF': (
        [x.strip() for x in KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF.split(',')]
        if KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF
        else ['admin']  # can be list, tuple or set
    )
}

All you need to do now is have your client code handle the Keycloak authentication flow, retrieve the access_token for the user, and then use the access_token for the user in an Authorization header in requests to your API.

Bearer <token>

Roles will be present in request.roles with a KEYCLOAK_ROLE_SET_PREFIX prefix (only if succesfully authenticated), e.g.:

['role:admin', 'a4a9be6e-bd04-42f8-9377-27d9db82216f']

except for the authenticated user's pk field, e.g. for a user model using uuid's as primary key:

['role:user', 'a4a9be6e-bd04-42f8-9377-27d9db82216f']

where the pk can be used for checking object ownership.

If you wish to create your own role permissions:

https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

simply import and use the prefix helper:

from .keycloak import prefix_role

ROLE_USER = prefix_role('user')
ROLE_SERVICE = prefix_role('service')
ROLE_ADMIN = prefix_role('admin')

request.user.is_staff will be modified based upon roles in KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF. These roles can be hard coded as a list, tuple or set, or from a comma-separated env var. Functionality ignored if KEYCLOAK_ROLES_TO_DJANGO_IS_STAFF is None or empty.

If your user model doesn't / can't have a UUID primary key, override the KEYCLOAK_DJANGO_USER_UUID_FIELD setting to indicate a unique UUIDField on your model, e.g.:

KEYCLOAK_DJANGO_USER_UUID_FIELD = 'uuid'

Voila!

Multi tenancy/site support

An application can be configured for multiple sites by using different Keycloak Realms on the same or seperate Keycloak instances by using the environment var KEYCLOAK_MULTI_OIDC_JSON

The client OIDC adaptor json file can be downloaded from Keycloak.

KEYCLOAK_MULTI_OIDC_JSON:

{
    "auth.example.org": {
        "realm": "example",
        "auth-server-url": "https://auth.example.org/auth/",
        "ssl-required": "external",
        "resource": "my-client",
        "verify-token-audience": true,
        "credentials": {
          "secret": "my-secret"
        }
    }
}

KeycloakMultiAuthentication should be configured as the authentication class.

REST_FRAMEWORK = {
  ...
  'DEFAULT_AUTHENTICATION_CLASSES': [
    ...
    'drf_keycloak_auth.authentication.KeycloakMultiAuthentication',
  ]
}

NOTE: This will ignore DEFAULTS parameters for hostname, realm and client credentials.
All other parameters are still shared accross sites.


Session auth

This library includes KeycloakSessionAuthentication for using the Standard flow Keycloak login to interact directly with a browsable API.

Requires 'Standard flow' to be enabled in the Keycloak client and a valid redirect URL to be configured.

Configuration

settings.py:

  'DEFAULT_AUTHENTICATION_CLASSES': [
    'drf_keycloak_auth.authentication.KeycloakSessionAuthentication',
  ]

urls.py:

    urlpatterns = [
        path('api-auth/', include('drf_keycloak_auth.urls', namespace='rest_framework'))
    ]

Contributing

  • Please raise an issue/feature and name your branch 'feature-n' or 'issue-n', where 'n' is the issue number.

Metadata

Release files for drf-keycloak-auth 0.5.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for drf-keycloak-auth 0.5.6
File Size Uploaded Provenance
drf_keycloak_auth-0.5.6.tar.gz 15.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for drf-keycloak-auth 0.5.6
File Interpreter ABI Platform
drf_keycloak_auth-0.5.6-py3-none-any.whl Python 3 none any Details

Total release size: 31.5 kB

Release files / drf_keycloak_auth-0.5.6.tar.gz

Download URL drf_keycloak_auth-0.5.6.tar.gz
Size 15.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6402b6be17c7507f0ba0fc87731abce8b6d62d4a275f48e3a2ebbf3f06b90c1e
BLAKE2b-256 checksum
How to use checksums
29c6624d3e0f7200351432489bb79c58af527ab48ef36547006b7dcce5d41b99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / drf_keycloak_auth-0.5.6-py3-none-any.whl

Download URL drf_keycloak_auth-0.5.6-py3-none-any.whl
Size 16.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2fdcd485259e8362754ed4de64f474414b2b723ce72303e9e7c892fb9d322cf1
BLAKE2b-256 checksum
How to use checksums
56e51e4b938ff804f6d7264a0d40bd422fb47123d1677cc08caa09f5119a253c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Security for drf-keycloak-auth 0.5.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.5.6 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page