## https://sploitus.com/exploit?id=EF265F74-C4A5-5AEB-B284-BDDD596A2412
# OIDC SSO Proof of Concept
Proof of concept for bidirectional SSO between a .NET app (Auth0) and a Python FastAPI app (Keycloak) using OIDC Authorization Code flow.
See [spec.md](./spec.md) for detailed requirements UI flows.
## Architecture Overview
```mermaid
graph TB
Auth0[Auth0]
Keycloak[Keycloak Docker
localhost:8080]
AppA[App A
ASP.NET Core 8
localhost:5001]
AppB[App B
FastAPI
localhost:8000]
AppA -->|OIDC| Auth0
AppB -->|OIDC| Keycloak
Auth0 |Brokered OIDC| Keycloak
AppA |SSO Nav| AppB
```
## Setup Guide
### 1) Prerequisites
- Docker Desktop or Docker Engine with `docker compose`
- An Auth0 free tenant (sign up at https://auth0.com/)
- A tunnel for Keycloak (ngrok, Cloudflare Tunnel, or localhost.run)
- Auth0 CLI (`auth0`) logged in
- Python 3.12+
### 2) Auth0: Tenant and Organization
1. Create a free Auth0 tenant.
2. Create an Organization (or use an existing one).
3. Record the Organization ID as `AUTH0_ORGANIZATION_ID` in `.env`.
4. In the Organization's Connections tab, enable the default database connection.
### 3) Auth0: App A (OIDC client)
1. Applications -> Create Application -> Regular Web Applications.
2. Name: `OIDC SSO POC - App A`.
3. Configure settings:
- Allowed Callback URLs: `https://localhost:5001/callback`
- Allowed Logout URLs: `https://localhost:5001`
- Allowed Web Origins: `https://localhost:5001`
4. **Important**: In "Login Experience" select "Business users" under "Types of users". This enables the Organization feature for multi-tenanting.
5. Enable this application in the Organization's Connections.
6. Record the Domain, Client ID, and Client Secret.
7. Record the Application ID as `AUTH0_APP_A_ID` in `.env`.
### 4) Keycloak public URL (required for Auth0)
Auth0 must reach Keycloak over the public internet for the B->A flow.
1. Start a tunnel to port 8080.
2. Copy the public URL (for example `https://abc123.ngrok-free.app`).
3. You will use this URL in Auth0 and in `KEYCLOAK_DOMAIN`.
### 5) Auth0: Keycloak broker application
1. Applications -> Create Application -> Regular Web Applications.
2. Name: `OIDC SSO POC - Keycloak Broker`.
3. Configure settings using the public Keycloak URL:
- Allowed Callback URLs: `https:///realms/sso-poc/broker/auth0/endpoint`
- Allowed Web Origins: `https://`
4. Save and record:
- Client ID as `AUTH0_BROKER_CLIENT_ID`
- Client Secret as `AUTH0_BROKER_CLIENT_SECRET`
- Application ID as `AUTH0_KEYCLOAK_BROKER_APP_ID`
5. In "Login Experience" select "Business users" under "Types of users"
### 6) Auth0: Create a test user
1. User Management -> Users -> Create User.
2. Email: `loris@fundapps.co` (must match the mock user store).
3. Set a password and mark email as verified.
### 7) Auth0: Enterprise connection (Keycloak)
1. Authentication -> Enterprise -> OpenID Connect.
2. Create a connection:
- Name: `keycloak-sso` (matches `AUTH0_KEYCLOAK_CONNECTION_NAME`)
- Issuer URL: `https:///realms/sso-poc/.well-known/openid-configuration`
- Client ID: `auth0-broker`
- Client Secret: copy from the Keycloak realm export for `auth0-broker`.
3. Enable this connection for the `OIDC SSO POC - App A` application.
4. In the Organization's Connections tab, enable this enterprise connection.
### 8) Local configuration
1. Copy `.env.example` to `.env`.
2. Fill in Auth0 values:
- `AUTH0_DOMAIN`, `AUTH0_CLIENT_ID`, `AUTH0_CLIENT_SECRET`
- `AUTH0_BROKER_CLIENT_ID`, `AUTH0_BROKER_CLIENT_SECRET`
- `AUTH0_ORGANIZATION_ID`
- `AUTH0_KEYCLOAK_CONNECTION_NAME=keycloak-sso`
- `AUTH0_KEYCLOAK_BROKER_APP_ID` (Auth0 app ID for the Keycloak Broker app)
- `AUTH0_APP_A_ID` (Auth0 app ID for the App A application)
3. Set `KEYCLOAK_CLIENT_SECRET` to a random string.
4. Set `KEYCLOAK_DOMAIN` to your public Keycloak URL.
### 9) Automated tunnel + Auth0 update
The helper script starts a localhost.run tunnel, updates `KEYCLOAK_DOMAIN` in `.env`,
updates the Auth0 App A application, the Auth0 broker app, and the enterprise connection,
then starts containers.
```bash
python3 ./start_poc.py
```
For safety, use dry-run to capture the URL and update `.env` only:
```bash
python3 ./start_poc.py --dry-run
```
### 10) Test flows
1. Visit `https://localhost:5001` (accept the cert warning).
2. Log in with `loris@fundapps.co`.
3. Click "Go to Python App" and confirm no login prompt.
4. Visit `http://localhost:8000` directly and log in with Keycloak user `loris`.
5. Click "Go to .NET App" and confirm no login prompt.
## Simplifying Local User Setup
Current setup requires:
- Auth0 user `loris@fundapps.co`
- Keycloak user `loris`
- Both apps have a fixed mock user store
If this is too cumbersome, a simpler option is to make both apps accept any user
that has a verified email claim, and display a warning banner when the email is
not in the mock store. This removes the need to pre-create matching local users
for basic demo flows while still showing how authorization data could be enforced.
## Notes
- This is a proof of concept and not production-ready.
- Auth0 cannot reach `localhost`, so B->A flow requires a public Keycloak URL.
- App A uses a self-signed HTTPS certificate.