SSO between two web applications where on is embedded in the other in an iframe

Hi everyone,

I’m looking for guidance on securely implementing SSO between two web applications where one app is embedded inside the other via an iframe.

Here’s our scenario:

  • We have a parent web application (App A)

  • A second web application (App B) is embedded within App A using an iframe

  • Currently, we are not using Auth0 — authentication is handled via a credentials grant flow

  • Our goal is that if a user authenticates in App A, they should be able to access App B within the iframe without needing to sign in again

We’re exploring whether Auth0 could help us achieve this, but we’re unsure about the best approach given the iframe setup.

Some of the concerns and questions we have:

  • How to securely propagate authentication from App A to App B

  • Whether SSO is feasible in an iframe context, especially with modern browser restrictions (e.g., third-party cookies)

  • If moving to Auth0, what would be the recommended flow or architecture for this use case

  • What patterns to avoid to ensure we don’t expose tokens or introduce security risks

Has anyone implemented something similar or can share best practices for this kind of setup? Any pointers, examples, or documentation would be really helpful.

Thanks in advance!

Hi @rdechiara,

Welcome to the Auth0 Community!

Please allow me some time to further investigate this and I will come back with an answer as soon as possible!

Thank you!
Best regards,
Remus

Hi @rdechiara,

Welcome to the Auth0 Community!

In Auth0 you can implement your desired use case and solve this type challenge securely and efficiently as well.

It is not recommended to propagate authentication. The secure and correct pattern is for App B to independently and silently acquire its own token from Auth0 . It does this by leveraging the central SSO session that was created when the user logged into App A. This is achieved through a mechanism called Silent Authentication , which is a standard part of the OIDC protocol that Auth0 supports.

Yes, it is entirely feasible , but you must address the primary browser restriction: the blocking of third-party cookies. When App B (e.g., app-b.com ) is in an iframe, its request to Auth0’s domain (e.g., your-tenant.auth0.com ) is considered a “third-party” context. The SSO session cookie set by Auth0 will be treated as a third-party cookie and blocked by the browser, causing silent authentication to fail.

The official and robust solution is to use Auth0’s Custom Domains feature. By setting up a custom domain (e.g., login.your-company.com ), you make the Auth0 authentication endpoint appear to be on the same primary domain as your applications. This transforms the SSO cookie into a “first-party” cookie, which browsers do not block.

Here is the recommended, high-level architecture for your scenario:

  1. Registration: Register both App A and App B as separate applications within your Auth0 dashboard.

  2. User Authentication: The user navigates to App A and is redirected to the Auth0 Universal Login page to sign in. Upon successful authentication, Auth0 sets a secure, encrypted SSO session cookie on your custom domain and redirects the user back to App A with their tokens.

  3. Silent Authentication (App B): When the user accesses the page in App A containing the iframe, the embedded App B loads. App B’s code then uses an Auth0 SDK (e.g., the Auth0 SPA JS SDK ) to call a method like getTokenSilently() .

  4. The Hidden iFrame: The SDK handles the complexity for you. It briefly creates a hidden, non-interactive iframe that points to Auth0’s /authorize endpoint with the prompt=none parameter.

  5. Seamless SSO: Auth0 checks for the first-party SSO cookie, finds the active session, and issues a new set of tokens specifically for App B without any user interaction. The SDK delivers these tokens to your App B code.

  6. Logout: The iframed app should nicely handle logout, by frequently (e.g. upon page reload) checking whether the session is still active and if not clear the local storage

To prevent security risks, you must avoid the following anti-patterns:

  • Auth0 discourages using the Auth0 (or any identity provider) login pages inside an iframe due to inherent security risks with the approach, so don’t have the iframe handle the initial login, the parent should always orchestrate the primary login.

  • You should not send tokens from App A to App B via URL parameters or any other client-side mechanism. The application should get its token directly from Auth0.

  • While you can rely on silent authentication, you need to account for the possible failures (i.e., when Auth0 can’t find a valid session for the user and needs to prompt for authentication) and be prepared to do a regular authentication on app A

Hi, thanks for the detailed explanation — this is really helpful.

I just want to clarify a couple of assumptions to make sure I’m understanding your proposed approach correctly:

  • Does your solution imply that both App A and App B need to be migrated to Auth0 and act as separate clients there?

  • Are you assuming that both applications live under the same parent domain (e.g. a.company.com and b.company.com) so that the custom domain (e.g. login.company.com) is considered same-site?

In our current setup, the two applications are hosted on completely different domains (e.g. xyz.com and abc.com), which is why I want to double-check whether the silent authentication approach you described would still work in this scenario, especially given third-party cookie restrictions in iframes.

Would you recommend a different approach for this case?

Thanks again!

Hi @rdechiara,

We’ll gladly break this down as well to clarify everything.

Yes, that is correct. The recommended and most secure approach is to register both App A and App B as separate “Applications” within your Auth0 tenant. This helps a lot when it comes to token issuance and achieving seamless SSO for your iframed application, otherwise the process would be more difficult and the complexity of achieving this would be much higher.

Yes, this architecture is designed to work even when your applications are on completely different domains (e.g., xyz.com and abc.com ). By using a Custom Domain, you ensure that the authentication process and the SSO session cookie both belong to the same trusted domain (login.company.com ), which the browser recognizes as a secure, first-party context.

The silent authentication flow succeeds because the Auth0 SDK initiates it from within a hidden iframe that points directly to your Custom Domain. This means the critical check for the user’s login session happens entirely on login.company.com , where it has first-party access to the SSO cookie. Because this process is self-contained within your Custom Domain, the original domains of App A and App B become irrelevant to the security check. This is how Auth0 securely bypasses the cross-domain problem and makes the seamless SSO experience possible, regardless of where your applications are hosted.

Thank you and if you have other questions please let me know!
Best regards,
Remus

I’ve started working on a proof of concept for Application B and have successfully integrated Auth0 into the SPA frontend. The authentication flow works as expected: after signing in, the user is redirected to the dashboard.

At this point, API calls are returning 401 responses, which makes sense because the authorization server is now Auth0 rather than our previous backend.

I’m now focusing on the Django REST backend. From what I understand, I need to configure the API to validate the JWTs issued by Auth0 (using JWKs), so that incoming requests can be properly authenticated and the endpoints protected.

I’m currently following this guide: https://auth0.com/docs/quickstart/backend/django/interactive. However, I’ve run into a couple of issues:

  • In step 2, the list of dependencies appears to be missing or blank.

  • I’m also unsure whether registering just the SPA as an application in Auth0 is sufficient, or if I also need to explicitly register my API (i.e., define it as an API resource with an identifier/audience) in order to properly validate tokens on the backend.

Could you please clarify these points?

Hi @rdechiara,

I understand you’re working on integrating Auth0 with your Django REST backend. We are more than glad to assist, so allow me to clear these points as well.

My apologies for the fact that you weren’t able to locate the information needed using directly from our quickstart’s documentation, but you can can find the correct list of dependencies in our updated Django API tutorial - Django API: Authorization.

Here are the dependencies you’ll need to add to your requirements.txt file:

cryptography~=2.8
django~=2.2.7
djangorestframework~=3.10.31
django-cors-headers~=3.1.1
drf-jwt~=1.13.3
pyjwt~=1.7.1
requests~=2.22.0

Regarding your second question, you are correct, so you do need to explicitly register your API in Auth0 for a couple of reasons:

  • Registering your API defines it as a resource server with a unique identifier (the “audience”). When your SPA requests an access token, it will specify this audience.

  • Your Django backend will then validate the JWT access token it receives. A critical part of this validation is checking that the aud (audience) claim in the token matches the identifier of your API. This ensures that the token was intended for your API and not for some other resource.

The Django API: Authorization documentation walks you through this entire process, from creating the API in the Auth0 dashboard to validating the tokens in your Django application.

I hope this clears things up and please let me know if you have any other questions.
Kind regards,
Remus