Package: drf-keycloak-auth
DRF Keycloak AuthRequirementsPython >= 3.4DjangoDjango Rest FrameworkPython KeycloakInstallation$ pip install drf-keycloak-authAdd the application to your project'sINSTALLED_APPSinsettings.py.INSTALLED_APPS = [
    ...
    'drf_keycloak_auth',
]In your project'ssettings.py, add this to theREST_FRAMEWORKconfiguration. Note that if you want to retain access to the browsable API for locally created users, then you will probably want to keeprest_framework.authentication.SessionAuthenticationtoo.REST_FRAMEWORK = {
  ...
  'DEFAULT_AUTHENTICATION_CLASSES': [
    ...
    'rest_framework.authentication.SessionAuthentication',
    'drf_keycloak_auth.authentication.KeycloakAuthentication',
  ]
}Thedrf_keycloak_authapplication comes with the following settings as default, which can be overridden in your project'ssettings.pyfile. Make sure to nest them withinDRF_KEYCLOAK_AUTHas below:# should be comma separated stringKEYCLOAK_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()forxinKEYCLOAK_ROLES_TO_DJANGO_IS_STAFF.split(',')]ifKEYCLOAK_ROLES_TO_DJANGO_IS_STAFFelse['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 anAuthorizationheader in requests to your API.Bearer <token>Roles will be present inrequest.roleswith aKEYCLOAK_ROLE_SET_PREFIXprefix (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-permissionssimply import and use the prefix helper:from.keycloakimportprefix_roleROLE_USER=prefix_role('user')ROLE_SERVICE=prefix_role('service')ROLE_ADMIN=prefix_role('admin')request.user.is_staff will be modified based upon roles inKEYCLOAK_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 theKEYCLOAK_DJANGO_USER_UUID_FIELDsetting to indicate a uniqueUUIDFieldon your model, e.g.:KEYCLOAK_DJANGO_USER_UUID_FIELD = 'uuid'Voila!Multi tenancy supportAn application can be configured for multiple tenancies by using different Keycloak Realms on the same or seperate Keycloak instances by using the environment varKEYCLOAK_MULTI_OIDC_JSONThe 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 ignoreDEFAULTSparameters for hostname, realm and client credentials.  All other parameters are still shared accross tenancies.
NOTE2:KeycloakAuthenticationcan still be present as a fallback for simpler cases like local dev.ContributingPlease raise an issue/feature and name your branch 'feature-n' or 'issue-n', where 'n' is the issue number.