The Do(s) and Don't(s) of implementing SSO using Authentik

The Do(s) and Don't(s) of implementing SSO using Authentik

SSO

SSO enables a user to sign in once and gain access to multiple applications without needing to sign in separately for each one. It consists of two main parts: Single Sign-In (SSi) and Single Sign-Out (SSo).?

Primary Use Cases:

  • Centralized user authentication and identity management
  • Allow multiple applications to use the same session which allow you to login/logout of all application if one on them login/logout(i.e. It helps syncing the session across multiple applications).

SSO primarily works using cookies, but managing these cookies is typically handled by available libraries and frameworks. For our SSO article, we will keep things simple, focusing on high-level architecture and using easy-to-understand terminology to make the concepts more accessible.

IDP

So to achieve SSO you need an IDP (i.e. Identity provider). IDP from its name explains its purpose, in this whole process it is the one who will hold the user database and credentials and will be responsible for accessing the token and identity that will authorize your secure resources. While the Applications for which we need SSO are called Service Provider(SP) also known as Client.

IDPs are available in two forms:

  1. Self-Deployable: Open-source solutions that you can set up on your local machine using Docker. Each IdP provides documentation for deploying their source code locally.
  2. Cloud-Hosted: Managed services where you simply create an account and use the IdP without needing to handle the infrastructure.

In simple terms, your application will delegate the authentication, authorization, and user management processes (login, logout, registration) to the IdP. The IdP handles these tasks and returns the necessary user information and tokens to your application upon successful authentication.

SAML vs Oauth/OpenId

SAML and OAuth/OpenID Connect are two important protocols that facilitate communication between your applications and the IdP server to exchange identities and tokens. Similar to how the HTTP protocol handles web browser requests and responses, SAML and OAuth/OpenID Connect enable communication with an Identity Provider (IDP) server for identity and token exchange.

SAML (Security Assertion Markup Language) is an older protocol designed for requesting and processing authentication and authorization from an IdP. It uses XML-based messages for these exchanges.

OAuth/OpenID Connect (OIDC) is a modern framework for communicating with an IdP that does the same SAML job for you.? OAuth is primarily an authorization framework, while OpenID Connect is an authentication layer built on top of OAuth 2.0. OIDC uses JSON Web Tokens (JWT) and provides functions for sign-in, sign-out, and retrieving user information. Almost every library and framework today offers OpenID Connect (OIDC) packages to handle these tasks and manage the underlying complexities for you.

Why are OAuth and OpenID Connect used together? OAuth is primarily an authorization framework, OpenID Connect is an authentication layer built on top of OAuth 2.0. OpenID Connect allows clients to verify the identity of the end-user based on the authentication performed by an Authorization Server and to obtain basic profile information about the end-user. We will discuss it in detail below in the token structure section.

Types of SSO

Machine-to-Machine (M2M): This type involves backend or headless services, typically using open-source APIs. No frontend or user involvement takes place. The backend service generates the authentication and authorization requests and handles the flow. This is used when two services (e.g., IdP and SP) directly communicate with each other.

Single Page Application (SPA): A frontend application that needs to be authenticated to access protected route and authorization to access the backend secure resources depend upon the claim and roles of authenticated user. Authentication is typically handled using OAuth 2.0 and OpenID Connect and authorization depends on the claims and roles associated with the authenticated use

Basic Terminologies

Following are the term which are relative to the IdP

  • Client : Your applications (aka SP service provider)
  • redirectUrl/callback : A url where Idp will redirect to after authentication
  • Tenate : Like a container consisting of applications that will need sso and share the user database and setting. Each tenant has its own user base and settings, and SSO works only for applications within the same tenant.
  • Well-knows : every tenant has its own well-knowns link where it will list all the public/ private key that used token signature that will be crucial for token validation
  • Front-channel : Communication involves the user's browser and redirects, often visible to the user, such as during an OAuth authorization code flow.
  • Back-channel : Communication happens directly between servers, not visible to the user, such as token exchanges or API calls.

Basic Flow Idea

  • Register Applications: Register all the applications in the IdP tenant that will share the SSO.
  • Extract Credentials: Obtain the secret and ID of each application, as well as the issuer and audience details.
  • Install OIDC Package: Install the OIDC package in your frontend application and provide the necessary configuration, including the secret and other extracted details.
  • Redirect for Authentication: Use the OIDC function to redirect the application to the login page.
  • Handle Callback: After successful authentication, the user will be redirected to the specified URL with two parameters: code and state.?
  • Exchange Code for Tokens: On the callback page, exchange the authorization code with the IdP server for the ID and access tokens using the OIDC function (callback function). Store the tokens locally, clear the query parameters from the browser, and redirect to the appropriate page.
  • Session Management: OIDC manages cookies and states for you. If you try to log in from another application (that is registered in the same tenant ), it will authenticate you automatically based on the existing session in the browser, achieving SSO.
  • Secure the Backend: To secure backend resources, use an interceptor or middle-ware to validate the token, extract claims, and control access.

  • For visually Summarise the whole Concept :

standard Oauth flow

Explanation with Example

To understand the basic flow of SSO in detail, we'll consider an Identity Provider (IdP). There are multiple IdPs available, such as Keycloak, Cloud Identity, Identity Server, Okta, Auth0, and Authentik.?

