Reusable Django app for SSO integration
Project description
Django-Keycloak Integration
Main Settings Configuration
KEYCLOAK_SERVER_URL = config('KEYCLOAK_SERVER_URL', default="http://localhost:8080", cast=str)
KEYCLOAK_ISSUER_PREFIX = config('KEYCLOAK_ISSUER_PREFIX', default="http://localhost:8080", cast=str)
KEYCLOAK_REALM = config('KEYCLOAK_REALM', cast=str)
KEYCLOAK_CLIENT_ID = config('KEYCLOAK_CLIENT_ID', cast=str)
KEYCLOAK_CLIENT_TITLE = config('KEYCLOAK_CLIENT_TITLE', cast=str)
KEYCLOAK_CLIENT_NAME = config('KEYCLOAK_CLIENT_NAME', cast=str)
KEYCLOAK_CLIENT_SECRET = config('KEYCLOAK_CLIENT_SECRET', cast=str)
KEYCLOAK_ALGORITHMS = config('KEYCLOAK_ALGORITHMS', cast=str, default='RS256')
KEYCLOAK_OAUTH_REDIRECT_URI = config(
'KEYCLOAK_OAUTH_REDIRECT_URI',
default="http://127.0.0.1:8000/auth/callback/",
cast=str
)
KEYCLOAK_DEFAULT_ADMIN_PANEL_PERMISSION_CLASSES = [
'django_keycloak_sso.permissions.IsAuthenticatedAccess'
] # default permission to access keycloak admin data endpoints
examples:
KEYCLOAK_SERVER_URL=https://sso.domain # if using in dokcer : https://<keycloak_container>:8443
KEYCLOAK_ISSUER_PREFIX=https://sso.domain
KEYCLOAK_REALM=main
KEYCLOAK_CLIENT_ID=ecommerce-back
KEYCLOAK_CLIENT_SECRET=<client_secret_key>
KEYCLOAK_OAUTH_REDIRECT_URI=http://127.0.0.1:8000/auth/callback/ # for login in ssr sites
KEYCLOAK_CLIENT_NAME=ecommerce
KEYCLOAK_CLIENT_TITLE=ecommerce-back
KEYCLOAK_ALGORITHMS=RS256
Authentication and Middlewares class usage
Mock default django or DRF authentication proccess
you can access to user in views like :
user = request.user
user.id
user.username
-
KeycloakAuthentication
-
KeycloakMiddleware
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'django_keycloak_sso.middlewares.KeycloakAuthentication', ] } # Usable for DRF services MIDDLEWARE = [ 'django_keycloak_sso.middlewares.KeycloakMiddleware', ] # Usable for SSR websites
note : KeycloakAuthentication is enough for DRF backend services
User Attrs and Properties
request.user is a instance of CustomUser class with these properties :
-
groups
-
groups_dict_list
-
groups_parent
-
group_roles
-
realm_roles
-
client_roles
-
roles
-
id
-
username
-
first_name
-
last_name
-
full_name
-
groups_id
-
All other keycloak user properties ...
Permission Decorators
These decorators provide fine-grained access control for your views using Keycloak user attributes. They can be used on Django views, DRF APIViews, or function-based views. All decorators rely on the check_user_permission_access function internally.
All decorators are stackable — combine multiple for more specific permission control.
Available Decorators
from django_keycloak_sso.decorators import (
require_roles,
require_groups,
require_group_roles,
require_all_permissions
)
@require_roles(*role_titles)
Checks if the user has all of the specified realm or client roles.
@require_roles('superuser', 'admin')
def view_func(request):
pass
@require_groups(*group_titles)
Checks if the user is a member of all specified group names.
@require_groups('group_1')
def view_func(request):
pass
@require_group_roles(*group_roles, match_group_roles=False)
Checks if the user has at least one of the specified roles within any group. Use match_group_roles=True to only allow matches where the group name is also explicitly listed via @require_groups.
@require_group_roles('manager') # Any group
@require_group_roles('admin', match_group_roles=True) # Must match both group and role
def view_func(request):
pass
@require_all_permissions(role_titles=[], group_titles=[], group_roles=[], match_group_roles=False)
Combined decorator that allows you to check all types of permissions in one call.
@require_all_permissions(
role_titles=['superuser'],
group_titles=['group_1'],
group_roles=['manager'],
match_group_roles=True
)
def view_func(request):
pass
Stacking Decorators
You can combine decorators for more control:
@require_roles('superuser')
@require_groups('group_1')
@require_group_roles('manager')
def view_func(request):
pass
All decorators raise PermissionDenied (403) if access checks fail.
Make sure your view expects an authenticated user (request.user.is_authenticated is checked internally).
Permission Classes
-
IsManagerAccess
-
IsSuperUserAccess
-
IsSuperUserOrManagerAccess
Usage Examples
class TestView(APIView):
http_method_names = ('get',)
permission_classes = (IsManagerAccess,)
Predefined Model, Meta Class, Fields
-
SSOModelMeta
-
CustomMetaSSOModelSerializer
-
SSOGroupField
-
SSOUserField
-
SSOUserM2MField
Usage Examples
from django_keycloak_sso.sso import fields as sso_fields
from django_keycloak_sso.sso.meta import CustomMetaSSOModelSerializer, SSOModelMeta
class Server(Model, metaclass=SSOModelMeta):
user = sso_fields.SSOUserField(verbose_name=_("User"))
group_id = sso_fields.SSOGroupField(verbose_name=_("Group"))
class ServerSerializer(CustomMetaSSOModelSerializer):
class Meta:
model = Server
fields = (...)
Benefits of using SSOModelMeta and SSO Fields:
-
access to sso field data
mode_obj.fieldname_data # mock django relation fields behavior my_server.user_data # get a dict of user datas my_server.user_data.username # get a key from sso field data # NOTE : Do same with group fields
-
auto validation field object exists in keycloak
when using CustomMetaSSOModelSerializer in a serializer and wants to create a instance with that serializer. it will automatically validate existence of data in keycloak and if not return proportionate error.
Define Endpoints
urlpatterns = [
path('accounts/', include('django_keycloak_sso.urls')),
]
Endpoints List
-
/v1/auth/login/
-
/v1/auth/refresh/
-
/v1/auth/logout/
-
/v1/sso/profile/
-
/v1/sso/groups/
-
/v1/sso/groups/<group_id>/
-
/v1/sso/users/
-
/v1/sso/users/<user_id>/
Note : for more information about how to use them, check created swagger for your project
Usefull Utilities
get_serializer_field_data
from django_keycloak_sso.sso.sso import SSOKlass sso_klass = SSOKlass() class TestSerializer(ModelSerializer): user_data = SerializerMethodField() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) queryset = args[0] if len(args) >= 1 else None self.user_list_data = list() if queryset and (isinstance(queryset, QuerySet) or isinstance(queryset, list)): self.user_list_data = sso_klass.get_sso_data_list( queryset, 'user', # field name defined in model sso_klass.SSOFieldTypeChoices.USER ) def get_user_data(self, obj) -> dict | None: return sso_klass.get_serializer_field_data( field_name='user', # field name defined in model field_type=sso_klass.SSOFieldTypeChoices.USER, # Or GROUP obj_=obj, list_data=self.user_list_data, # Optional for optimize list data caching get_from_list=True # True if you want use <list_data> )
send_request
integration with keycloak
keycloak_klass = KeyCloakConfidentialClient() users_data = keycloak_klass.send_request( self.keycloak_klass.KeyCloakRequestTypeChoices.USER_ROLES, # has many options to integrate with keycloak self.keycloak_klass.KeyCloakRequestTypeChoices, self.keycloak_klass.KeyCloakRequestMethodChoices.GET, self.keycloak_klass.KeyCloakPanelTypeChoices.ADMIN, detail_pk='1234', # Additional data args extra_headers={} #Additional request headers )
Advanced Usage
For get more facilities and features go deep on these classes :
-
SSOKlass
-
SSOCacheControlKlass
-
KeyCloakBaseManager
-
KeyCloakConfidentialClient
-
KeyCloakInitializer
-
BaseKeycloakAdminView
-
CustomSSORelatedField
Note: To get most caching performance use REDIS as cache system (especially HiRedis)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_keycloak_sso-0.2.1.tar.gz.
File metadata
- Download URL: django_keycloak_sso-0.2.1.tar.gz
- Upload date:
- Size: 61.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95867376ea8e5cbc0b0833af5478cd10637057e5f1ae87f849a066a662dc549c
|
|
| MD5 |
6ffa2680c36afa9d5b832856601e1c23
|
|
| BLAKE2b-256 |
c802f35555eecb57d87b0d18cfbb87b5a735a6320a3eb2eeb59d4b84fc266edf
|
File details
Details for the file django_keycloak_sso-0.2.1-py3-none-any.whl.
File metadata
- Download URL: django_keycloak_sso-0.2.1-py3-none-any.whl
- Upload date:
- Size: 56.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a34ad8d142669326c65468270624d393a81c37fdf5aacb1047142320ec78e4a
|
|
| MD5 |
cb2667e01d785b63f8095f0a136cae44
|
|
| BLAKE2b-256 |
394d5202a755f41cfc7de048f12872e5c466061848e58a9f82f2667bd6b53da0
|