Enabling SSO for your React and Django app with SAML 2.0

CogitoEngineering
cogito-engineering
Published in
4 min readNov 24, 2020

--

This guide walks you through integrating SAML 2.0 authentication with a Django API server and React Single-Page Application (SPA). Authentication is set up so that the front-end React application obtains a JSON Web Token (JWT) from the Django API server once the API server has successfully authenticated with the Single Sign-on Provider — in this article we use Okta.

Our annotation tool at Cogito

At Cogito, we use a similar setup to authenticate users for our annotation tool (see screenshot). With this, we are able to deliver securely labeled data to power our machine learning models.

Screenshot of the Cogito Annotation Tool

Here is the step by step workflow of the implementation:

1. Log in and visit your identity provider app home (i.e. Okta)
2. Click your app
3. Identity provider redirects to the Django backend server
4. Backend server completes authentication and generates a JWT token
5. Redirect to the frontend server with the JWT token as a URL parameter
6. Frontend stores JWT token and can now make authenticated API requests
7. Frontend can refresh token until configured refresh period expires

Start here to configure SAML2.0 authentication with a backend Django API server and a React application:

  • Install requirements
  • Setup JWT token Authentication
  • Download your SAML2.0 metadata XML file
  • Store JWT token in React

Installing requirements

For this blog post we use the following technologies:

We assume you are familiar with Django and have an application ready. Let’s start by adding the django-saml2-auth package.

Now that you’ve installed django-saml2-auth, let’s configure the authentication views and their settings.

Add the following to your root “urls.py” file. Note: This rewrites the user login + admin login URL patterns:

Next, add the “django-saml2-auth” app to your “INSTALLED_APPS”:

Then, you need to add the “SAML2_AUTH” variable to your “settings.py” file. This is a map containing all the required and optional configurations for “django_saml2_auth”. Below is a bare minimum example for a React SPA and Django API server with separate host names:

Make sure the path in the “ENTITY_ID” URL lines up with your views’s URLs. For example, if you changed the “/sso” URL to “/saml2_auth” in your “urls.py” the “ENTITY_ID” should be “https://BACKEND.example.com.com/saml2_auth/acs/”.

There are several other optional settings that “django_saml2_auth” provides. For example, you can define attributes in your SSO provider and sync them with Django or trigger hooks that run before/after login. Checkout their docs to learn more about these options. That’s all you need. Next we configure your SSO provider.

Install Django Rest Framework

Django Rest Framework is a useful, well documented API development framework. With DRF you are able to rapidly develop APIs by abstracting away the boilerplate glue that Django doesn’t provide.

DRF’s documentation is excellent. To install DRF to your Django application follow the instructions here.

Set up JWT Auth with Django

Next, we set up your Django app to allow JWT based authentication. You may want to write your own JWT authentication class, just be sure to add this to “DEFAULT_AUTHENTICATION_CLASSES” in your “settings.py” file. For this guide we use the drf-jwt plugin. Read the instructions here or continue following below:

Install drf-jwt:

Add this to your urls.py:

Note: You do not need to use the “obtain_jwt_token” view, because a JWT token is automatically generated by the “django_saml2_auth” application each time a user is authenticated.

Finally, add this to your “settings.py”:

You can checkout additional configurations on the drf-jwt docs page.

Download your SAML2.0 metadata XML file

Assuming you have an Okta application set up already, you’ll need to export the IDP metadata XML file and keep it in your app repo. Here are instructions from Okta on how to do this.

Once you have that file, store it inside your Django app settings directory. Then update the “METADATA_LOCAL_FILE_PATH” with the relative path. This setting is inside the “SAML2_AUTH” dictionary of your “settings.py” file.

Use JWT token for API requests in React

Once you are here, you can now login to your backend server with SSO. Simply login with the default Django login URL: “/accounts/login”. You will be redirected to your identity provider. Once authenticated, you’ll then be redirected to your React application (see “FRONTEND_URL” setting) with a JWT token in the URL.

The final step is to create a React component that retrieves the token from the URL and stores it somewhere. In this guide, we keep the JWT token in local storage. Depending on your application requirements, you might want to store the token in context or session storage.

Note: This example uses the “query-string” and “react-router” libraries to get and parse URL parameters. Check out react-router here.

Add this component to the landing page where “FRONTEND_URL” sends you:

That’s it! You can now authenticate your React application’s API requests with the JWT token.

Opportunities at Cogito

If you are based in the US, Ireland or India and are interested in opportunities at Cogito, please check out our careers page! We have an office optional policy that encourages remote work and collaboration!

Acknowledgements

This article was written by Jacob Duyon and was based on collaboration between Jacob and Mauri Niininen. Thanks to Richard Brutti for providing detailed proofreading and feedback.

--

--