Django + JSON web tokens + disabling session-based authorization - django

I am currently working on a Django project that wants to replace and disable Django's traditional cookie-based sessions and replace it with JSON web tokens as a means of user authentication for a user on my website.(User Authentication for the 'login-required' part of the website instead of just REST API's).
How I want JSON web tokens to be used in my web app: The login page will make an API call and receive a JSON web token as a response and the JSON web token will be stored through (local storage, session storage, or cookies). The JSON web token will be passed in the HTTP header in subsequent HTTP requests (after logging in) so that the server knows we are an authorized user.
Some of the libraries that I have looked at is the 'djangorestframework' library. It seems to protect certain URLS concerning a site's API (not what I want). Are there any libraries that can replace the normal 'cookie-based' sessions Django uses with JSON web tokens and have the normal functionality of 'cookie-based' session authorization scheme(Normal meaning 'logging a user in and logging a user out works on the site as well as in the Django's default admin panel') If so, how do I integrate that library with my current web app to achieve normal functionality?
I also want the traditional 'cookie-based' sessions to be disabled. How do I completely disable it so user authentication is done only with JSON web tokens?

Simply use jwt to authentication class.
JSON Web Token Authentication
JSON Web Token is a fairly new standard which can be used for token-based authentication. Unlike the built-in TokenAuthentication scheme, JWT Authentication doesn't need to use a database to validate a token. Blimp maintains the djangorestframework-jwt package which provides a JWT Authentication class as well as a mechanism for clients to obtain a JWT given the username and password
Also set default authentication class to jwt and determine setting in setting.py like :
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
)
}

Related

Access Django Rest API using Azure access token and SimpleJWT access token

Need just hint, tried all possible ways.
Any approach is highly appreciated.
Problem statement: access jwt authenticated django rest api using azure ad access token in postman and local app. django app is hosted on azure app service.
Challenge: pass two token with different header values in authorisation header such that azure token is also reader with django jwt token.
A. All possible authorisation in postman.
B. Different authorization keys and header values in django jwt settings
I've deployed my django application on azure app service.
I'm using JWT authentication for all rest API's.
I've an azure directory and service principal linked to azure web app.
In postman,
I can get access token from azure active directory(using clientID, Secret, resource, etc.) and use the same token to call django rest api.
I can easily access unauthenticated API just by using azure access taken in authorization bearer header.
For JWT authenticated API, I'm not able to use them (crud operation) as none of my approach is working.
Azure access token header value : Bearer
Django JWT token header value: Bearer, Token, JWT.
---- EDIT ----
Django application will server as a backend to client applications. Thus client application have to generate azure token and provide while calling django app API. But django application API's are also authenticted with JWTAuthentication, thus 2 tokens have to provided.
Problem
Both Tokens have to be provided in 'Authorisation' key to use with HTTP_AUTHORISATION.
INFORMATION
JWT packages: simplt_jwt
simplt_jwt,django version: latest
client: react-js webapp, swift ios mobile app
resources: azure app service, azure active directory with service plan
django website is used as a backend for webapp and mobile app.
To elaborate, some images are added:
Need to use this architecture (api endpoint with jwt authentication):
Call an API with JWT authentication header value in (Bearer, Token, JWT), and have to provide Azure access token withheader value as (Bearer).
Both Tokens have to be provided in authorisation header.
[api endpoint with jwt authentication][1]
[1]: https://i.stack.imgur.com/y0Uvf.png
Called an API(wihout django JWT authentication) using only azure access token and was able to get response.
Correct me if I'm using some wrong approach.
Add another custom backend and verify your Azure token by its public key:
https://docs.djangoproject.com/en/4.1/topics/auth/customizing/
And add it next to your SimpleJWT auth backend.
In your settings.py file:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
# add your azure backend here
'your_app.auth_azure_backend.AzureAuthentication',
)
...
}
from django.contrib.auth.backends import BaseBackend
class AzureAuthentication(BaseBackend):
def authenticate(self, request, token=None):
azure_token = request.headers['AzureToken'] # you can use custom headers or just use `Authentication` with Bearer token. Django will go through every backend to verify it.
decoded = jwt.decode(azure_token, public_key, algorithms=["RS256"])
# return user instance based on decoded data from Azure
If you can decode without error that means your token is generated by Azure AD.
You can follow this question to get your public key https://learn.microsoft.com/en-us/answers/questions/793793/azure-ad-validate-access-token
So I found a solution, if wrong please provide feedback.
I have create an authentication class inheriting JWTAuthentication class. And reading custom headers in request.headers. this way I can provide multiple tokens in a request.
Actually, My application is hosted on azure app service. So have to authenticate send also application have some inbuilt authentication to manage user access, thus need token for the same.

