How to set up SSO with Microsoft Entra ID and Google Workspace using SAML 2.0 and OpenID Connect
To set up SSO with Microsoft Entra ID and Google Workspace, whether one directory or both, you do not integrate every application with every identity provider: you put an identity broker in the middle. Applications speak a single protocol — OpenID Connect — to the broker; the broker speaks SAML 2.0 or OIDC to Entra ID and Google Workspace. A new application then needs one configuration (redirect URI and project key) instead of N SAML configurations, and adding a new identity provider does not touch the code of applications already in production. With LoginMaster as the broker, applications connect through the TypeScript and .NET SDKs or the REST API (LoginMaster is not a generic OpenID Provider for your apps), and the broker federates Entra ID and Google Workspace over OAuth 2.0 / OpenID Connect; SAML 2.0 federation is on the roadmap.
OIDC or SAML 2.0: which one, and where
The question "SAML or OIDC?" has different answers depending on which side of the integration you are on. Between your applications and the broker, OIDC is almost always preferable: it is JSON, it works with SPAs and mobile apps, it handles token refresh and it does not require parsing and validating signed XML. Between the broker and the corporate identity provider the IdP decides: Entra ID and Google Workspace support both, but many established enterprise setups (and on-premise ADFS) only expose SAML 2.0. A clarification about LoginMaster: towards applications it does not expose a generic OpenID Connect endpoint, integration goes through the SDKs or the REST API; towards Entra ID and Google Workspace it federates over OIDC today, while SAML 2.0 is on the roadmap. The SAML steps below therefore apply to brokers that already support it.
| Criterion | OpenID Connect | SAML 2.0 |
|---|---|---|
| Format | JSON / JWT | Signed XML |
| Typical transport | HTTPS redirect + POST to /token | HTTP-Redirect (AuthnRequest) + HTTP-POST (Response) |
| SPAs and mobile apps | Native (Authorization Code + PKCE) | Not suitable: needs a backend to process the assertion |
| Session renewal | Refresh tokens and prompt=none | Re-authentication at the IdP |
| User attributes | Claims in the ID token and /userinfo | Attribute Statement in the assertion |
| Global logout | RP-Initiated Logout / Front-Channel | Single Logout (SLO), often partially implemented |
| Clock sensitivity | Low (tolerance on iat/exp claims) | High: NotBefore / NotOnOrAfter typically ±5 minutes |
| Choose it when | New apps, APIs, mobile, broker integration | Legacy enterprise IdP, ADFS, SaaS apps that only expose SAML |
For the theoretical comparison between the protocols, the extended treatment is in OAuth 2.0, OIDC and SAML: differences and use cases. Here we move on to configuration.
Step 1 — Register the application as a project
Every application that delegates login is a project: web app, mobile app and admin panel are three distinct projects, each with its own cryptographic key and its own policies. That is what lets you enforce mandatory 2FA on the admin panel while keeping it optional on the public app, without duplicating the user base.
- 1Create the project in the tenant and note the project key (pk_live_…): it is the public identifier used in authentication calls.
- 2Register the exact redirect URIs, one per environment. The comparison is character by character: https://app.example.com/callback and https://app.example.com/callback/ are two different URIs.
- 3Set the project session lifetime and 2FA policy (disabled, optional, mandatory).
- 4Generate a separate API key (ak_live_…) if the backend will also do provisioning: the project key is for login, the API key for administrative operations.
npm install @loginmaster/sdkimport { LoginMaster } from "@loginmaster/sdk";
const lm = new LoginMaster({
projectKey: process.env.LOGINMASTER_PROJECT_KEY,
tenant: "https://tenant.example.com",
});
// After delegated login: verify the dual-signature token (tenant + cloud)
const session = await lm.verifyToken(token);
if (session.valid) {
const userId = session.subject; // e.g. sub_9f2a7c
}The same applies on .NET with the ASP.NET Core middleware; both full quickstarts are on Integration. If you use neither TypeScript nor .NET, the same operations are available over REST: POST /v1/auth/token and POST /v1/auth/verify.
Step 2 — Federate Microsoft Entra ID via OpenID Connect
This is the path to prefer with Entra ID when there are no historical constraints. In the Entra ID portal: App registrations → New registration.
- 1Supported account types: choose "Accounts in this organizational directory only" for a closed corporate SSO, or multitenant if you must accept several customer directories.
- 2Redirect URI (Web type): the broker callback endpoint, not the one of the final application.
- 3Certificates & secrets: generate a client secret (or better, register a certificate) and store it in the broker tenant.
- 4API permissions: openid, profile, email. Add User.Read only if you need to read the Graph profile; SSO alone does not require it.
- 5Token configuration: add the groups claim if you want to map Entra groups onto application roles.
https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configurationFrom that document the broker automatically derives the authorization endpoint, the token endpoint and the jwks_uri, so Microsoft's signing key rotation requires no manual work. The relevant ID token claims are:
| Claim | Content | Recommended use |
|---|---|---|
| oid | Immutable object ID of the user in the directory | Identity correlation key: use this, not the email |
| tid | Tenant ID of the Entra directory | Check the user comes from the expected directory (multitenant) |
| preferred_username | UPN or sign-in email | Display; it can change over time |
| Email address | Notifications; do not use it as a stable identifier | |
| groups / roles | Assigned groups or app roles | Mapping onto project roles |
Step 3 — Federate Microsoft Entra ID via SAML 2.0
You need this when the organisation has already standardised on SAML or when the IdP is on-premise ADFS. In the portal: Enterprise applications → New application → Create your own application → Integrate any other application, then Single sign-on → SAML.
| Entra ID field | What to enter | Name in the SAML standard |
|---|---|---|
| Identifier (Entity ID) | The unique Service Provider identifier, e.g. https://tenant.example.com/saml/metadata | SP EntityID |
| Reply URL | The endpoint receiving the signed assertion, e.g. https://tenant.example.com/saml/acs | Assertion Consumer Service (ACS) URL |
| Sign on URL | Entry point for the SP-initiated flow | SP-initiated SSO URL |
| Logout URL | Single Logout endpoint, if you implement it | SLO endpoint |
| User Identifier (Name ID) | user.objectid, not user.mail | NameID (persistent format) |
Then download the Federation Metadata XML and upload it to the broker: it contains the IdP EntityID, the SSO endpoints and the signing certificate, and importing it avoids transcribing the certificate by hand.
https://login.microsoftonline.com/{tenantId}/federationmetadata/2007-06/federationmetadata.xmlThe same rule as the oid claim applies to the NameID: set user.objectid with persistent format. The Entra ID default is often the email address, and it is the number-one cause of duplicate accounts after a corporate reorganisation.
Signing certificate rotation
Entra ID SAML certificates default to a three-year validity, and expiry breaks login for every user at the same instant. Two concrete countermeasures: configure expiry notifications to a monitored mailbox, and import the IdP metadata by URL rather than as a file, so the broker re-reads the certificate without a manual task scheduled three years in advance.
Step 4 — Federate Google Workspace via OpenID Connect
Google exposes a public discovery document and a single issuer for all domains, so configuration is shorter than Entra ID's — but with one extra security requirement.
https://accounts.google.com/.well-known/openid-configuration- 1In Google Cloud Console create a project and, under APIs & Services → Credentials, an OAuth 2.0 Client ID of type Web application.
- 2Authorized redirect URIs: the broker callback endpoint (exact, https, no trailing slash unless you use one).
- 3Configure the OAuth consent screen as Internal if you want to restrict it to the Workspace domain only.
- 4Requested scopes: openid, email, profile.
- 5Validate the hd (hosted domain) claim on every login on the broker side: without that check, any personal Gmail account going through the same consent screen is technically a valid login.
Step 5 — Federate Google Workspace via SAML 2.0
In the Admin console: Apps → Web and mobile apps → Add app → Add custom SAML app. Google shows its own metadata (SSO URL, Entity ID, certificate) to upload to the broker; then you fill in the Service Provider ACS URL and Entity ID.
- 1Copy or download Google's IdP metadata and import it into the broker.
- 2Service provider details: broker ACS URL and Entity ID; Name ID format PERSISTENT and Name ID = Basic Information > Primary email (or a custom immutable attribute, if you manage one).
- 3Attribute mapping: map at least primary email, first name, last name; add groups if you need them for roles.
- 4User access: assign the app to the organisational units or groups that must have access. Skip this and login fails with app_not_configured_for_user.
- 5Allow for propagation: Admin console changes can take several minutes to become effective for all users.
Step 6 — Map claims and groups onto application roles
The real value of federated SSO is not saving a password: it is that authorisation stops living in a local table nobody updates. A user who moves department changes group in the directory, and the application role follows at the next login with no IT ticket.
| Source | Example | Project role |
|---|---|---|
| Entra ID group (groups claim) | GRP-FINANCE-APPROVERS | approver |
| Entra ID app role (roles claim) | Admin.Billing | billing-admin |
| Google Workspace group | administration@example.com | admin |
| Workspace custom attribute | department = Support | support-agent |
| Verified email domain (hd claim) | example.com | member (baseline role) |
Two rules that prevent incidents: always assign a minimal baseline role to anyone who authenticates but matches no rule (instead of inheriting the last known role), and recompute roles at every login rather than only at account creation. The second point is what makes privilege revocation effective, not just access revocation.
If there are many groups to propagate, note that Entra ID "overages" the token beyond a certain group count and returns a Graph reference instead of the list: in that case, map explicit app roles rather than raw groups.
Step 7 — Session, revocation and deprovisioning
SSO is half the problem; the other half is what happens when access must stop. With federation, disabling the account in the corporate directory stops new sessions being issued on federated services: you do not have to remember to disable the user on every platform. The residual window is the lifetime of tokens already issued, which is why it should be sized deliberately.
| Scenario | Effect | Configuration lever |
|---|---|---|
| Account disabled in the IdP | No new federated sessions | Immediate at the next login |
| Access token already issued | Stays valid until expiry | Project token lifetime (e.g. 3600 s) |
| Immediate revocation required | Session closed on the application side | Token verification on every sensitive request + app-side invalidation (webhooks on the roadmap) |
| Role change | Permissions updated at the next login | Role recomputation on every authentication |
| Lost device | Active sessions closed | User session management page |
With a broker that supports them, the lever for immediate revocation is the webhook: the broker notifies the application and the application invalidates its own session, with no polling. In LoginMaster lifecycle webhooks are on the roadmap and not available today: immediate revocation relies on a short token lifetime and on verifying the dual-signature token on every sensitive request. Mind a second limit too: deactivating a subject blocks new logins but does not atomically revoke sessions and API keys, which must be closed with explicit steps.
The full lifecycle (creation, role change, suspension, deletion) is covered in User provisioning and lifecycle via REST API and SDK.
Entra ID and Google Workspace together: one SSO for both directories
Many organisations run both: Microsoft 365 and Entra ID for one business unit, Google Workspace for another, often after an acquisition or a merger. There are two different problems here, and it pays to keep them apart.
1. Signing in to Google Workspace with Entra ID credentials. Here Entra ID is the identity provider and Google Workspace is the service provider. Microsoft publishes a native gallery application ("Google Cloud / G Suite Connector by Microsoft") for this. It is configured between Microsoft and Google and does not involve your own applications.
2. Letting users from both directories into your own business applications. This is the scenario this guide covers. Instead of configuring every application twice, you register Entra ID (Steps 2–3) and Google Workspace (Steps 4–5) as two identity providers on the same broker. Your applications keep speaking one protocol, OpenID Connect, and the broker tells the two populations apart through the tid claim (Entra ID) and the hd claim (Google Workspace).
Two rules apply when both directories are federated:
- Correlate users on immutable identifiers (
oidfor Entra ID,subfor Google), never on email. The same person may have an address in both directories, and correlating on email merges two distinct accounts. - Map roles per source. An Entra ID group and a Google Workspace group with the same name are not the same group. Keep separate mapping rules for each identity provider (see Step 6).
Testing: nine checks before release
- 1SP-initiated login: from the application, with the user not yet authenticated at the IdP.
- 2IdP-initiated login: from the Microsoft or Google portal (SAML only; it does not exist in OIDC, and asking for it signals a mis-stated requirement).
- 3Valid user not assigned to the application: it must fail with an understandable message, not a blank page.
- 4User from an external domain: must be rejected (hd or tid claim verification).
- 5Expired session: silent renewal and, where impossible, a clean return to the login screen.
- 6Logout: check whether the IdP session stays open; with partial SLO the user 'leaves' and re-enters with one click, and that must be documented.
- 7Account disabled in the IdP: new login refused within the expected time.
- 8Clock skew: move a client clock by 10 minutes and check the error message (SAML will fail on the NotBefore / NotOnOrAfter conditions).
- 9Signing certificate rotation: simulate it in a test environment, do not discover it in production.
Typical errors and how to read them
| Symptom | Most likely cause | Fix |
|---|---|---|
| AADSTS50011 | Redirect URI does not match the registered one | Align character by character, trailing slash included |
| AADSTS700016 | Application not found in the directory | Wrong client ID, or app registered in another tenant |
| AADSTS50105 | User not assigned to the application | Assign the user or group to the Enterprise application |
| app_not_configured_for_user (Google) | SAML app not assigned to the organisational unit | Assign the app to the OU or group in Admin console |
| Signature validation failed | IdP certificate expired or stale on the SP | Re-import the IdP metadata, preferably by URL |
| Assertion rejected on time conditions | Clock skew between IdP and SP | Sync via NTP; typical tolerance ±5 minutes |
| Duplicate users after a reorganisation | Identity correlated on email instead of an immutable ID | Correlate on oid / sub / persistent NameID |
| invalid_client on the token endpoint | Expired client secret | Rotate the secret and schedule the next expiry |
Managed broker, self-hosting or direct integration
All three routes are viable, but their cost and risk profiles differ sharply. The honest comparison is about the work left after the first successful login.
| Aspect | Direct per-app integration | Self-hosted broker (e.g. Keycloak) | Managed broker (LoginMaster) |
|---|---|---|---|
| Configurations to maintain | N apps × M identity providers | 1 per IdP, but you own the infrastructure | 1 per IdP, managed infrastructure |
| SAML certificate rotation | Manual on every application | Centralised, to be staffed | Centralised, via metadata URL |
| IdP patches and CVEs | On every application team | On your team (major upgrades included) | On the vendor |
| Customer/tenant isolation | To be designed | Separate realms, logical isolation | Cryptographic isolation: tokens signed per tenant and project |
| Admin credential reset | Depends on the app | Possible for the realm admin | Technically impossible: the user only |
| Cost as users grow | Hidden in team time | Infrastructure + staffing | Per tenant and project, unlimited users |
| Data jurisdiction | Varies | Wherever you install it | EU, personal data only in the tenant |
What sets LoginMaster apart in the bottom rows is not commercial but architectural: the token returned to the application carries two independent signatures, one from the tenant and one from the cloud, and a token issued for tenant A fails validation in the context of tenant B even when the two share the deployment. Architecture details are on Security, while the SSO page collects the available federation features. Teams coming from a Keycloak installation will find the full path in Migrating from self-hosted Keycloak to a managed IAM.
Where this guide comes from
LoginMaster is the IAM platform of CDBKR S.r.l., an Italian company that builds and operates authentication infrastructure for software houses, MSPs and European enterprise organisations. The procedures described here are the ones the team applies in federation projects towards Entra ID and Google Workspace, including the case where both directories coexist in the same organisation. A real adoption example is documented in the case studies; to assess your own scenario, start from the contact page.
Frequently asked questions
It depends on which side of the integration you are on. Between your applications and the identity broker use OpenID Connect: it is JSON, it supports SPAs and mobile apps with Authorization Code + PKCE and it handles token renewal. Between the broker and Entra ID choose OIDC if you have no historical constraints; use SAML 2.0 if the organisation has already standardised on SAML or if the identity provider is on-premise ADFS. Not every application needs to speak the identity provider's protocol: that is exactly the job of the broker. With LoginMaster applications integrate through the TypeScript/.NET SDKs or the REST API, and federation to Entra ID and Google Workspace is OIDC today (SAML 2.0 on the roadmap).
Yes, and it is a frequent scenario after acquisitions or in companies whose departments run different suites. The broker registers both identity providers and either presents the choice to the user or routes automatically based on the domain of the email address entered (home realm discovery). Applications do not see the difference: they always receive an OIDC token with the same claim shape, whichever IdP authenticated the user.
The technical configuration of an OIDC federation to Entra ID or Google Workspace is a matter of a few hours: app registration on the IdP side, redirect URI, scopes and claim mapping. The SAML 2.0 route adds the metadata exchange and NameID verification. Real project time is almost always dominated by testing — unassigned users, external domains, revocation, certificate rotation — not by the initial configuration.
Access to federated services stops with no manual work: the corporate directory no longer authenticates the user, so the broker issues no new sessions. Tokens already issued stay valid until their configured expiry (typically one hour), so immediate revocation needs an event such as the subject.deactivated webhook, which notifies the application to invalidate its own session (in LoginMaster lifecycle webhooks are on the roadmap: today you rely on short-lived tokens and checking user status via the REST API). That is the difference between revoking access and revoking the session in progress: both need to be designed.
Because email changes: marriages, surname changes, domain mergers, reorganisations. If application identity hangs off the email, at the next login the user looks like a new person and loses history, roles and data. Always correlate on an immutable identifier: the oid claim in Entra ID, the sub claim in Google, the persistent-format NameID in SAML. Email stays a useful attribute, but an updatable one.
In federated SSO passwords never pass through the broker: the user authenticates at Entra ID or Google and the broker only receives an assertion or an ID token. For local users — non-federated ones, typical of mixed scenarios with partners and end customers — the answer depends on the vendor. In LoginMaster credentials are protected with Argon2 and a split salt between tenant and cloud, and no function exists that returns or resets a user's password: not even the tenant administrator can do it.
The broker can act as a SAML Identity Provider towards those applications while remaining a Service Provider towards Entra ID or Google Workspace. In practice the legacy application sees a classic SAML IdP (Entity ID, ACS URL, signing certificate) while upstream authentication happens against the corporate directory. That way you neither touch the application code nor duplicate credentials, which is the main reason migrating those applications gets postponed for years.
It adds to it. If the corporate identity provider already enforces MFA, the broker can accept it and not ask for a second one, reading the authentication information carried in the token. If instead you need a specific second factor on sensitive applications — an admin panel, an area with financial data — the policy is set at project level, independently of what the IdP does. The detail of TOTP and conditional access policies is in the dedicated LoginMaster guide.
Want to see LoginMaster in action?
Request a personalized demo and discover how to manage identities and access securely and compliantly.