Skip to main content

django_wso2is

A Django application that enables authentication against a remote WSO2 Identity Server.

Installation

pip install django-wso2is-auth

Getting started

  1. In your Django project's settings file, change the Django AUTHENTICATION_BACKENDS to:
AUTHENTICATION_BACKENDS = ['django_wso2is.backends.WSO2isAuthenticationBackend',]
  1. 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'
    ],
}
  1. 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)

Source distribution for django-wso2is-auth 0.0.1
File Size Uploaded
django-wso2is-auth-0.0.1.tar.gz 13.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-wso2is-auth 0.0.1
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

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