django_wso2is
A Django application that enables authentication against a remote WSO2 Identity Server.
Installation
pip install django-wso2is-auth
Getting started
- In your Django project's settings file, change the Django
AUTHENTICATION_BACKENDSto:
AUTHENTICATION_BACKENDS = ['django_wso2is.backends.WSO2isAuthenticationBackend',]
- If you are using Rest framework and want to authenticate API requests against WSO2 Identity server:
REST_FRAMEWORK = {
# ... other rest framework settings.
'DEFAULT_AUTHENTICATION_CLASSES': [
'django_wso2_is.authentication.BearerAuthentication'
],
}
- Lastly, you need to provide some settings:
WSO2IS_CONFIG = {
# The URL of your WSO2 identity server
"SERVER_URL": "<str>",
# The "OAuth Client Key" of your service provider
"OAUTH_CLIENT_ID": "<str>",
# The "OAuth Client Secret" of your service provider
"OAUTH_SECRET_KEY": "<str>",
# The username of the service provider admin
"ADMIN_USER_USERNAME": "<str>",
# The password of the service provider admin
"ADMIN_USER_SECRET_KEY": "<str>",
# The name of the admin role for the client (e.g. `Application/Administration`)
"CLIENT_ADMIN_ROLE": "<str>",
# The group's admin role name
"GROUP_ADMIN_ROLE": "<str>",
# Whether the validity of the server's SSL certificate should be validated.
# default=`False`. WARNING: This should be `True` in production environments.
"VERIFY_SSL": False,
# When a user is successfully authenticated with the WSO2 server this user
# will be created or updated in the local database. This search is based on `DJANGO_USER_LOOKUP_FIELD`.
# This field is optional (default=None), and in such cases the lookup is performed based on the `USERNAME` field
# of the auth user model, which by default corresponds to the `username` field.
# For instance, if you want this lookup to be based on email
# you can specify `"DJANGO_USER_LOOKUP_FIELD": "email"`
DJANGO_USER_LOOKUP_FIELD: None,
# This dictionary makes the mapping between attributes of the local user with attributes of the remote user.
# This field is optional (default=None), but it is HIGHLY recommended you customize it. By default only `username` get's mapped
# to WSO2's attribute "userName". A more detailed example of how to customize this field will be presented below.
ATTRIBUTE_MAPPING: {"username": "userName"} # dict in format 'local_attribute' : 'remote_attribute'
}
You are all set!
Advanced usage
1. Customizing attribute mapping
As previously mentioned, only the mapping between the username field is done. Let's say you have the following django User model:
class MyUser(AbstractBaseUser):
# first_name, last_name and email exist by default in django.contrib.auth user model
# Now we specify new custom fields to save the user's organization and phone number from WSO2 identity server
user_organization = models.CharField(max_length=255,null=True, blank=True)
phone_number = models.CharField(max_length=255, null=True, blank=True)
external_id = models.CharField(max_length=255, null=True, blank=True)
First we can inspect the JSON response from WSO2 to see the user information that is being returned to django. (This assumes you already configured everything else)
# Inside django's shell (python manage.py shell)
from django_wso2is import Token
from pprint import pprint
token = Token.from_credentials("sample-username", "sample-password")
pprint(token.user_info)
You should get something like this:
{'emails': ['sample-email@gmail.com'],
'id': '6b15e727-6b52-4d15-a9c9-b166a0439aa1',
'meta': {'created': '2023-01-19T10:44:51.563609Z',
'lastModified': '2023-01-19T15:52:48.282703Z',
'location': 'https://sample-wso2is-server:9443/scim2/Users/6b15e727-6b52-4d15-a9c9-b166a0439aa1',
'resourceType': 'User'},
'name': {'familyName': 'John', 'givenName': 'Doe'},
'phoneNumbers': [{'type': 'mobile', 'value': '914420876'}],
'roles': [{'type': 'default',
'value': 'Internal/everyone,Application/Administração'},
{'$ref': 'https://sample-wso2is-server:9443/scim2/Roles/f0da2c12-f4c5-49dd-81f6-5077dfdd98d1',
'display': 'Application/Administration',
'value': 'f0da2c12-f4c5-49dd-81f6-5077dfdd98d1'},
{'$ref': 'https://sample-wso2is-server:9443/scim2/Roles/75ace894-dc8b-495f-8438-60a066d84966',
'display': 'everyone',
'value': '75ace894-dc8b-495f-8438-60a066d84966'}],
'schemas': ['urn:ietf:params:scim:schemas:core:2.0:User',
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'],
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User': {'country': 'Portugal',
'organization': 'My organization'},
'userName': 'sample-username'}
To accommodate these additional fields the attribute mapping will be:
"ATTRIBUTE_MAPPING": {
"username": "userName",
"email": "emails[0]", # [0] because WSO2 returns the key "emails" as a list
"phone_number": "phoneNumbers[0].value", # [0].value because WSO2 returns the key "phoneNumbers" as a list of objects with key "value"
"first_name": "name.givenName", # .givenName because WSO2 returns nested "name" object
"last_name": "name.familyName", # .familyName for the same reason as before
"external_id": "id", # Simple attribute mapping
},
2. Post authentication signal
If you want to hook additional behaviour after an user has been authenticated, you can simply attach to the user_authenticated signal. For instance, let's say we want to also get/create and associate with the user a Group object based on the user WSO2 roles.
yourapp/signals.py
from django.contrib.auth.models import Group
from django.dispatch import receiver
from django_wso2is.signals import user_authenticated
from django_wso2is import Token
@receiver(user_authenticated)
def wso2_user_authenticated(sender, user, token: Token, **kwargs):
# Get user roles
roles: list[str] = [role for role in token.client_roles]
for role in roles:
group, _ = Group.objects.get_or_create(name=role)
user.groups.add(group)
user.save()
Metadata
Release files for django-wso2is-auth 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django-wso2is-auth-0.0.1.tar.gz | 13.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_wso2is_auth-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.5 kB
Release files / django-wso2is-auth-0.0.1.tar.gz
| Download URL | django-wso2is-auth-0.0.1.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
842b3affde2139fbe84cab0f3c80ba565e9a3f768ddaef37c08150f2bb6395ed
|
|
BLAKE2b-256 checksum How to use checksums |
db4cb6e4805c367de8ec98db58722b2d04d6446171d76861daa429df21835ee8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.9.16
|
Release files / django_wso2is_auth-0.0.1-py3-none-any.whl
| Download URL | django_wso2is_auth-0.0.1-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6b533e32b40b1f2847b5c9aead45bc271c26444d69d8a31677bd635be075e883
|
|
BLAKE2b-256 checksum How to use checksums |
05882ee84dedbb87b5ffb56c6650a7880a43c18b557bf169dfae02137f26d1e6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.9.16
|