For this example, we will use Authentik because it is open-source and self-deployable.?

Installation and Configuration

  1. Setup Docker: Ensure Docker is installed on your machine. Follow this YouTube tutorial for setup instructions.
  2. Install Authentik: Follow the installation guide using Docker Compose from the Authentik documentation.
  3. Create Admin Account: Create your first account as an admin and start using Authentik.

Register Applications

Register

Go to the Applications section in Authentik and register two applications that will share SSO. Assume you have two applications running on your local host (e.g., https://localhost:3000 and https://localhost:3001). It will look like this

Authentik server Application registration Section

Create Application Configuration

  • Click on “Create with wizard” to set up the application configuration and its provider settings in a single flow. Alternatively, you can specify the provider separately for each registered application.
  • Select OpenID/OAuth as the provider, as this is how your application will communicate with the IdP.

Specify Redirect URL

  • Carefully specify the redirect URL, which is where the IdP will redirect you after login. An incorrect URL will result in a Cross-Origin error.
  • Fill out the form, select OpenID/OAuth as the provider, and fill out the provider form. Always select the implicit default flow for authentication and authorization, then set your redirect URIs.
  • Copy Client ID and Secret: Note your client ID and secret, as these will be used in your application.

Verify Configuration

Your application and provider will be created. Click on the provider to see all relevant links, such as the issuer, well-known, and token endpoints.

Like below

Application Credential and endpoint


FrontEnd Side - OIDC implementation

You can get a basic application from the following repository: GitHub - ali-whizz/sso-front-application.

Note: Make a copy of this repository and run two applications on two different ports. Follow the README file in git repo for detailed configuration instructions.

Install OIDC Package

Install any OIDC popular package like react-oidc-context or ?oidc-client

Provide Settings and Configuration

  • Paste the extracted information from application registration i.e. clientId, secrete and issuer.?
  • Make this a higher-order component to ensure authentication is applied across the entire application.

Redirect to Login Page

  • Same as described above in the Basic Flow section, Use the OIDC object to redirect users to the login page using auth.signinRedirect().?
  • Follow the steps described in the Basic Flow section to handle the authentication flow and you can achieve SSO across all your applications

Token Structure

As we discussed earlier using the OpenId layer over the Oauth, we can achieve authentication with authorization so for this purpose the IdP issues 3 types of token which is access_token, refresh_token and Id_token. Don’t misunderstood them :

  1. access_token is the one that will be exchanged and validates to access secure resources.?
  2. Refres_token is a long life token used to obtain the new access_token when the current one expires. Users don't need to authenticate again, it is just the refresh_token that is passed to get new access_token and refresh_token, ensuring a smooth flow.
  3. Id_token Holds the identity information of the currently logged-in user. This is where OpenID Connect (OIDC) enhances the OAuth framework by providing authentication capabilities.

Acess_token structure

  • Header : “Kid” in the header is the Public Key Id, which is used for signing this token, and is available in the well-known list that we discussed above. So this will be useful for validating a token or decode it.
  • Payload : Contains the scope and claims necessary to protect your backend secure resources.

JWT token structure in openId/oauth

Some Useful work around To achieve SSO Seamlessly

As we discussed above, when a user login in an App and then if he presses the login button in another app he doesn't have to go through the authentication process again. Right ? Isn't it very silly ? instead it should automatically detect the login in other apps and show the user as logged in all other apps. Yes this is the Expected behavior and this is how it should be implemented? but you need some work around for this purpose.?

Avoid Using Cookies: Do not rely on cookies to detect login or active sessions across different applications, as this is not recommended at all.

Let's Discussed it casually,?

  • Silent Login : OIDC provides the functionality of silent login which neither affects your current view nor requires any client interaction. It just keeps checking to IdP server if there is any active session for this browser and if found it will return with the tokens and other information. It runs in an iframe and users don't even notice when the application communicates to IdP and then displays the Logged In view, making for a seamless user experience. Happy User :)?

  • Silent Logout and Session Status : Let's think of a scenario where a user logged out of one app, what do you expect from the other ? also logged out of them which is single sign out. Right ? But how could the other know that the session is not valid anymore without interacting with the IdP? So for this purpose you must keep checking the Active Session Status So when the session is not available anymore you should immediately silently Sign Out. That will remove cookies and other authentication from this tab and show the user unauthenticated Seamlessly. The function in react-oidc-context is auth.querySessionStatus().

This Is What SSO Is All About :)

I have tried to cover every hurdle I faced while understanding and implementing SSO. I hope this guide will be helpful for you. Feel free to reach out if you have any questions. Best of luck on your SSO journey!

Talha Hammad

AWS | GCP | CICD | Docker | K8's | Terra form | Cloud Security Engineer

4 个月

Very insightful information.

Awais Zafar

Software Engineer @Whizzbridge (ROR, .NET, React)

4 个月

Very informative, good job.

Shahzada Fahad Ashraf

Principal Software Consultant / Software Solutions Architect

4 个月

This is extremely extensive, detailed and well-structured. Kudos on this contribution! ????????????

要查看或添加评论,请登录

社区洞察

其他会员也浏览了