BioConnect Authorization Template: Django Application:
The template include:
- django application with endpoints and users
- added authorization
Create Django Base Application
Create a Django base application, using peotry to manage the dependency
Create a new Poetry project
mkdir bioconnect-api-template && cd bioconnect-api-template
poetry init
Add Django and init Django project
poetry add django
poetry run django-admin startproject bioconnect_api_template .
poetry export -f requirements.txt --output requirements.txt
Run Django
python manage.py runserver
Create API endpoints
In order to create API endpoints, start to add a "sample" app into the project
python manage.py startapp sample
edit "models.py" in "sample" directory
from django.db import models
class Sample(models.Model):
"""
A sample
"""
name = models.CharField(max_length=256, null=False, blank=False)
description = models.CharField(max_length=5000, null=False, blank=False)
class Meta:
verbose_name = 'Sample'
verbose_name_plural = 'Samples'
edit "serializers.py" in "sample" directory
from rest_framework import serializers
from . import models
class SampleSerializer(serializers.ModelSerializer):
class Meta:
model = models.Sample
fields = '__all__'
edit "views.py" in "sample" directory
from rest_framework import viewsets
from rest_framework import permissions
from . import models, serializers
class SampleViewSet(viewsets.ModelViewSet):
queryset = models.Sample.objects.all()
serializer_class = serializers.SampleSerializer
permission_classes = [permissions.IsAuthenticated]
create a new file "urls.py" in "sample" directory
from django.urls import path
from . import views
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r"sample", views.SampleViewSet)
urlpatterns = router.urls
edit root "settings.py", add 'sample.apps.SampleConfig' to the "INSTALLED_APPS"
INSTALLED_APPS = [
'sample.apps.SampleConfig',
'django.contrib.admin',
...
]
edit root "urls.py", add new entry in URL
urlpatterns = [
path('sample/', include('sample.urls')),
...
]
save the model into the database
python manage.py makemigrations sample
python manage.py migrate
Add Swagger UI
add swagger UI library
poetry add django-rest-swagger
poetry add drf-yasg
edit root "urls.py", add swagger libray import and code
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from rest_framework import permissions
schema_view = get_schema_view(
openapi.Info(
title="BioConnect Template APIs",
default_version='v1',
description="API Specificiation for JAX BioConnect Template",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact@jax.org"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
re_path(r'^swagger(?P<format>\.json|\.yaml)$',
schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0),
name='schema-swagger-ui'),
......
]
BioConnect Authorization
Library installation
The BioConnect authorization library is available from PyPI, the Python packaging index.
https://test.pypi.org/project/bioconnect-lib
Installation can be done in the usual ways by adding the repository to your Poetry pyproject.toml file, or to requirements.py for pip. With pip from the command line do:
# add dependency
apache-ranger = "^0.0.5"
environs = "^9.5.0"
elasticsearch7 = "^7.17.1"
python-logstash = "^0.4.6"
azure-servicebus = "^7.6.1"
marshmallow = "^3.15.0"
pip install --index-url https://test.pypi.org/simple/ bioconnect-lib
New Permission Class
Add a new file "bioconnect_permission.py" to define a class "BioConnectPermisison".
The "BioConnectPermisison" is a subclass of "permissions.BasePermission" in the rest_framework.
It overwrites the two methods to use Apache Ranger for authorization.
This is the class for all the views.
from rest_framework import permissions
from bioconnect_lib.ranger.authorizer_api import ranger_is_access_allowed_api
from bioconnect_lib.ranger.request_api import AuthorizerRequestAPI
import logging
logger = logging.getLogger(__name__)
class BioConnectPermisison(permissions.BasePermission):
RANGER_SERVICE_NAME = 'bioconnect-api-template'
def has_permission(self, request, view):
if not request.user.is_authenticated:
return False
auth_request = AuthorizerRequestAPI(
user_id = request.user.username,
service_name = BioConnectPermisison.RANGER_SERVICE_NAME,
action = request.method,
host = request._request._current_scheme_host,
path = request.path,
)
try:
response = ranger_is_access_allowed_api(auth_request)
return response.is_allowed
logger.info(f'response: {response}')
except Exception as e:
logger.error("Failed to authorize", exc_info=True)
def has_object_permission(self, request, view, obj):
return True
Add Permission View
For the views to be protected, add import and the class to permission_classes
from rest_framework import viewsets
from rest_framework import permissions
from . import models, serializers
from bioconnect_api_template.bioconnect_permission import BioConnectPermisison
class SampleViewSet(viewsets.ModelViewSet):
queryset = models.Sample.objects.all()
serializer_class = serializers.SampleSerializer
permission_classes = [BioConnectPermisison]
Set Up Django Users
Create admin user by run
python manage.py createsuperuser
Start the app, and login to the admin console: http://localhost:8000/admin
Create two more users with user_id "guest", and "editor". Remember the password.
Only user_id and password matters, and all other fields can be ignored. The user_id
needs to match the exact user_id in the Ranger. The Ranger only does the
authorization based on the user_id.
Three users in the system:
- adimin
- editor
- viewer
Config in Apache Ranger
Add service
To use Apache Ranger for authorization, a new instance of BIOCONNECT-SERVICE needs to be created, and name it as "bioconnect-api-template", which should be the same name as in Django for the permission class.
Add policy
To add, click on the service name "bioconnect-api-template"
The policy detail is.
- admin: can call "get", "post", "patch", "put", "delete"
- editor: can call "get", "post", "patch", "put"
- guest: only can call "get" end point
For detail steps, refer to BioConnect Authorization
Test Authorization
Start the app, and open swagger UI in the browser: http://localhost:8000/swagger
Test Get Sample
Click on "GET" "/sample/" to expand, click on "Try it out" button, and then "Execute" button. Error:
{
"detail": "Authentication credentials were not provided."
}

Add User Info
Click on "Authroize" button
Test Post Sample
Now try "POST", "/sample/" with guest account, error will occur
Check Audit Log
Check the Ranger audit log, "Denied" entry: