Skip to main content

A convenience libary for authenticating users from Keycloak access tokens

Project description

DRF Keycloak Auth

Requirements

  • Python >= 3.4
  • 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 for locally created users, then you will probably want to keep rest_framework.authentication.SessionAuthentication too.

REST_FRAMEWORK = {
  ...
  'DEFAULT_AUTHENTICATION_CLASSES': [
    ...
    'rest_framework.authentication.SessionAuthentication',
    '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_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 support

An application can be configured for multiple tenancies 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=
{
"hostname1": { OIDC adaptor },
"hostname2": { OIDC adaptor },
}

KeycloakMultiAuthentication should be configured as the authentication class.

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

NOTE: This will ignore DEFAULTS parameters for hostname, realm and client credentials. All other parameters are still shared accross tenancies. NOTE2: KeycloakAuthentication can still be present as a fallback for simpler cases like local dev.


Contributing

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf_keycloak_auth-0.3.1.tar.gz (12.0 kB view details)

Uploaded Source

Built Distribution

drf_keycloak_auth-0.3.1-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file drf_keycloak_auth-0.3.1.tar.gz.

File metadata

  • Download URL: drf_keycloak_auth-0.3.1.tar.gz
  • Upload date:
  • Size: 12.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.7

File hashes

Hashes for drf_keycloak_auth-0.3.1.tar.gz
Algorithm Hash digest
SHA256 f5856f947da39e4a6e858492abeca2d1da24360265029d2f1850e19e615b1ad9
MD5 d6c6471921f2752e1593373e81cda4e6
BLAKE2b-256 4b5408fee74a38ca76265833bb7b6ae5b53a19b955bce15d214129e594c8f08b

See more details on using hashes here.

File details

Details for the file drf_keycloak_auth-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for drf_keycloak_auth-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3d30e4fb7815a826749a9289aeed888b0c2e6a14229d714f479d1e4786cb3f20
MD5 5a4b680e958476c5013d2302e83ef652
BLAKE2b-256 50dfb7ec2e4e2cf8a13ee1b9f2bfa0b239053f97ba093e96dc68396b1791eea7

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page