Navigating SAML: Implementing Stateless Authentication with Django and JWT

Varun Sharma
2 min readJul 1, 2023

I felt the urge to share my experience, a journey I initially started without a clearly laid roadmap. The path became visible only after sifting through countless forums, articles, and technical documents. That’s when I decided to look for my own trail and find a solution (Always wanted to write these lines 😁)

SAML, a well-established protocol for single sign-on (SSO), has been a reliable tool for us over the years. However, it was born in an era where web applications were heavily reliant on session-based authentication. Fast forward to the present, when the majority of apps have migrated from session-based to stateless authentication, and yet, SAML remains a critical component in the enterprise environment. The reason lies primarily in the continued reliance of organizations on legacy systems, recognized for their proven stability and reliability.

How does SAML work?
The SAML protocol sets the ball rolling with a request to an Identity Provider (IDP). The IDP’s responsibility is to confirm if the app initiating the request is both registered and configured correctly. Subsequently, user credentials for the IDP are solicited. Once the login is successful, the user is seamlessly redirected back to the original app, armed now with the access required.

SAML Flow

To the end-users, this is virtually indistinguishable from other authentication protocols like OpenID Connect. The user journey appears the same, but there’s a world of difference behind the scenes. For instance, OpenID Connect employs OAuth for stateless authentication and relies on JWTs for everything.

In the case of the app I developed, stateless authentication was the method of choice, leveraging JSON Web Tokens (JWTs). Consequently, the backend server’s understanding of request origins was wholly contingent on these JWTs.

My first significant hurdle was integrating the SAML protocol into Django’s REST framework. There’s no shortage of third-party Django apps that offer seamless integration, but they were ill-suited for my scenario. My app was built on the Django REST framework, which, unfortunately, ruled out the possibility of using these third-party solutions.

My workaround was to cobble together the necessary pieces for the implementation, relying on minimal changes and core libraries. I’ve shared a detailed, step-by-step process in a follow-up article.

Once implemented and I started receiving responses from the IDP, I found myself facing another challenge.

During the SAML process I outlined above, all actions transpire via POST requests. This works like a charm for traditional, session-based applications, as sessions are managed on the backend. However, my setup had JWTs managed by the front end. As a result, notifying the front end of successful user authentication upon receiving the IDP response was the next mountain to climb.

After tackling both challenges, looking back at the code was a truly satisfying experience.

--

--

Varun Sharma

Fall in love with building products, now learning to make them successful.