This is my journey learning how to implement Single Sign-On (SSO) between Microsoft 365 and Oracle APEX applications. I'm documenting my process, findings, and the concepts I discover along the way.
Esta pagina es para documentar el proceso de implementar Single Sign-On (SSO) entre Microsoft 365 y una aplicacion en Oracle APEX. Se compartiran las cosas que se encuentran y conceptos que se descubren mientras aprendo.
What is Single Sign-On (SSO)?
Single Sign-On allows users to authenticate once with their MS365 credentials and access multiple applications without re-entering passwords. Think of it as a master key that opens multiple doors.
The Key Players
Identity Provider (IdP): Microsoft Azure AD
Azure Active Directory (part of MS365) acts as the Identity Provider. It's the trusted source that verifies who the user is and what they're allowed to access.
Azure Active Directory (parte de MS365) actua como el Proveedor de Identidad. Es la "identidad" que trabaja como la fuente de confianza que verifica y valida quien es el usuario y lo que esta permitido accesar / acceder.
Service Provider (SP): Oracle APEX
Your Oracle APEX application becomes the Service Provider - it trusts Azure AD to handle authentication and accepts the identity information it provides.
La aplicacion de Oracle APEX es quien se convierte en el Proveedor de Servicio - quien confia en Azure AD para el manejo de la autenticacion y es quien acepta la informacion de identidad que se le provee.
The Communication Protocol
They communicate using standard protocols:
Estos ultimos dos componentes ("Key Players") se comunican a traves de protocolos estandares, como:
- SAML 2.0 - Security Assertion Markup Language
- OpenID Connect/OAuth 2.0 - Modern web authentication
Requirements & Prerequisites
What You Need:
- Azure AD Premium (for advanced SSO features)
- Oracle APEX 20.1+ (built-in SAML/OAuth support)
- Domain verification in Azure AD
- SSL certificates for secure communication
- Admin access to both Azure AD and APEX workspace
Approach
1. Clarify environment / Aclarar ambiente
- APEX version: Oracle APEX 24.2.10
- Where is ORDS running (Autonomous DB, on-prem, OCI, etc.)?
- Autonomous DB
- adb in APEX URL --> Autonomous DataBase
- us-ashburn-1 --> OCI region
- oraclecloudapps.com --> Oracle's cloud application domain
- /ords/... --> built-in ORDS endpoint that comes with ADB
- ORDS lives inside the ADB instance.
- APEX + ORDS are both tied to the Autonomous DB instance.
- For REST modules, wallets, ACLs, etc., we are working in the Autonomous DB + ORDS managed stack, not a custom ORDS deployment.
2. Choose protocol / Escoger protocolo
- OIDC (cleaner with modern Entra + web apps).
- In Azure, create normal Entra ID App Registration
- From APEX, calling the OAuth2 v2 / OIDC endpoints with scope openid
-
In APEX, create an Authentication Scheme of type Social Sign-In / OpenID Connect
and point it to those Azure endpoints.
- App Builder --> Shared Components --> Authentication Schemes [Create]
- Authentication Schemes [Create]
- Scheme Type: Social Sign-In
- ...
3. Work with Azure admin / Trabajar con el admin de Azure
- Get app registration set up in Entra ID (Azure AD).
- Configure callback URL (redirect URI).
- Obtain client ID, client secret, and tenant/issuer URL.
4. Configure APEX authentication scheme / Configurar el esquema de autenticación en APEX
- Set up Social Sign-In / OIDC in the APEX authentication scheme.
- Test the roundtrip: redirect to Microsoft, log in, return to APEX, and confirm
APP_USERis set.
5. Add authorization logic / Añadir lógica de autorización
- Decide how you’ll store app-specific roles (tables, APEX authorization schemes, etc.).
- Map roles to Entra groups / claims or to a local table.
How the Authentication Flow Works
Here's what happens when a user tries to log in:
Esto es lo que sucede cuando un usuario intenta hacer log in:
Paso 1: El usuario intenta accessar la aplicacion de APEX
Paso 2: APEX redirecciona al usuario a la pagina de login de Azure AD
Paso 3: El usuario entra los credenciales de MS365 (los mismos que en Outlook)
Paso 4: Azure AD valida los credenciales y envia un token de seguridad a APEX
Paso 5: APEX valida el token y permite acceso a la aplicacion
My Learning Journey
I'm currently exploring:
Lo que estoy actualmente explorando:
- Setting up Azure AD application registration
- Configurando el registro de una aplicacion de Azure AD
- Configuring APEX authentication schemes
- Configurando esquemas de autenticacion de APEX
- Understanding SAML assertions and claims
- Comprendiendo las "aserciones" y los claims (declaraciones) de SAML
- Testing the complete authentication flow
- Probando el flujo completo de autenticacion
- Troubleshooting common integration issues
- Haciendo troubleshooting en problemas comunes de integracion
Key Concepts I'm Learning / Conceptos Claves
Claims & Attributes / Declaraciones & Atributos
Azure AD sends user information (claims) like email, name, and group memberships to APEX. These can be used for authorization and personalization.
Azure AD le envia informacion del usuario ("claims" o declaraciones) como el email, nombre, y membresias de grupo a APEX. Esta informacion puede ser utilizada para autorizaciones y personalizacion.
Trust Relationship / Relacion de Confianza
Both systems need to trust each other through certificate exchange and configuration. It's like exchanging business cards with security credentials.
Ambos sistemas (MS365 y Oracle APEX) necesitan tener confianza entre si por medio de un intercambio de certificados y configuraciones. Es parecido a cuando se intercambian tarjetas de negocio con credenciales de seguridad.
Session Management / Manejo de Sesiones
Once authenticated, APEX manages the user session while respecting the SSO token lifecycle from Azure AD.
Luego de que sucede la autenticacion, APEX maneja la sesion del usuario mientras toma en consideracion (respetando) el ciclo de vida del token de SSO de Azure AD.
Next Steps in My Learning / Proximos Pasos
I'll be documenting my hands-on experience with:
Se documentara la experiencia hands-on con lo siguiente:
- Azure AD app registration process
- El proceso del registro de la aplicacion de Azure AD
- APEX authentication scheme configuration
- La configuracion del esquema de autenticacion de APEX
- Testing and troubleshooting
- Las pruebas y troubleshooting
- Security best practices
- Las mejores practicas de seguridad
- User experience optimization
- Optimizaciones de las experiencias de usuario
This is a living document that I'll update as I progress through my SSO implementation journey. Stay tuned for more detailed technical steps and real-world insights!
Este documento estara continuamente siendo actualizado mientras se progresa en el proceso de la implementacion de SSO.
Next Steps
Step 1 – Create the App Registration in Azure
2.1 Basic info
- Name: APEX-SSO or APEX-YourAppName-M365.
-
Supported account types (keep it simple for now):
- Leave “Accounts in this organizational directory only (Single tenant)” selected
(good for internal corporate app tied to this tenant).
- Leave “Accounts in this organizational directory only (Single tenant)” selected
2.2 Redirect URI (optional at this screen)
We’ll eventually use:
https://<your-apex-host>/ords/apex_authentication.callback
On Autonomous DB, that host will look like:
But APEX will tell you the exact value later, so you have two options:
- Option A (safe): leave Redirect URI blank for now, click Register, and add it after we create the APEX auth scheme.
- Option B (if you already know your ORDS URL): you can put it now.
For now, easiest: leave it empty → click Register.
Step 2 – Grab the important Azure values
After you click Register, you land on the app's Overview page.
Write down:
- Application (client) ID
- Directory (tenant) ID
Then:
- Go to Certificates & secrets → Client secrets
- Click New client secret
- Description: APEX-SSO-secret
- Expiry: 6/12/24 months – up to your security policy.
- Copy the secret value now and save it somewhere safe (once you leave the page you can't see it again).
We'll use:
- Tenant ID
- Client ID
- Client Secret
in the APEX authentication scheme.
Step 3 – Configure APEX Authentication Scheme (OIDC / Social Sign-In)
In APEX 24.2.10:
- Log into APEX Builder.
- Open your application.
- Go to Shared Components → Security → Authentication Schemes.
- Click Create.
- Choose:
- Create Scheme → From scratch
- Scheme Type: Social Sign-In (or OpenID Connect depending on exact wording)
- Give it a name, e.g. OIDC - Microsoft Entra ID
Now fill the important fields (names may vary slightly, but conceptually):
4.1 OpenID Connect settings
- Authentication Provider or Provider Type: OpenID Connect
- Discovery URL (important – this is where OIDC "lives"):
https://login.microsoftonline.com/<TENANT_ID>/v2.0/.well-known/openid-configuration
(replace
<TENANT_ID>with your Directory (tenant) ID from Azure). - Client ID: your Azure Application (client) ID
- Client Secret: the secret you created
- Scope:
openid profile email
(you can also add
offline_accessif you want refresh tokens later, but not needed just for SSO). - Username Column / Attribute Mapping:
- Map APEX username to a claim like
preferred_usernameorupn. - Often
preferred_usernameoremailis fine.
- Map APEX username to a claim like
Save the scheme.
4.2 Get the Callback URL from APEX
After you save, APEX will show a Callback URL for that scheme.
It looks like:
https://<your-apex-host>/ords/apex_authentication.callback
Copy this value.
Now go back to Azure:
- In the app registration, go to Authentication.
- Under Redirect URIs, add:
- Platform: Web
- URI: paste that Callback URL from APEX.
- Save.
4.3 Make this scheme the current one
In APEX Authentication Schemes:
- Set your new OIDC - Microsoft Entra ID scheme as Current.
At this point, the OIDC wiring is "ready".
Step 4 – Test the full roundtrip
Let's confirm the whole flow:
- In APEX, create a simple page (or use an existing one) with a region showing:
<p>APP_USER = &APP_USER.</p>
- Run the application from the builder (or via URL).
If everything is correct:
- You hit your APEX app → immediately get redirected to Microsoft login.
- You sign in with an organization account (
user@yourcompany.com). - After success, you get redirected back to APEX.
- You see your page and the value of
APP_USERshould be something like:user@yourcompany.com(depending on which claim you mapped).
If that works, SSO is alive 💡
If it fails, typical issues:
- Redirect URI mismatch (Azure vs APEX).
- Wrong tenant ID in discovery URL.
- Wrong client secret / expired secret.
Step 5 – Add authorization logic (roles)
Now that "who are you?" is solved, we decide "what can you do?".
You asked: Which option is best or ideal? Local tables? APEX schemes? Map to Entra groups?
6.1 Option A – Local roles table in the database (recommended starter)
Structure:
- APP_USERS
- USER_ID (PK)
- USERNAME (e.g., user@company.com)
- ACTIVE_FLAG
- whatever else (full name, etc.)
- APP_ROLES
- ROLE_ID (PK)
- ROLE_CODE (e.g., ADMIN, MANAGER, REPORT_VIEWER)
- DESCRIPTION
- USER_ROLES
- USER_ID
- ROLE_ID
Flow:
- In the Post-Authentication process for your scheme, you call a PL/SQL procedure, e.g.:
my_security_pkg.post_auth (
p_username => apex_authentication.get_user
);Inside
my_security_pkg.post_auth:- If
p_usernamenot in APP_USERS, insert it. - Optionally set defaults (e.g., first logged-in user becomes ADMIN, or you manage manually).
- No roles assignment logic hardcoded; you do that via admin UI / SQL later.
- If
- Create Authorization Schemes in APEX that check roles:
- e.g., Authorization Scheme:
Is_Admin
RETURN my_security_pkg.user_has_role(
p_username => :APP_USER,
p_role_code => 'ADMIN'
); - e.g., Authorization Scheme:
- Apply authorization schemes to pages, regions, buttons, etc.
Pros:
- All app behavior controlled in the DB/APEX layer.
- Easy to debug and modify without touching Azure.
- Good starter path while you're figuring the org's group structure.
6.2 Option B – Use Entra ID groups / app roles directly
You can tell Azure to send group IDs or app roles as claims in the token.
Flow:
- In Azure App Registration → Token configuration:
- Add Group claims or App roles.
- In APEX, read these claims (depending on the mapping options your scheme exposes).
- Your Authorization Schemes check something like:
- Does the user's claims contain
some-group-id? - Or does the
rolesclaim containAdmin?
- Does the user's claims contain
Pros:
- Roles are managed centrally in Entra ID.
- Good for large organizations with many apps sharing roles.
Cons:
- More Azure-side complexity.
- You tie app behavior to Azure configuration and group IDs → less DB-centric.
6.3 Hybrid approach (often ideal)
- Source of truth for roles is still in the DB (Option A).
- But you auto-sync / auto-assign based on Entra claims in your Post-Auth PL/SQL:
- If the token has group XYZ, assign user role ADMIN in your local tables.
- If not, give them just basic role.
Gives you:
- Central identity/entitlement from Entra.
- Local, easy-to-query roles in the DB.