How to set up javascript and django applications to exchange jwt tokens

I have a SAP implemented on the Netlify platform. The processing for the app is implemented in a django api running on a hosted server.
Users are authenticated on the Netlify app, but do not need to be authenticated in django.
I now want authorised users to be able to post data to the api and the django server objects with the message
Forbidden (CSRF cookie not set.): /api/save-archive/{...}/
I am looking at implementing JWT cookies and have considered djangorestframework_simplejwt but that seems to require that the user is authenticated in django
My question is, what software elements do I need to be able to generate and consume a token is this scenario?

django_auth_adfs: get JWT token for the client on successful authentication

I have a Django application that doesn't have MVC pages and most of the data is served/posted via restful API powered by django-rest-framework. My userbase is in Azure single tenant AD, so I am trying to get the SSO going for them.
I am using django_auth_adfs to authenticate users against the Azure AD. Most of the stuff seems to work and the module takes care of the redirects and establishing the Django sessions for the client. Specifying the right permission_classes for the API ViewSets will make sure only authenticated users can access it it works fine via browser with proper django session cookie.
What I can't figure out is how to get the JWT token that I can give the UI client so that it could interact with the django-rest-framework API by supplying the JWT bearer and not relying on the session.
The documentation is not very specific on these details (besides the password grant that isn't quite relevant for my scenario).

Can DjangoRestFramework accept JWTs that have more than username/password in payload?

I have a Django application that uses the Django Rest Framework. At first I was just using Session, and Token authentication, but now want to implement JWT Token authentication. I downloaded a package called djangorestframework-jwt that allows you to use JWT for authentication in DRF. The crux of the problem is that my client side application is using Auth0 which can return a lot of different information, first name, last name, userid, etc. We are using Auth0 with gmail as an identity provider to log into our client side EmberJS application. For our data adapters to get data from Django though, we are using 1 consistent token that we configured in our Auth0 account that is tied to a user in Django. What I would like to accomplish is to use the JWT returned from Auth0, instead of this 1 token, to authenticate all our requests to Django. Can you authenticate yourself in Django without using a Django User object?

Secure authentication between ReactJS and Django

Been reading and watching quite a bit, and asking a lot of questions regarding ReactJS and Django.
This particularly helped me to understand the the flow of data from Django REST Framework to ReactJS and from ReactJS to Django REST Framework.
Django Forms and Authentication with Front-end Framework (AngularJS/ReactJS)
However, the one thing I am trying to understand is authentication to the Django REST Framework. I understand from the documentation that it has built in authentication. Since this is sensitive data, I would obviously want it protected people retrieving it just by going to http://www.my_site.com/info/api.
I would need to setup ReactJS to be the only thing that can request data from the API whether that is through a key or username/password credentials. I am just curious how this is handled? Obviously I don't want that hard coded in ReactJS because it will compile with the rest of ReactJS.
Here's how I'd approach it: I'd use a JSON Web Token (JWT) for authentication and authorization.
You'd use your back-end to protect ALL API requests from invalid JWT's except for routes where a user won't have a token (ie, registration/log-in pages).
Here's how the flow of the application will go:
A new user registers to your app with standard credentials such as email and password.
Your back-end will create a new user, sign a new JWT token (usually with the user's ID). You'll probably use a third-party library to sign/verify tokens (I don't have experience in the Django community but I am sure a quick Google search will give you answers). Your back-end will send back this token. This is the only time the back-end will receive email, passwords or any other sensitive information on registration.
From this point on React will only use this token for authorization. React will save this token somewhere (ie, localStorage) and send this token along with the other parts of a request to the API routes you created with your back-end. You'll send this token in the authorization headers in the request.
Your back-end will validate this token using a third-party library. If it's invalid the request stops and an unauthorized error is returned. If it's valid the request continues.
This achieves the following:
Your API routes are protected against unauthenticated users
Each request to your API is verified for authorized users which protects anyone from requesting any part of your API.
You can further solidify this by only allowing requests for users to modify their own data. For example, protect Suzy's profile from being modified by people other than herself by only allowing her token with her ID to modify her account/data.
Important Note- Your backend will never save these tokens in storage. It will verify the token on each request. Read more about JSON Web Tokens (JWT) and how it works.
Django Rest Framework has built-in token authentication and a third party package for JWT Token Auth.
If you the standard token auth would work for you, then it could be pretty simple with drf-redux-auth. If you need JWT for some reason, as suggested by Keith above, you could easily fork the above...