nopStation documentation
Single Sign-On (SSO) for nopCommerce
Simplify enterprise authentication on nopCommerce. This guide covers installing and configuring the nopStation Enterprise Single Sign-On plugin, managing identity providers, and connecting Microsoft Entra ID, Okta, Google Workspace, Keycloak, Auth0, OneLogin, Ping, ADFS, JumpCloud and other SAML 2.0 or OpenID Connect providers.
1. Overview
Managing separate login credentials and user permissions adds unnecessary complexity for growing businesses. The nopStation Enterprise Single Sign-On (SSO) plugin connects nopCommerce to the identity providers your organization already uses, so employees and B2B customers sign in with their existing organizational accounts.
The plugin supports SAML 2.0 and OpenID Connect (OIDC). It simplifies sign-in while keeping you in control of identity validation, customer roles and access management. Ready-made presets are included for Microsoft Entra ID, Okta, Google Workspace, Keycloak, Auth0, OneLogin, Ping Identity, Microsoft ADFS and JumpCloud, and a Generic option connects other compatible identity providers.
Key capabilities
- Standards-based sign-in: SAML 2.0 and OpenID Connect, including PKCE.
- Identity provider presets: nine ready-made presets, plus Generic for other providers.
- Role mapping: directory groups become nopCommerce customer roles and B2B price tiers at every sign-in.
- Optional SCIM 2.0 provisioning: create, update and deactivate accounts as your directory changes.
- Controlled account linking: link existing customers automatically, after email verification, or through an admin approval queue.
- Audit history: a searchable record of sign-ins, role changes and configuration updates.
- Emergency administrator access: a local admin login that keeps working if the identity provider is unavailable.
Together, these features solve common enterprise authentication challenges directly within nopCommerce, with no third-party broker in between.
2. Prerequisites
Before you install the Single Sign-On plugin, make sure you have the following:
- nopStation Core plugin (
NopStation.Core): it must be installed before the Single Sign-On plugin. It provides the shared licensing and menu features that all nopStation plugins use. - Administrator access to your nopCommerce administration area.
- A store reachable over HTTPS: identity providers send users back to HTTPS callback addresses (see section 14).
3. Installation
Install the nopStation Core plugin first, then the Single Sign-On plugin.
- Download the Single Sign-On plugin (and the nopStation Core plugin, if it is not installed yet) from your nopStation account under Downloadable products.
- In nopCommerce, go to Administration → Configuration → Local plugins.
- Click Upload plugin or theme, choose the nopStation Core zip file, and click Upload plugin or theme in the dialog.
- Repeat the upload for the Single Sign-On plugin zip file.
- In the Local plugins list, find nopStation Core and click Install.
- Find Single sign-on (SSO) in the same list and click Install.
- When nopCommerce prompts you, click Restart application to apply changes.
- Continue with section 4 to confirm the plugin is installed, then configure it.
4. Find and verify the plugin
To inspect, configure, or verify the installed plugin, navigate in the nopCommerce administration panel to Configuration > Local Plugins (/Admin/Plugin/List).
In the search panel, enter Single sign-on (SSO) into the Friendly name field and click the Search button. The grid immediately filters to display exclusively the Single sign-on (SSO) plugin entry.
Plugin Metadata & System Dependencies
| Attribute | Value | Description |
|---|---|---|
| Friendly Name | Single sign-on (SSO) | User-facing display name in the administration interface. |
| System Name | NopStation.Plugin.ExternalAuth.SSO |
Unique programmatic system identifier used across routes and database bindings. |
| Group | Nop-Station | Groups the plugin with other nopStation plugins (label shown by the plugin metadata). |
| Version | See Local plugins list | Targets the current nopCommerce runtime on .NET 9.0. |
| Dependencies | NopStation.Core |
Core infrastructural dependencies for licensing and menu hooks. |
5. Global SSO configuration
Global runtime parameters, authentication policies, security tolerances, and SCIM 2.0 provisioning settings are managed at /Admin/SSO/Configure.
Configuration Parameters Reference
| Setting Name | Default | Functional Description |
|---|---|---|
| Enable SSO | True |
Master switch enabling or disabling federated single sign-on across the storefront. |
| Emergency local admin login | True |
Ensures store administrators can always access local login at /login?returnUrl=/Admin even when IdP enforcement is active. |
| Allowed Clock Skew | 60 seconds |
Cryptographic tolerance window applied when validating SAML assertion NotBefore/NotOnOrAfter and OIDC JWT expiration. |
| Default Provider | (None) | Optional provider automatically selected when customers access the store with SSO auto-redirect enabled. |
| Domain Discovery | Disabled |
Enables Home Realm Discovery (HRD) to automatically route users to their corporate IdP based on their email domain. |
| Audit Retention | 90 days |
Number of days before security and authentication audit events are pruned by the scheduled retention task. |
| Public Base URL | (store URL) | Public HTTPS origin used to build redirect, ACS and Entity ID URLs. Must match exactly what browsers and identity providers use. |
| Disable default login | — | Hides the password form and redirects /login to the default provider (SSO-only). Turn on only after every provider passes the verification checklist. |
6. Identity providers
The Identity Providers grid at /Admin/SSO/List provides a centralized management console for all federated SAML 2.0 and OpenID Connect identity sources.
7. Create an identity provider
To register a new enterprise federation connection, click the Add new button on the provider list to access /Admin/SSO/Create.
8. Provider settings and protocol cards
Editing an identity provider at /Admin/SSO/Edit/{id} provides collapsible cards for granular protocol settings, attribute mappings, role reconciliation, and certificate management.
9. Linked customer identities
The Linked Identities console at /Admin/SSO/Links displays all active federated links connecting nopCommerce customer accounts with external IdP identifiers (Subject / NameID).
10. Pending and rejected link approvals
When an identity provider or store policy requires manual administrator verification before linking an existing account, requests are held in the verification queue.
11. Policy and claims simulator
The interactive Policy Simulator at /Admin/SSO/Simulator allows administrators and integration engineers to validate SAML assertions, OIDC claims payloads, email domain filters, and role mappings without performing live logins.
12. Security audit log and SIEM export
The audit trail at /Admin/SSO/Audit logs every authentication attempt, session establishment, certificate change, and policy rejection for corporate compliance and security operations.
13. Storefront login experience
On the customer-facing storefront, the plugin seamlessly injects federated single sign-on buttons into the standard nopCommerce login page (/login or /en/login).
15. Production checklist
The setup guides use relaxed settings so you can test quickly. Before you open SSO to real customers, work through this list.
- Stable public URL: set Public Base URL to the store’s permanent HTTPS address (no tunnels or
localhost), then re-copy every redirect, ACS and Entity ID URL into each identity provider. - Safe account linking: switch Account linking from Automatic to Admin approval or email-verified linking, unless the IdP’s email claim is verified and trusted. Automatic email linking can enable account takeover.
- Private network off: turn off Allow private network endpoints and Allow private-network metadata URL.
- Pinned issuers and allow lists: pin each Issuer to the exact discovery value and restrict access with tenant, domain or group allow lists where available.
- Emergency access: keep Emergency local admin login on and confirm
/login?returnUrl=%2FAdminworks for an Administrator. - SSO-only mode last: turn on Disable default login only after every provider passes the verification checklist.
- IdP-initiated SSO: leave Allow IdP-initiated SSO off unless users must launch the store from an IdP portal.
- Certificates and secrets: prefer SHA-256 signing, record certificate expiry dates, and rotate client secrets used during testing.
- Clean up: remove test users, test applications and test providers you no longer need.
- Audit: set Audit retention to match your policy and export the audit CSV to your SIEM if you use one.
16. Identity provider setup guides
Each guide covers the identity provider’s app registration and the matching settings in the nopStation SSO plugin. Where a provider supports both OIDC and SAML, both are covered in the same guide. Screenshots of the admin pages are in sections 4–13.
| # | Provider | Preset | Typical protocol |
|---|---|---|---|
| 17 | Microsoft Entra ID | EntraId | OIDC / SAML |
| 18 | Azure AD B2C | EntraId | OIDC |
| 19 | Okta | Okta | OIDC / SAML |
| 20 | Auth0 | Auth0 | OIDC / SAML |
| 21 | Google Workspace | GoogleWorkspace | OIDC / SAML |
| 22 | Keycloak | Keycloak | OIDC / SAML |
| 23 | OneLogin | OneLogin | OIDC / SAML |
| 24 | PingOne / PingFederate | Ping | OIDC / SAML |
| 25 | ADFS | Adfs | SAML only |
| 26 | JumpCloud | JumpCloud | SAML / OIDC |
| 27 | Salesforce as IdP | Generic | SAML |
| 28 | Generic / Custom IDP | Generic | OIDC / SAML |
17. Microsoft Entra ID
OIDC app registration and Enterprise SAML application are separate IdP apps. Both use Preset EntraId; choose Protocol Oidc or Saml2 on the plugin provider. Verified with OIDC and SAML.
Microsoft Entra ID / Azure AD / Office 365 (Preset: EntraId, OIDC)
Replace {providerId} in every URL below with your provider id (shown in the Edit page URL after the first save).
OIDC setup
A. Access Entra ID
- Open Microsoft Entra admin center.
- Sign in with your Microsoft account.
- Go to Manage tenants and select your existing Default Directory.
- No new tenant is required for testing.
B. Register the SSO application
- Navigate to Entra ID → App registrations → New registration.
- Application name:
nopStation SSO(or any label you prefer). - Supported account types: Single tenant only – Default Directory.
- Redirect URI platform: Web.
- Enter the plugin OIDC callback from the provider Edit page (Redirect URI, read-only):
{PublicBaseUrl}/sso/oidc/callback/{providerId}
Example (testing): https://localhost:{port}/sso/oidc/callback/12
(If you use a Cloudflare/ngrok public URL, use that host instead of localhost — it must match Public Base URL on /Admin/SSO/Configure.)
- Click Register.
C. Get application credentials
- From the app Overview, copy:
- Application (client) ID
- Directory (tenant) ID
- Navigate to Certificates & secrets → New client secret. Create a secret and copy its Value immediately (shown once).
openid profile emailare OIDC scopes on the plugin authorize request—not Microsoft Graph API permissions. Do not add them in the Graph permissions blade. Add Graph permissions (e.g.User.Reador group APIs) only if you configure Graph-based overage/enrichment that actually calls Graph.- Token configuration (optional): add optional claims
email,family_name,given_name,upnas needed.
D. Create a test user
- Navigate to Entra ID → Users → New user.
- Create a dedicated test user in your tenant (e.g.
sso.tester@{yourtenant}.onmicrosoft.com). - Set the required password and complete any required first-login / MFA steps.
E. Map Entra values → /Admin/SSO/Edit/{providerId} (e.g. /Admin/SSO/Edit/12)
| Entra source | Paste into Edit field | Example / notes |
|---|---|---|
| (create provider first) | Name | nopStation SSO (storefront button label) |
| (fixed) | Preset | EntraId |
| (fixed) | Protocol | Oidc |
| Directory (tenant) ID | OIDC discovery URL then click Fetch OIDC discovery | https://login.microsoftonline.com/{Directory-tenant-ID}/v2.0/.well-known/openid-configuration |
| Directory (tenant) ID (after Fetch, or pin manually) | Issuer | https://login.microsoftonline.com/{Directory-tenant-ID}/v2.0 — pin the real tenant GUID (avoid leaving {tenantid} unresolved unless you intentionally allow multi-tenant) |
| Application (client) ID | Client Id | GUID from Overview |
| Client secret Value | Client Secret | Paste once; leave blank on later saves to keep existing |
| (recommended default) | Scopes | openid profile email |
| (recommended default) | Email claim | Prefer email when Entra emits it (add optional claim if missing). preferred_username is often UPN — not a verified mailbox; inspect a real ID token before Automatic linking |
| (recommended default) | Subject claim | Preset default sub (OIDC subject). Use oid only intentionally (directory object id; tenant-scoped) |
| Plugin shows this (read-only) | Redirect URI | Copy into Entra Redirect URI (Web) — do not invent a different path |
| (testing) | JIT policy | Automatic (first login creates customer) |
| (testing) | Account linking | Automatic (testing only) or Admin approval for safer linking |
| (testing) | Audience | Storefront until admin SSO is required |
| Directory (tenant) ID (optional harden) | Tenant allow list | Paste the same tenant GUID to lock the provider to that directory |
Also on /Admin/SSO/Configure:
| Setting | Value |
|---|---|
| Enable SSO | Yes |
| Public Base URL | Exact browser/IdP URL (e.g. https://localhost:{port} or your tunnel) — must match the host used in Entra Redirect URI |
F. Test user steps
- Incognito →
{PublicBaseUrl}/en/login→ continue with nopStation SSO (or your provider name). - Sign in as the Entra test user.
- Confirm customer created/linked under
/Admin/SSO/Links. - Confirm
/Admin/SSO/Auditshows success (filter by Customer email if needed).
G. SAML
Use the Microsoft Entra ID SAML guide (same Entra tenant; separate Enterprise application + plugin provider with Protocol Saml2).
SAML setup (Enterprise application)
Use this when testing Microsoft SAML SSO (Enterprise application → Single sign-on → SAML), not the OIDC app registration described in Microsoft Entra ID OIDC.
Replace {providerId} with your provider id after you create or import the provider.
https://localhost:{port} works for browser redirects in some OIDC tests but fails for Entra SAML ACS from Microsoft’s servers. Use one host everywhere: Configure → provider Public base URL → Entra Identifier / Reply / Sign on / Logout URLs → browser.A. Prerequisites (plugin)
- Admin → nopStation → SSO → Configure:
- Enable SSO = Yes
- Public Base URL = tunnel origin (no trailing slash), e.g.
https://your-tunnel.trycloudflare.com - Keep Emergency local admin login on while testing
- Confirm the tunnel forwards to your store (e.g.
https://localhost:{port}). - Decide how to create the provider (B1 or B2).
B1. Create provider manually (Add new)
- SSO → Identity providers → Add new.
- Set:
| Field | Value |
|---|---|
| Name | Microsoft SAML SSO (storefront button label) |
| Protocol | Saml 2 |
| Provider preset | Entra Id |
| Audience | Storefront |
| Public base URL | Same tunnel as Configure (overrides store URL for ACS/Entity ID) |
| JIT policy | Automatic (testing) |
| Account linking | Automatic (testing) |
| Enabled | Leave off until IdP fields + cert are saved |
- Save once → note provider id from
/Admin/SSO/Edit/{providerId}. - Copy the read-only URLs shown on Edit (they use Public base URL + id):
| Plugin read-only field | Path |
|---|---|
| SSO login URL | {PublicBaseUrl}/sso/login/{providerId} |
| Assertion consumer URL | {PublicBaseUrl}/sso/saml/acs/{providerId} |
| Entity ID | {PublicBaseUrl}/sso/saml/metadata/{providerId} |
| (SLO, if shown) | {PublicBaseUrl}/sso/saml/slo/{providerId} |
- Continue with C (Entra app), then D (paste Entra → plugin).
B2. Import IdP from metadata (recommended when you already have Entra SAML app)
On SSO → Identity providers, click Import IdP from metadata.
Dialog tip (same as admin): Provide a federation metadata URL and/or paste EntityDescriptor XML. When both are set, XML is used. Preferred entity ID selects one IdP from multi-entity metadata.
| Dialog field | Admin hint (nopCommerce *.Hint) |
What to enter (Entra SAML) |
|---|---|---|
| Federation metadata URL | Purpose: HTTPS URL of InCommon or other SAML metadata to import IdP endpoints and certificates. Example: https://md.incommon.org/InCommon/InCommon-metadata.xml |
Entra App Federation Metadata Url (see C). Example: https://login.microsoftonline.com/{tenant-id}/federationmetadata/2007-06/federationmetadata.xml?appid={application-id} |
| Preferred entity ID | Purpose: when the metadata file has many IdPs, import only this entity. Example: https://idp.example.edu/idp/shibboleth |
https://sts.windows.net/{tenant-id}/ (Entra IdP entityID / Issuer) |
| Allow private-network metadata URL | Purpose: allow metadata URLs on private IPs for test IdPs only. Never enable in production. Example: https://192.168.1.10/metadata |
Off (Entra is public HTTPS) |
| Federation metadata XML | Purpose: paste EntityDescriptor / EntitiesDescriptor XML instead of fetching a URL. Example: copy from your campus IdP metadata download. | Optional. If URL import fails, open the metadata URL in a browser and paste the full XML here (leave URL empty). When both URL and XML are set, XML wins. |
Import creates a SAML 2 draft with Issuer, IdP entity ID, SAML SSO endpoint, SLO, and IdP signing certificate.
Then on Edit:
- Set Name =
Microsoft SAML SSO - Set Provider preset = Entra Id (applies Microsoft claim URIs)
- Set Public base URL = tunnel; Save
- Set JIT / Linking = Automatic; Enabled = On; Save
- Confirm Validation = Ready /
valid - Copy the read-only ACS / Entity ID / Login / SLO URLs into Entra (C)
C. Create / configure Entra Enterprise application (SAML)
- Open Microsoft Entra admin center → your tenant.
- Identity → Applications → Enterprise applications → New application → Create your own application.
- Name: e.g.
nopStation SAML→ Integrate any other application you don’t find in the gallery (Non-gallery) → Create. - Open the app → Single sign-on → SAML.
- Under Basic SAML Configuration → Edit, enter plugin values from Edit (B1/B2):
| Microsoft Entra field | nopStation plugin value |
|---|---|
| Identifier (Entity ID) | Entity ID / SP metadata — {PublicBaseUrl}/sso/saml/metadata/{providerId} |
| Reply URL (Assertion Consumer Service URL) | Assertion consumer URL — {PublicBaseUrl}/sso/saml/acs/{providerId} |
| Sign on URL | SSO login URL — {PublicBaseUrl}/sso/login/{providerId} |
| Relay State | Leave empty |
| Logout URL (optional) | {PublicBaseUrl}/sso/saml/slo/{providerId} |
Example (tunnel + provider id 12):
- Identifier:
https://your-tunnel.trycloudflare.com/sso/saml/metadata/12
- Reply URL:
https://your-tunnel.trycloudflare.com/sso/saml/acs/12
- Sign on URL:
https://your-tunnel.trycloudflare.com/sso/login/12
- Logout URL:
https://your-tunnel.trycloudflare.com/sso/saml/slo/12
- Save Basic SAML Configuration.
- Attributes & Claims (defaults are usually enough for Entra preset):
| Claim | Source (typical) | Plugin claim field (Entra preset) |
|---|---|---|
| givenname | user.givenname |
First name → …/claims/givenname |
| surname | user.surname |
Last name → …/claims/surname |
| emailaddress | user.mail |
Email → …/claims/emailaddress |
| name | user.userprincipalname |
Username → …/claims/name |
| Unique User Identifier (Name ID) | Prefer user.mail for email match; UPN also works |
Subject → NameID |
- SAML Certificates:
- Status Active
- Download Certificate (Base64) (public only — never a private key)
- Copy App Federation Metadata Url
- Set up {App name} (right side): copy Login URL, Azure AD Identifier, Logout URL, and metadata URL for the plugin if you did not use Import.
D. Map Entra → /Admin/SSO/Edit/{providerId} (required IdP fields)
If Import (B2) already filled endpoints + cert, only confirm Public base URL, preset, JIT, Enabled. Otherwise fill:
| Entra source | Plugin field | Example |
|---|---|---|
Azure AD Identifier / metadata entityID |
Issuer | https://sts.windows.net/{tenant-id}/ |
| Same as Issuer | IdP entity ID | https://sts.windows.net/{tenant-id}/ |
| Login URL | SAML SSO endpoint | https://login.microsoftonline.com/{tenant-id}/saml2 |
| Logout URL (optional) | Single logout URL | Same host /saml2 or Entra logout URL |
| Tunnel / public store origin | Public base URL | https://your-tunnel.trycloudflare.com |
| (usually leave blank) | Service provider entity ID | Blank → uses metadata Entity ID above |
| Certificate (Base64) → PEM | Signing certificate → Save certificate | -----BEGIN CERTIFICATE----- … public only |
| (testing) | JIT / Linking | Automatic / Automatic |
| (testing) | Enabled | On after Validation is Ready |
Entra preset claim defaults (normally leave as-is after choosing Preset Entra Id):
| Plugin field | Value |
|---|---|
| Subject claim | NameID |
| Email claim | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress |
| Username claim | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name |
| First / Last name | …/givenname / …/surname |
| Tenant claim | http://schemas.microsoft.com/identity/claims/tenantid |
| Object ID claim | http://schemas.microsoft.com/identity/claims/objectidentifier |
| Groups claim | http://schemas.microsoft.com/ws/2008/06/identity/claims/groups |
| App roles claim | http://schemas.microsoft.com/ws/2008/06/identity/claims/role |
Leave empty for first login: Domain / Group allow lists, role mapping, SP signing/decryption certs (unless Entra requires signed AuthnRequests or encrypted assertions).
Do not put plugin ACS/Entity ID values that still say localhost into Entra if Public base URL is the tunnel (or the reverse). After changing Public base URL, Save and re-copy the read-only URLs into Entra.
E. Test user
- Entra → Users → New user (or use an existing cloud user with a mailbox / UPN).
- Assign the user to the Enterprise application (Users and groups → Add user/group).
- Complete password / MFA prompts in a normal browser first if required.
F. Test login
- Open the store on the same host as Public base URL (tunnel URL in the address bar).
- Incognito →
/en/login→ Microsoft SAML SSO (or open Sign on URL). - Sign in at Microsoft → return to store authenticated.
- Confirm SSO → Linked identities and SSO → Audit (
sso.signin_succeeded). - Optional: sign out and confirm SLO if Logout URL is configured on both sides.
G. SAML checklist / common failures
| Check | Pass |
|---|---|
| Public base URL = tunnel (or public HTTPS) | Yes |
Entra Identifier / Reply / Sign on use same host + correct {providerId} |
Yes |
| IdP signing certificate saved (Validation Ready) | Yes |
Issuer / IdP entity ID = https://sts.windows.net/{tenant-id}/ |
Yes |
| SAML SSO endpoint = Entra Login URL | Yes |
| Test user assigned to Enterprise app | Yes |
| Preset Entra Id + Protocol Saml2 | Yes |
| Symptom | Likely cause | Fix |
|---|---|---|
| ACS never hit / timeout | Entra cannot reach localhost | Use tunnel Public base URL + update Entra URLs |
| Signature validation failed | Wrong/expired IdP cert | Re-download Certificate (Base64); Save certificate |
| Email / JIT failed | Name ID = UPN but no mail claim | Set Unique User Identifier to user.mail; ensure emailaddress claim |
| Wrong provider ACS | Entra still points at an old provider id | Re-copy Entity ID / ACS / Login from current Edit page |
| Import URL failed | Download blocked/timeout | Paste Federation metadata XML; retry URL |
| Validation still “cert required” after import | Stale message before cert attach | Save provider again after cert |
18. Azure AD B2C
Use Preset EntraId with B2C policy discovery (*.b2clogin.com), not workforce login.microsoftonline.com. User flows often emit emails (array) — plugin accepts that alias automatically.
Azure AD B2C (Preset: EntraId, OIDC)
B2C is not a separate plugin preset — use Preset EntraId + Protocol Oidc with B2C policy discovery (*.b2clogin.com). Do not reuse a workforce Entra (login.microsoftonline.com) issuer for a B2C app.
Trial: Azure subscription → create an Azure AD B2C tenant (or use an existing one). Create a local B2C test user under Users.
localhost and a tunnel causes cookie / redirect mismatches.A. User flow + app registration
- B2C tenant → User flows → New user flow → Sign up and sign in (e.g.
B2C_1_signupsignin). Recommended attributes: Email Address, Display Name, Given Name, Surname. - Under the flow → Application claims: enable Email Addresses, Given Name, Surname, User’s Object ID (and Display Name if needed).
- App registrations → New registration (in the B2C tenant, not the workforce directory):
- Supported account types: Accounts in any identity provider or organizational directory (for authenticating users with user flows).
- Redirect URI (Web):
{PublicBaseUrl}/sso/oidc/callback/{providerId}(exact; create the plugin provider first to get{providerId}).
- Certificates & secrets → new client secret → copy once.
- Optional: under Authentication, add front-channel logout URL later if testing RP logout (B2C end_session support varies by policy).
B. Plugin (/Admin/SSO/Edit/{id})
| Field | Value |
|---|---|
| Name | e.g. Azure AD B2C |
| Protocol / Preset | Oidc / EntraId |
| Audience | Storefront (or Both if Admin returnUrls needed) |
| OIDC discovery URL | https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/v2.0/.well-known/openid-configuration → Fetch |
| Issuer | Exact discovery issuer (includes policy name — pin it; do not use login.microsoftonline.com) |
| Client ID / Secret | B2C app registration |
| Client authentication | Client Secret Post |
| Require PKCE | On (recommended default) |
| Scopes | openid profile offline_access (drop offline_access if the flow rejects it) |
| Subject / Email / Username | sub / email (or emails if tokens only emit the array) / emails or name |
| First / Last name | given_name / family_name (confirm in token) |
| Tenant / Object ID | Often empty on B2C; oid may appear depending on claims — leave blanks if unused |
| Allow multi-tenant issuers | Off (B2C issuer is policy-specific) |
| Public base URL | Same host as redirect URI |
| JIT / Linking | Automatic / Automatic (testing) |
| Enabled | On when Validation = Ready |
emails (array), not email. The plugin accepts emails as an alias automatically. If JIT still fails, set Email claim to emails explicitly and re-test.C. Test
- Incognito →
{PublicBaseUrl}/sso/login/{providerId}or storefront Continue with …. - Complete B2C sign-up / sign-in → confirm Links + Audit + customer email.
| Symptom | Likely cause |
|---|---|
| Discovery 404 / wrong issuer | Policy name typo, or workforce tenant URL instead of b2clogin.com |
redirect_uri mismatch |
App registration redirect ≠ plugin Redirect URI (host or provider id) |
customer_creation_failed |
No usable mailbox — enable Email Addresses application claim; set Email claim to emails if needed |
issuer_mismatch |
Issuer not pinned to discovery (policy changed) or multi-tenant toggle on |
| Works on tunnel, fails on localhost | Public base URL / redirect host mismatch |
D. Limitations and notes (B2C)
- No dedicated B2C preset logo path — catalog may say Azure AD B2C but preset id is still EntraId.
- B2C SAML via custom policies is advanced; prefer OIDC user flows for testing. For SAML use Entra workforce SAML or Generic.
- Social IdPs inside B2C (Google/Facebook) still return through the B2C issuer — configure claims on the user flow, not on Google Cloud.
19. Okta
OIDC Web app and SAML app are separate. Key points: sign-in redirect / ACS must match Public base URL exactly; default AS Access Policy required for OIDC; SAML needs email attribute statements and ACS=/sso/saml/acs/{id} (never /sso/login).
Okta (Preset: Okta) — OIDC and SAML
Trial: developer.okta.com/signup/ (Integrator Free Plan / Developer). Create a test user under Directory → People. Assign that user to every Okta app you create.
localhost and the tunnel in the same flow. Never put the Okta Admin host ({org}-admin.okta.com) in discovery/issuer — use {org}.okta.com.A. OIDC — Okta Web app
- Applications → Create App Integration → OIDC - OpenID Connect → Web Application.
- Grant type: Authorization Code (PKCE on is fine for confidential web apps in this plugin).
- Sign-in redirect URIs (exact, no trailing slash, no
/en/):{PublicBaseUrl}/sso/oidc/callback/{providerId}(example:https://your-tunnel.trycloudflare.com/sso/oidc/callback/12). - Sign-out redirect URIs (optional):
{PublicBaseUrl}/ - Assignments → assign your test user (missing assignment →
access_denied). - Copy Client ID, Client secret, and org domain (
integrator-….okta.comordev-xxxxx.okta.com). - Prefer the default custom authorization server for testing: Issuer
https://{domain}/oauth2/default, Discoveryhttps://{domain}/oauth2/default/.well-known/openid-configuration. Org issuerhttps://{domain}is different — pin whichever discovery returns asissuer.
B. OIDC — Authorization Server access policy (required)
If authorize returns 400 / Policy evaluation failed / access_denied with no matching policy:
- Security → API → Authorization Servers → default → Access Policies.
- Add Policy (e.g.
nopStation OIDC Policy) → Assign to your OIDC client (or All clients) → Active. - Add Rule (e.g.
Allow Authorization Code):- Grant type: Authorization Code
- User: Any user assigned to the app (or your test user/group)
- Scopes: Any scopes while testing (later lock to
openid profile email) - Access: Allowed
- Ensure no higher-priority Deny rule blocks the client.
App Assignments and AS Access Policy are separate — both must allow the user/client.
C. OIDC — plugin (/Admin/SSO/Edit/{id})
| Field | Value |
|---|---|
| Name | e.g. Okta Oidc SSO |
| Protocol / Preset | Oidc / Okta |
| Audience | Storefront (or Both if you need Admin returnUrl=/Admin/...) |
| OIDC discovery URL | https://{domain}/oauth2/default/.well-known/openid-configuration → Fetch OIDC discovery |
| Issuer | Must equal discovery issuer (never *-admin.okta.com) |
| Client ID / Secret | From Okta app (re-paste secret after any decrypt error) |
| Client authentication | Client Secret Post (or Basic if the Okta app requires it) |
| Require PKCE | On (recommended default for Okta web) |
| Scopes | openid profile email |
| Subject / Email / Username | sub / email / preferred_username |
| Groups claim | groups — only after you add a Groups claim on the authorization server |
| Public base URL | Tunnel/public host used in Okta Sign-in redirect URI |
| JIT / Linking | Automatic / Automatic (testing) |
| Enabled | On when Validation = Ready |
D. OIDC test
- Incognito →
{PublicBaseUrl}/sso/login/{providerId}or/en/login→ Continue with Okta… (storefrontreturnUrl, not/Admin/...unless Audience = Both). - Confirm Links + Audit after success.
| Symptom | Likely cause |
|---|---|
Okta 400 redirect_uri must be a Login redirect URI |
URI not listed exactly under Sign-in redirect URIs, or Public base URL / tunnel host changed |
Okta 400 Policy evaluation failed / access_denied |
No Access Policy rule for this client/grant/scopes, or user not assigned |
audience_mismatch on store |
Provider Audience is Storefront-only but login used returnUrl=/Admin/... |
Direct /sso/login/{id} works, button “fails” |
Usually different host or Admin returnUrl; both paths send the same redirect_uri when Public base URL is set |
E. SAML — Okta app
Create a separate SAML 2.0 app (do not reuse the OIDC client).
- Applications → Create App Integration → SAML 2.0.
- In Okta SAML Settings (where you configure the SP):
| Okta field | Must be (from plugin Edit read-only values) |
|---|---|
| Single sign-on URL | {PublicBaseUrl}/sso/saml/acs/{providerId} — ACS, never /sso/login/{id} |
| Audience URI (SP Entity ID) | {PublicBaseUrl}/sso/saml/metadata/{providerId} (or your SP Entity ID if set) |
| Name ID format | EmailAddress (recommended for JIT) |
| Application username |
- Attribute statements (Sign On) — required for JIT customer create:
| Name | Value |
|---|---|
email |
user.email |
firstName |
user.firstName |
lastName |
user.lastName |
login |
user.login (optional; Okta SAML username claim) |
groups |
as needed for group allow lists |
- Assignments → test user.
- User authentication (testing): prefer Password only / Any one factor. Any two factors often breaks the Okta Sign-In widget (“The page has timed out”) and causes a redirect loop back to
/sso/login/{id}. - Open Sign On → Metadata details (or View SAML setup instructions) and copy:
| Okta label | Example shape | Plugin field |
|---|---|---|
| Metadata URL | https://{domain}/app/exk…/sso/saml/metadata |
Federation metadata URL (import) |
| Sign on URL | https://{domain}/app/…/exk…/sso/saml |
SAML SSO endpoint |
| Issuer | http://www.okta.com/exk… |
Issuer and IdP entity ID (same for Okta) |
| Signing Certificate | Active SHA-2 | IdP signing certificate (PEM) |
SAMLRequest often redirects to the app Initiate Login URI (/sso/login/{id}) → auto-POST → Okta again (redirect loop). Always start from {PublicBaseUrl}/sso/login/{providerId}.F. SAML — plugin (/Admin/SSO/Edit/{id})
Recommended: paste Okta Metadata URL into Federation metadata URL → Import IdP from metadata (fills Issuer, SSO endpoint, IdP cert).
| Field | Value |
|---|---|
| Name | e.g. Okta SAML SSO |
| Protocol / Preset | Saml2 / Okta |
| Audience | Storefront (or Both if Admin return URLs needed) |
| Issuer | http://www.okta.com/exk… (Okta Identity Provider Issuer) |
| IdP entity ID | Same as Issuer for Okta |
| SAML SSO endpoint | Okta Sign on URL |
| Single logout URL | Leave blank (Okta “Sign out URL” is not SAML SLO) |
| SP Entity ID | Blank → defaults to metadata URL; must match Okta Audience URI |
| Public base URL | Same host as ACS / Audience |
| Email / Username / Name claims | email / login / firstName / lastName |
| IdP signing certificate | Required (import or paste Active SHA-2 PEM) |
| Allow IdP-initiated SSO | Off unless users launch from the Okta app tile |
| JIT / Linking | Automatic / Automatic (testing) |
| Enabled | On when Validation = Ready |
Register back into Okta: ACS + Audience from the plugin Edit page (read-only Assertion consumer URL / Entity ID).
G. SAML test
- Incognito →
{PublicBaseUrl}/sso/login/{providerId}only (or storefront SSO button with non-Admin returnUrl). - Complete Okta username/password without refreshing the Okta page if it warns about timeout.
- Confirm customer created/linked + Audit.
H. SAML checklist / common errors
| Check / error | Fix |
|---|---|
Loop: Okta /…/sso/saml ↔ /sso/login/{id} |
ACS wrongly set to login URL, or Initiate Login URI + timed-out Sign-In page; fix ACS/Audience; use Password-only auth policy; start from /sso/login/{id} only |
| AuthnRequest ACS/Issuer look correct but still loops | Okta Sign-In “page has timed out” → GET without SAMLRequest → bounce to Initiate Login URI; the plugin throttles rapid restarts and shows a Continue button |
customer_creation_failed |
Okta did not send a usable email — add Attribute Statement email=user.email, set Name ID / Application username to Email; JIT = Automatic |
state_validation_failed on ACS |
IdP-initiated response with Allow IdP-initiated off, or RelayState/transaction expired |
signature_validation_failed |
Missing/wrong IdP signing cert; re-import metadata or paste Active SHA-2 cert |
| Audience / destination mismatch | Okta Audience URI and ACS must match plugin Entity ID and ACS exactly (same Public base URL) |
20. Auth0
OIDC: Domain/Client ID/Secret → plugin; Callback URL → Allowed Callback URLs. SAML: enable Addons → SAML2 Web App (not a separate app type); ACS→Callback, Entity ID→Audience; Usage tab → IdP fields. Client secret is OIDC-only. No default groups — Auth0 Actions required.
Auth0 (Preset: Auth0) — OIDC (primary) / SAML
Trial: auth0.com/signup → Free plan (no card required for basic testing) → create tenant + Database connection + a test user (User Management → Users → Create User, connection typically Username-Password-Authentication). Enable that connection on the application.
{tenant}.{region}.auth0.com (e.g. eu, au) — copy Domain from the app Settings, do not invent the host. Tunnel hosts (e.g. *.trycloudflare.com) change when the tunnel restarts — update Auth0 and the plugin together.Copy direction (both protocols):
| Direction | What |
|---|---|
| Auth0 → plugin | OIDC: Domain, Client ID, Client Secret (+ discovery). SAML: IdP Login URL, Issuer, signing cert / metadata from the add-on Usage tab |
| Plugin → Auth0 | OIDC: read-only Callback URL → Allowed Callback URLs. SAML: ACS → Application Callback URL; Entity ID → Audience |
There is no Auth0 application type named “SAML App”. Create a Regular Web Application, then either configure OIDC under Settings or enable Addons → SAML2 Web App for SAML. Client ID / Client Secret are OIDC only — they are not substitutes for SAML issuer, SSO URL, or certificate.
A. OIDC — Regular Web Application (Auth0 Settings)
- Applications → Create Application → Regular Web Application → Create (e.g.
nopCommerce SSO). - Settings → Application URIs (use values from the plugin Edit page after Save — do not guess paths):
| Auth0 field | Value |
|---|---|
| Application Login URI | Leave blank for basic SP-initiated tests |
| Allowed Callback URLs | Plugin read-only Callback URL: {PublicBaseUrl}/sso/oidc/callback/{providerId} (exact match: scheme, host, port, path, trailing slash) |
| Allowed Logout URLs | {PublicBaseUrl}/ |
| Allowed Web Origins | {PublicBaseUrl} (optional for this server-side code flow) |
| Back-Channel Logout URI | Leave blank unless the plugin implements it |
- Copy Domain, Client ID, Client Secret from Basic Information into the plugin (keep the secret server-side only).
- Advanced Settings → OAuth: OIDC Conformant On (default on modern tenants).
- Connections: enable the Database (or social) connection that contains your test user.
- RP-initiated logout: tenant Settings → Advanced → Login and Logout — enable RP-Initiated Logout End Session Endpoint Discovery if discovery lacks
end_session_endpoint(tenants created before ~Nov 2023).
B. OIDC — plugin (/Admin/SSO/Edit/{id})
| Field | Value |
|---|---|
| Protocol / Preset | Oidc / Auth0 |
| Discovery | https://{Domain}/.well-known/openid-configuration → Fetch (custom domain: use that host) |
| Issuer | Exact discovery issuer (Auth0 often includes a trailing / — must match) |
| Client ID / Secret | From app Settings (Domain → Authority base; secret from Client Secret field) |
| Client authentication | Client Secret Post |
| Require PKCE | On (recommended default) |
| Scopes | openid profile email |
| Subject / Email / Username | sub / email / email (preset username=email) |
| First / Last name | given_name / family_name |
| Groups / Roles / Tenant / Company | Leave empty until Auth0 Actions / custom claims emit them — then paste the exact claim names (namespaced URLs are supported as exact keys) |
| End-session | Filled by Fetch when the tenant publishes it |
| Public base URL | Same host as Callback URL |
| JIT / Linking | Automatic / Automatic (testing) |
| Enabled | On when Validation = Ready |
After Save, copy the plugin’s Callback URL back into Auth0 Allowed Callback URLs if you had not already.
C. OIDC test / errors
- Incognito →
{PublicBaseUrl}/sso/login/{providerId}→ Auth0 Universal Login → Links + Audit. (Optional: Auth0 app Quickstart / Auth0 CLI login to confirm the tenant before plugin wiring.)
| Symptom | Likely cause |
|---|---|
redirect_uri / Callback URL mismatch |
URI not listed exactly under Allowed Callback URLs |
issuer_mismatch |
Trailing slash / custom domain / region host ≠ pinned Issuer |
| Connection disabled / access denied | User’s connection not enabled on the application |
| Groups allow-list deny | No groups claim by default — add Action + set Groups claim |
| Logout stays on Auth0 | end_session missing — enable RP-Initiated Logout discovery, re-Fetch |
D. SAML — Auth0 as IdP (Addons → SAML2 Web App)
Reuse the same Regular Web Application (or create another). Open the application → Addons tab → SAML2 Web App → Settings. Putting the ACS under the main app Allowed Callback URLs alone does not enable SAML assertion issuance — the add-on must be enabled and configured.
- Plugin first: Add new → Protocol Saml2 → Preset Auth0 → Save → copy read-only Assertion consumer URL (ACS), Entity ID, and note SSO login URL (start URL only).
- Auth0 add-on Settings:
| Auth0 field | Value from plugin |
|---|---|
| Application Callback URL | ACS {PublicBaseUrl}/sso/saml/acs/{providerId} — never the SSO login URL /sso/login/{id} |
| Audience | Entity ID {PublicBaseUrl}/sso/saml/metadata/{providerId} (unless custom SP Entity ID) — must match exactly |
| Recipient / Destination (if shown) | Same as ACS |
| NameID format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress (recommended for JIT) |
| Issuer (Auth0 side, if shown) | Leave Auth0 default unless the plugin requires a specific value |
- Attribute mappings (addon JSON / mappings UI) — align with plugin claim fields:
| Plugin claim | Typical Auth0 mapping |
|---|---|
email (or MS emailaddress URI) |
|
| Username | email or nickname |
| First / Last name | given_name / family_name |
| Groups | custom Action claim only |
- Enable / Save the add-on → open the Usage tab → copy IdP Login URL, Issuer, signing certificate, and/or metadata URL/XML into the plugin (Import IdP preferred when available).
- Assign / authorize the Database connection for that application.
SSO login URL ({PublicBaseUrl}/sso/login/{providerId}) is where the shopper starts SSO on nopCommerce. It is not Auth0’s Application Callback URL and must not be pasted into Audience.
E. SAML — plugin
| Field | Value |
|---|---|
| Protocol / Preset | Saml2 / Auth0 |
| After Import / Usage tab | Confirm Issuer (IdP Entity ID), SAML SSO endpoint (IdP Login URL), IdP signing cert |
| Email / Username / Names | email / email / given_name / family_name (adjust to assertion) |
| Allow IdP-initiated | Off unless testing Auth0 app tile / IdP-initiated |
| Public base URL | Same host as ACS / Entity ID |
| Enabled | On when Validation = Ready |
F. Limitations and notes (Auth0)
- No default
groups/roles/company/tenant→ Dynamic B2B needs Auth0 Actions + claim field names. - Custom domains change discovery host — always Fetch after domain change.
- SAML addon attribute names vary; verify with a SAML tracer / Audit if JIT fails.
- Auth0 as SAML SP (enterprise connection inbound) is out of scope for this guide — here Auth0 is the IdP.
- Tunnel URL churn: update ACS, Audience, Allowed Callback URLs, and plugin Public base URL / Entity ID together when the public host changes.
21. Google Workspace
Cloud OAuth (OIDC) and Google Admin custom SAML are separate setups. Both use Preset Google Workspace; choose Protocol Oidc or Saml2 on the plugin provider. Verified with OIDC and SAML.
Google OIDC (Preset: GoogleWorkspace, OIDC)
https://localhost:{port} with a Cloudflare tunnel causes redirect_uri_mismatch or “audit success but not logged in” (cookie on the other host).OIDC setup
A. Google account / Cloud project
- This section is Google OIDC only (Google Cloud OAuth Web client). It does not create a Google Admin custom SAML app — that is Google Workspace SAML and needs a Workspace/Cloud Identity admin.
- OIDC can use a consumer Google account or a Workspace user. With consent External + Testing, add the account as a Test user.
- Open Google Cloud Console and select (or create) your project:
- Open Google Auth Platform → Clients:
console.cloud.google.com/auth/clients
B. OAuth consent screen
- Google Auth Platform → Branding / Audience (consent screen).
- User type:
- Internal — only when the Cloud project is tied to an eligible Workspace/Cloud Identity org; users must be in that org. Does not enable Admin Console SAML.
- External — while Testing, only listed test users (can include personal Gmail). Does not create a Workspace org or SAML app.
- App name: e.g.
nopStation SSO. - Add developer contact email; save.
- If External + Testing: Audience → Test users → Add users. Untested accounts get Access blocked.
C. Create OAuth client
- Clients → Create client (or Create OAuth client).
- Application type: Web application.
- Name: e.g.
nopStation SSO. - Authorized redirect URIs → Add URI — must match the plugin Redirect URI exactly:
{PublicBaseUrl}/sso/oidc/callback/{providerId}
Examples:
- Local:
https://localhost:{port}/sso/oidc/callback/12
- Tunnel:
https://your-tunnel.trycloudflare.com/sso/oidc/callback/12
Copy the read-only Redirect URI from /Admin/SSO/Edit/{providerId} after the provider exists (save once to get an id).
- Create → copy Client ID and Client secret immediately (secret is shown once).
- Clients list: console.cloud.google.com/auth/clients
D. Test user
- Workspace: Admin console → Directory → Users → Add user, or use an existing org user.
- External/Testing: add that email under consent Test users.
- Complete any first-login / 2-Step Verification prompts in a normal browser before SSO testing.
E. Map Google values → /Admin/SSO/Edit/{providerId}
Create provider: Add new → Protocol Oidc → Preset Google Workspace (claims/discovery hints fill automatically). Then:
| Google / known value | Plugin field | Notes |
|---|---|---|
| (your label) | Name | e.g. Google workspace SSO (login button text) |
| (fixed) | Preset | Google Workspace |
| (fixed) | Protocol | Oidc |
| (fixed) | OIDC discovery URL | https://accounts.google.com/.well-known/openid-configuration → click Fetch OIDC discovery |
Discovery issuer |
Issuer | https://accounts.google.com |
| OAuth Client ID | Client ID | ….apps.googleusercontent.com |
| (fixed) | Client authentication | Client Secret Post |
| OAuth Client secret | Client secret | Paste once; leave blank later to keep stored secret |
| Discovery (after Fetch) | Authorization endpoint | https://accounts.google.com/o/oauth2/v2/auth |
| Discovery (after Fetch) | Token endpoint | https://oauth2.googleapis.com/token |
| Discovery (after Fetch) | JWKS URI | https://www.googleapis.com/oauth2/v3/certs |
| Discovery (after Fetch) | UserInfo endpoint | https://openidconnect.googleapis.com/v1/userinfo |
| (none from Google) | OIDC end-session URL | Leave empty (Google does not publish one) |
| Same host as redirect URI | Public base URL | Defaults to store URL; set tunnel URL if Google redirect uses the tunnel |
| Plugin (read-only) | Redirect URI | Paste into Google Authorized redirect URIs — do not invent a different path |
| (recommended default) | Scopes | openid email profile |
| (recommended default) | Subject claim | sub |
| (recommended default) | Email claim | email |
| (recommended default) | Username claim | email |
| (recommended default) | First / Last name | given_name / family_name |
| Workspace hosted domain | Tenant claim | hd only when present in the verified ID token; enforce with Tenant/domain allow list server-side |
| Optional harden | Tenant allow list / domain allow | Your Workspace domain (e.g. contoso.com) if restricting hd |
| (testing) | JIT / Account linking | Automatic / Automatic (testing only — see 14.2) |
| (testing) | Audience | Storefront |
| (testing) | Enabled | On |
Also on /Admin/SSO/Configure: enable SSO; Public Base URL must match the host used in Google redirect and in the browser.
F. Test
- Open the store on the same host as Public base URL (tunnel or localhost — not mixed).
- Incognito →
/en/login→ Continue with Google workspace SSO. - Sign in as a consent test user / Workspace user.
- Confirm
/Admin/SSO/Linksand/Admin/SSO/Audit(sso.signin_succeeded) and/en/customer/infoshows the signed-in customer. - If Error 400: redirect_uri_mismatch: Google client URI ≠ plugin Redirect URI (check provider id and host).
- If audit success but UI still looks logged out: you started SSO on a different host than Public base URL; use one host only (the plugin redirects to the Public base URL when the hosts differ).
SAML setup (Google Admin custom SAML app)
Use this when testing Google Admin → custom SAML app (not Google Cloud OAuth / Google OIDC). Aligns with Google: Set up your own custom SAML app and plugin preset Google Workspace + Protocol Saml2.
| Item | Value |
|---|---|
| Preset | Google Workspace |
| Protocol | Saml2 |
| ACS | {PublicBaseUrl}/sso/saml/acs/{providerId} |
| SP Entity ID | {PublicBaseUrl}/sso/saml/metadata/{providerId} |
| Admin console | admin.google.com/ → Apps → Web and mobile apps |
| Verification status | OIDC verified. SAML follows Google’s documented custom-app setup: run the verification checklist after configuring. |
https://localhost:{port} or a tunnel). Google ACS is browser POST, so localhost often works for SP-initiated testss; still avoid mixing hosts.A. Plugin — create provider first (get ACS / Entity ID)
- nopStation → SSO → Configure: Enable SSO; set Public Base URL; keep emergency local admin on.
- SSO → Identity providers → Add new:
| Field | Value |
|---|---|
| Name | e.g. Google Workspace SAML (storefront button) |
| Protocol | Saml 2 |
| Provider preset | Google Workspace |
| Audience | Storefront |
| Public base URL | Same as Configure |
| JIT / Linking | Automatic / Automatic (testing) |
| Enabled | Off until IdP fields + cert are saved |
- Save → note
{providerId}from/Admin/SSO/Edit/{providerId}. - Copy read-only URLs:
| Plugin field | Path |
|---|---|
| Assertion consumer URL | {PublicBaseUrl}/sso/saml/acs/{providerId} |
| Entity ID | {PublicBaseUrl}/sso/saml/metadata/{providerId} |
| SSO login URL | {PublicBaseUrl}/sso/login/{providerId} |
Leave Service provider entity ID blank unless you need a custom SP Entity ID (blank → metadata Entity ID above).
B. Google Admin — Add custom SAML app (wizard order)
- Open Google Admin → Apps → Web and mobile apps.
- Add app → Add custom SAML app.
- App details: name e.g.
nopStation SSO(optional icon) → Continue. - Google Identity Provider details (do this before SP fields):
- Download IdP metadata (XML file) — Google does not publish a stable public federation metadata URL for custom apps.
- Or copy SSO URL, Entity ID, and download Certificate (X.509, public only).
- Continue.
- Service provider details:
| Google Admin field | Plugin value |
|---|---|
| ACS URL | Assertion consumer URL — must be https://… |
| Entity ID | Plugin Entity ID / SP metadata URL |
| Start URL | Optional; leave empty for SP-initiated tests (or set login URL if Google docs ask) |
| Signed response | Optional; leave default unless your SP requires whole-response signature |
| Name ID format | |
| Name ID | Basic Information → Primary email |
- Continue → Attribute mapping (App attributes are case-sensitive; match SAML Google preset):
| Google Directory attribute | App attribute (plugin claim) |
|---|---|
| Primary email | email |
| First name | firstName |
| Last name | lastName |
Optional groups: map Group membership → set plugin Groups claim to the same App attribute name.
- Finish.
- Open the app → User access → turn ON for Everyone, or the test OU / group / user.
If access is Off, Google shows app_not_configured_for_user (403) — not a plugin bug.
C. Plugin — map Google IdP → /Admin/SSO/Edit/{providerId}
Option A (recommended): Import IdP from metadata → paste the downloaded XML into Federation metadata XML (leave URL empty). Preferred entity ID = Google’s IdP Entity ID if the file has multiple entities.
Option B: Paste manually:
| Google source | Plugin field |
|---|---|
| IdP Entity ID | Issuer and IdP entity ID |
| SSO URL | SAML SSO endpoint |
| Certificate (public) → PEM | Signing certificate → Save certificate |
| Public Base URL | Same host as ACS |
| (testing) | JIT / Linking Automatic; Enabled On when Validation = Ready |
SAML Google Workspace preset defaults (normally leave after choosing preset):
| Plugin field | Value |
|---|---|
| Subject claim | NameID |
| Email / Username | email / email |
| First / Last name | firstName / lastName |
| Tenant claim | hd (only if present; enforce with domain allow list if needed) |
D. Test user & login
- Ensure the Workspace user exists (Directory → Users) and has User access to the SAML app.
- Complete first-login / 2SV in a normal browser if required.
- Incognito →
{PublicBaseUrl}/en/login→ Google Workspace SAML (or open SSO login URL). - Sign in at Google → return authenticated.
- Confirm SSO → Links, SSO → Audit (
sso.signin_succeeded), and/en/customer/info. - Optional IdP-initiated: Google app launcher — enable Allow IdP-initiated on the plugin only if you need that path; re-test issuer/audience.
E. Checklist / common failures
| Check | Pass |
|---|---|
| Protocol Saml2 + Preset Google Workspace | Yes |
ACS / Entity ID host = Public Base URL + correct {providerId} |
Yes |
| Name ID = Primary email / EMAIL | Yes |
Attributes email, firstName, lastName mapped |
Yes |
| IdP signing cert saved; Validation Ready | Yes |
| User access ON for test user/OU | Yes |
| Symptom | Likely cause | Fix |
|---|---|---|
app_not_configured_for_user |
App Off for user/OU | User access → ON |
| Signature validation failed | Wrong/expired cert | Re-download Certificate; Save certificate |
| Email / JIT failed | Name ID or email attribute missing |
Name ID = Primary email; map Primary email → email |
| Wrong ACS / audience | Stale provider id or host | Re-copy ACS/Entity ID from Edit after Save |
| Metadata URL import fails | Google has no public metadata URL | Paste Federation metadata XML from download |
22. Keycloak
A free option for local testing (Docker start-dev). OIDC Roles claim defaults to realm_access.roles. SAML client ID must equal plugin Entity ID; enable Allow private network for localhost.
Keycloak (Preset: Keycloak) — OIDC (primary) / SAML — a free option for local testing
Install (Docker):
docker run -d --name keycloak -p 127.0.0.1:8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:latest start-dev
Bash syntax shown; in PowerShell replace the trailing \ with a backtick (`). Recent Keycloak releases use KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD; the older KEYCLOAK_ADMIN variables are deprecated. The admin / admin credentials are for local testing only.
Open http://localhost:8080 → admin / admin. Create realm nopstation. Create a user (email + password, Email verified = On, Temporary = Off).
A. OIDC client
- Clients → Create client → OpenID Connect → Client ID
nop-sso. - Client authentication On (confidential). Standard flow On.
- Valid redirect URIs:
{PublicBaseUrl}/sso/oidc/callback/{providerId} - Web origins:
{PublicBaseUrl}or+ - Credentials → copy Client secret.
- Protocol mappers (recommended):
- Email, given name, family name (usually present via default scopes).
- Group Membership → Token Claim Name
groups(for group allow lists). - Roles: preset Roles claim is
realm_access.roles(dotted path supported). Or map a flatrolesclaim and set the plugin field to match.
B. OIDC — plugin
| Field | Value |
|---|---|
| Protocol / Preset | Oidc / Keycloak |
| Discovery | http://localhost:8080/realms/nopstation/.well-known/openid-configuration → Fetch |
| Allow private network endpoints | On (testing only — required for localhost / RFC1918) |
| Issuer | Exact discovery issuer (e.g. http://localhost:8080/realms/nopstation) |
| Client ID / Secret | nop-sso / secret |
| Client authentication | Client Secret Post |
| Scopes | openid profile email |
| Subject / Email / Username | sub / email / preferred_username |
| Groups / Roles | groups / flat roles only |
| JIT / Linking | Automatic / Automatic |
| Enabled | On when Validation = Ready |
C. OIDC test
Incognito → /en/login → Keycloak → Links + Audit.
| Symptom | Likely cause |
|---|---|
| Validation / endpoints blocked | Allow private network endpoints Off while using localhost / RFC1918 |
issuer_mismatch |
Browser used hostname but discovery issuer is localhost (or vice versa) — pin one host |
customer_creation_failed |
User Email empty or Email verified Off |
| Roles allow-list deny | Default Roles claim is realm_access.roles (dotted); map Groups groups for allow lists |
| PKCE error on authorize | Turn Require PKCE Off only if the confidential client rejects code_challenge |
D. SAML client (separate from OIDC)
- Plugin first: Saml2 + Keycloak → Save → copy ACS + Entity ID.
- Keycloak Clients → Create → Client type SAML → Client ID = plugin Entity ID (exact).
- Login settings: Valid redirect URIs / Assertion Consumer Service POST URL =
{PublicBaseUrl}/sso/saml/acs/{providerId}(ACS, never/sso/login/{id}). - NameID format: email (or username if you map email via attributes).
- Client scopes / mappers: add attribute mappers so assertion contains:
| Name | User attribute / property |
|---|---|
email |
|
username |
Username |
firstName |
First name |
lastName |
Last name |
groups |
Group list (optional) |
Role |
Realm role list (optional; matches SAML Roles claim preset) |
- Realm → Realm settings → Endpoints → SAML 2.0 Identity Provider metadata → plugin Federation metadata URL → Import IdP (or paste SSO URL + realm signing cert).
- If Keycloak requires signed AuthnRequests: enable Sign AuthnRequests on the plugin and upload SP signing cert/key; import SP metadata into the Keycloak client.
E. SAML — plugin
| Field | Value |
|---|---|
| Protocol / Preset | Saml2 / Keycloak |
| After Import | Issuer (realm), SSO endpoint, IdP signing cert |
| Email / Username / Names / Groups / Roles | email / username / firstName / lastName / groups / Role |
| Allow IdP-initiated | Off unless testing IdP-initiated |
| Allow private network | On for local HTTP Keycloak |
| Public base URL | Reachable host Keycloak can POST ACS to (localhost OK for browser-only SAML tests) |
| Enabled | On when Validation = Ready |
F. Limitations and notes (Keycloak)
- Roles claim default OIDC is
realm_access.roles(dotted path). Client roles underresource_access.{client}.rolesneed a manual Roles claim path. - Prefer Group Membership mapper named
groupsfor allow lists. - HTTP Keycloak + HTTPS store can break cookies / mixed content; use the same scheme for both, or tunnel both.
start-devis for testing only — not a production Keycloak topology.
23. OneLogin
Use SAML Custom Connector (Advanced) for SAML (not vendor apps). Issuer URL is the Federation metadata URL. ACS must be /sso/saml/acs/{id}. Assign users from Users → Applications if the app Users tab has no Add button — otherwise OneLogin shows Access Denied. Verified with OIDC and SAML.
OneLogin (Preset: OneLogin) — OIDC / SAML
Trial: www.onelogin.com/developer-signup (or vendor trial). Create an Active user under Users and assign that user to each app you test (OIDC and SAML are separate apps).
localhost and the tunnel.Common pitfalls: OIDC access_denied (user not assigned), invalid_client (secret / Basic vs POST), SAML Access Denied (/access_denied?id=… — user not assigned), ACS set to /sso/login causing loops, and missing email attributes → customer_creation_failed.
A. OIDC app (OneLogin Admin)
- Applications → Add App → OpenId Connect (OIDC) → Save.
- Configuration tab:
- Login Url =
{PublicBaseUrl}/sso/login/{providerId}(not the store homepage — portal launch must hit SP start so a state transaction exists). - Redirect URI's =
{PublicBaseUrl}/sso/oidc/callback/{providerId}(HTTPS; exact match to plugin Redirect URI). - Post Logout Redirect URIs =
{PublicBaseUrl}/(optional).
- Login Url =
- SSO tab:
- Enable OpenID Connect = On.
- Copy Client ID, Client Secret, Issuer URL =
https://{subdomain}.onelogin.com/oidc/2. - Application Type = Web.
- Token Endpoint Authentication Method = POST (recommended for this plugin) or Basic — must match plugin Client authentication.
- Open Well-known Configuration to confirm
authorization_endpoint/token_endpointunder/oidc/2/.
- Users tab (or Access via Role): assign the test user to this app. Without assignment →
access_denied/ End-user does not have access to this application (often with no OneLogin password page if a session already exists). - Token timeout (Access / Refresh minutes): optional. This plugin uses the access token only at login (UserInfo); it does not refresh tokens or tie the nopCommerce cookie to access-token lifetime. Leave defaults.
B. OIDC — plugin (/Admin/SSO/Edit/{id})
| Field | Value |
|---|---|
| Protocol / Preset | Oidc / OneLogin |
| Public base URL | Same host as Redirect URI / browser (e.g. tunnel origin) |
| Discovery | https://{subdomain}.onelogin.com/oidc/2/.well-known/openid-configuration → Fetch |
| Issuer | https://{subdomain}.onelogin.com/oidc/2 (exact) |
| Client ID / Secret | From SSO tab — re-paste secret after any Regenerate; blank save keeps old secret |
| Client authentication | Client Secret Post if OneLogin = POST; Client Secret Basic if OneLogin = Basic |
| Require PKCE | Off for confidential Web + Client Secret (OneLogin often rejects authorize when PKCE is on with POST/Basic) |
| Scopes | openid profile email (+ groups if testing allow lists) |
| Username claim | preferred_username (confirm in token) |
| Groups claim | groups only if emitted |
| Enabled | On when Validation = Ready |
C. Test
- Browse the store on the same host as Public base URL (do not mix localhost and tunnel).
- Incognito →
{PublicBaseUrl}/en/loginor{PublicBaseUrl}/sso/login/{providerId}. - Confirm Links + Audit (
sso.signin_succeeded) and/en/customer/info.
D. SAML — choose the connector
In Applications → Add App, search for SAML. For nopStation:
| Goal | Select |
|---|---|
| SAML login / SSO only | SAML Custom Connector (Advanced) (recommended) |
| SAML + SCIM provisioning | SCIM Provisioner with SAML (only if testing SCIM too) |
| OIDC login | Separate OpenId Connect (OIDC) app (OneLogin OIDC) — not a SAML connector |
Avoid SAML 1.1 connectors and vendor-specific apps (Adobe, DocuSign, ChatGPT, etc.).
E. SAML — OneLogin Configuration tab (SP settings from the plugin)
Create the plugin provider first (Protocol Saml2, Preset OneLogin) so Edit shows read-only URLs, then paste into OneLogin Configuration:
| OneLogin Configuration field | Plugin value |
|---|---|
| RelayState | Leave blank |
| Audience (EntityID) | {PublicBaseUrl}/sso/saml/metadata/{providerId} (plugin Entity ID) |
| Recipient | Same as ACS |
| ACS (Consumer) URL | {PublicBaseUrl}/sso/saml/acs/{providerId} — never /sso/login/{providerId} |
| ACS (Consumer) URL Validator | Escaped ACS regex, or .* for testing |
| Single Logout URL | {PublicBaseUrl}/sso/saml/slo/{providerId} (optional) |
| Login URL | {PublicBaseUrl}/sso/login/{providerId} (required when initiator = Service Provider) |
| SAML initiator | Service Provider for /sso/login/{id} tests |
| SAML nameID format | |
| SAML issuer type | Specific |
| SAML signature element | Response or Both |
| Encrypt assertion | Off unless SP encryption cert is configured in the plugin |
| SAML not valid before / on or after | 3 / 3 (minutes) is fine for testing |
| SAML sessionNotOnOrAfter | 1440 (default) |
Example (provider id 12, Cloudflare tunnel):
- Audience =
https://….trycloudflare.com/sso/saml/metadata/12 - ACS / Recipient =
https://….trycloudflare.com/sso/saml/acs/12 - Login URL =
https://….trycloudflare.com/sso/login/12
F. SAML — OneLogin SSO tab (IdP values → plugin)
| OneLogin SSO field | Plugin field / action |
|---|---|
Issuer URL (e.g. https://app.onelogin.com/saml/metadata/{app-uuid}) |
Federation metadata URL (import) and Issuer / IdP entity ID |
| SAML 2.0 Endpoint (HTTP) | SAML SSO endpoint |
| SLO Endpoint (HTTP) | Single logout URL (optional) |
| X.509 Certificate → View Details | IdP signing certificate (PEM) |
| SAML Signature Algorithm | Prefer SHA-256 (not SHA-1) |
Recommended: paste Issuer URL into plugin Federation metadata URL → Import IdP from metadata (fills Issuer, SSO endpoint, cert). Leave Preferred entity ID blank. Allow private-network metadata URL = Off for public OneLogin hosts. Federation metadata XML = only if URL import fails.
Manual plugin fields if not importing:
| Plugin field | Value |
|---|---|
| Protocol / Preset | Saml2 / OneLogin |
| Public base URL | Tunnel/public host used in OneLogin ACS |
| Issuer / IdP entity ID | Issuer URL from SSO tab |
| SAML SSO endpoint | SAML 2.0 Endpoint (HTTP) |
| Email / Username / Name claims | Often short email / username / firstname / lastname — verify on Parameters (preset also documents User.Email style names) |
| JIT / Linking | Automatic / Automatic (testing) |
| Allow IdP-initiated SSO | Off unless testing portal launch without /sso/login |
G. SAML — assign user (required)
OneLogin returns Access Denied / https://{subdomain}.onelogin.com/access_denied?id={appId} when the user is not assigned to this SAML app.
- Ensure an Active user exists under directory Users.
- Prefer assignment from the user side when the app Users tab has no Add button:
- Users → open test user → Applications → + / Add App → select this SAML connector → Save.
- Or Applications → Access → attach a role that includes the user.
- Confirm the user → Applications list shows the SAML app.
H. SAML — Parameters (email for JIT)
On Parameters, map NameID / email (or User.Email) so the assertion includes a usable mailbox. Missing email → plugin customer_creation_failed.
I. SAML test
- Incognito →
{PublicBaseUrl}/sso/login/{providerId}(or?forceSso=trueafter a cooldown page). - Sign in as the assigned OneLogin user.
- Do not refresh a timed-out OneLogin page — restart from
/sso/login/{id}. - Confirm Links + Audit and
/en/customer/info.
J. common errors (OIDC + SAML checklist)
| Symptom / Audit reason | Cause | Fix |
|---|---|---|
OneLogin Access Denied / /access_denied?id=… |
User not assigned to this SAML (or OIDC) app | Assign via user → Applications or Access roles; retry Incognito as that user |
| App Users tab empty / no Add User | UI limitation on some trials | Assign from Users → {user} → Applications instead |
access_denied on OIDC callback |
Same assignment issue on the OIDC app | Assign user to the OIDC app specifically |
| Loop / “Sign-in already started” | ACS set to /sso/login, or IdP timeout bounce; plugin cooldown |
ACS must be /sso/saml/acs/{id}; use Retry / ?forceSso=true; fix Configuration |
customer_creation_failed |
No email in assertion | Parameters + NameID Email; JIT Automatic |
invalid_client / client authentication failed |
OIDC secret / POST vs Basic mismatch | Match Token Endpoint Auth Method ↔ plugin Client authentication; re-paste secret |
token_exchange_failed |
Secret or redirect_uri mismatch | Exact Redirect URI; Audit details |
oidc_provider_error |
OneLogin returned error on callback | Fix IdP message (assignment, etc.) |
| Access Token timeout minutes | Does not control store session | Leave OneLogin defaults |
K. Limitations and notes
- Claim name mismatch on SAML (
User.*vs short names) — always check Parameters. - Groups often require extra Parameters; empty groups → allow-list deny.
- Custom domain changes discovery host — always Fetch after change.
- SCIM is separate from SAML login; use a SCIM+SAML connector only when testing provisioning.
24. PingOne / PingFederate
PingOne OIDC is the cloud trial path; PingFederate is typically SAML. Copy region discovery from the console. SAML email attribute is often mail (preset default).
PingOne / PingFederate (Preset: Ping)
Trial: www.pingidentity.com/en/try-ping.html (PingOne). Prefer PingOne OIDC for cloud trials; PingFederate needs a test or evaluation VM. Preset Ping is dual-protocol (OIDC default).
auth.pingone.com / .eu / .asia / .ca / .sg). Guessing the region → discovery 404. Use one public HTTPS origin for callback/ACS and the browser.A. PingOne OIDC
- Create a Worker / population + test user; assign the user to the application.
- Applications → Add → OIDC Web App (or OIDC + Authorization Code).
- Redirect URIs =
{PublicBaseUrl}/sso/oidc/callback/{providerId}. - Enable Authorization Code; create/copy Client Secret.
- Open Configuration / URLs and copy discovery exactly:
https://auth.pingone.{region}/{envId}/as/.well-known/openid-configuration
- Issuer shape:
https://auth.pingone.{region}/{envId}/as - Attribute / resource scopes: ensure
email(and profile names) are released to the token / UserInfo.
B. OIDC — plugin
| Field | Value |
|---|---|
| Protocol / Preset | Oidc / Ping (use Generic only if claim names diverge wildly) |
| Discovery | Exact URL from PingOne console → Fetch |
| Issuer | Exact discovery issuer |
| Client ID / Secret | From app |
| Client authentication | Client Secret Post (match Ping app) |
| Require PKCE | On unless Ping app rejects it |
| Scopes | openid profile email |
| Subject / Email / Username | sub / email / preferred_username (verify token) |
| Groups / Roles | Configure Ping claim mapping first; defaults groups / roles |
| Public base URL | Same host as redirect URI |
| Enabled | On when Validation = Ready |
C. PingFederate / PingOne SAML
- Plugin first: Saml2 + Ping → copy ACS + Entity ID.
- Create SAML SP connection; ACS = plugin ACS (POST); Entity ID = plugin Entity ID.
- Prefer IdP metadata export → plugin Import IdP, or paste Issuer + SSO URL + signing cert.
- Attribute contract — confirm against the assertion. Ping SAML preset defaults:
| Plugin field | Preset default | Often seen instead |
|---|---|---|
mail |
email |
|
| Username | uid |
userPrincipalName |
| First / Last | givenName / sn |
firstName / lastName |
| Groups / Roles | memberOf / Role |
contract-specific |
- Enable Sign AuthnRequests + upload SP signing cert/key when Ping requires signed requests.
- Assign the test user / group to the SP connection.
D. Test / errors
| Symptom | Likely cause |
|---|---|
| Discovery 404 | Wrong region host or env id |
| Claims look SAML-shaped on OIDC form | Protocol left on Saml2 — switch to Oidc and re-apply preset / Fetch |
customer_creation_failed (SAML) |
Contract uses mail but Email claim was changed to email (or vice versa) |
| Signature / AuthnRequest rejected | Sign AuthnRequests Off while Ping requires signed requests |
E. Limitations and notes
- PAR / DPoP / PingOne advanced OAuth features are not used (authorization code + optional PKCE only).
end_sessionis often…/as/signoff— register post-logout URL on Ping when testing RP logout.- PingFederate attribute contracts are highly custom — treat presets as hints, not guarantees.
25. Microsoft ADFS
SAML only (no WS-Fed). Microsoft claim URIs are the preset defaults. ADFS must reach a public ACS host — localhost on a laptop is usually unreachable from the ADFS VM.
ADFS (Preset: Adfs, SAML only)
Test setup: Windows Server with AD DS + AD FS (Azure VM is fine). Create [email protected]. No public SaaS trial. Preset Adfs appears only for Protocol Saml2.
https://localhost:… on the developer PC is unreachable from a remote ADFS VM.A. Relying Party Trust (SAML)
- Plugin first: Saml2 + Adfs → Save → copy Entity ID + ACS.
- AD FS Management → Relying Party Trusts → Add.
- Identifier = plugin Entity ID (
{PublicBaseUrl}/sso/saml/metadata/{providerId}or custom SP Entity ID). - Endpoint: SAML Assertion Consumer → POST →
{PublicBaseUrl}/sso/saml/acs/{providerId}(never/sso/login/{id}). - Optional: SAML Logout endpoints if testing SLO.
- Issuance transform rules must emit claim types that match the Adfs preset (Microsoft URIs), or change plugin claim fields to match your rules:
| Plugin field | Default claim type |
|---|---|
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress |
|
| Username | …/upn |
| First / Last | …/givenname / …/surname |
| Groups / Roles | http://schemas.microsoft.com/ws/2008/06/identity/claims/groups / …/role |
FriendlyName short names also resolve (plugin indexes Name and FriendlyName).
- Export Token-signing certificate (Base64) → plugin IdP signing certificate (or import metadata).
- Federation metadata:
https://{adfs-host}/FederationMetadata/2007-06/FederationMetadata.xml→ Import IdP. If private CA / TLS fails, download XML on the ADFS host and paste XML.
B. Plugin
| Field | Value |
|---|---|
| Protocol / Preset | Saml2 / Adfs |
| After Import | Issuer (http://{adfs-host}/adfs/services/trust), SSO endpoint, cert |
| Sign AuthnRequests | On when RP requires signed requests + upload SP signing cert/key |
| Want assertions signed / encrypted | Match ADFS policy; upload SP decryption key if assertions are encrypted |
| Allow IdP-initiated | Off unless testing ADFS app launcher |
| Public base URL | HTTPS host ADFS can reach |
| Enabled | On when Validation = Ready |
C. OIDC on ADFS
Only if the farm exposes OIDC (newer AD FS + Application Groups). There is no Adfs+OIDC preset — use Generic + OIDC with the farm discovery URL. Most setups should stay on SAML.
D. Test / errors
| Symptom | Likely cause |
|---|---|
| ACS unreachable / timeout | ADFS cannot reach Public base URL (localhost on laptop) |
signature_validation_failed |
Wrong/expired token-signing cert; re-import metadata |
customer_creation_failed |
Issuance rules omit emailaddress; NameID not email-shaped |
| Claim URI mismatch | Rules emit short names only — either add URI types or set plugin fields to FriendlyName/short names |
| Metadata URL import fails | Private CA — paste FederationMetadata XML |
E. Limitations and notes
- WS-Federation unsupported — SAML 2.0 or OIDC only.
- Response signing vs assertion signing policies must match what the plugin validates.
- ADFS claim rules (LDAP rules) are the most common source of setup problems — inspect one assertion to confirm the claim types.
26. JumpCloud
Dual preset: SAML default, OIDC via Protocol switch. SAML IdP Entity ID is immutable after create. Bind users to the app or access fails.
JumpCloud (Preset: JumpCloud) — SAML (default) / OIDC
Trial: jumpcloud.com/ → Admin Portal. Create a user; bind the user to the SSO app. Use the correct regional admin URL if the org is not US-hosted.
A. Custom SAML
- Plugin first: Saml2 + JumpCloud → copy Entity ID + ACS.
- Access → SSO Applications → + Add New Application → Custom Application → Configure SSO with SAML.
- Display label → Save → Configure.
- SP Entity ID = plugin Entity ID; ACS URL =
{PublicBaseUrl}/sso/saml/acs/{providerId}. - Optional: upload SP metadata from
{PublicBaseUrl}/sso/saml/metadata/{providerId}. - Attribute mapping (matches JumpCloud SAML preset):
email,firstname,lastname,username; groups oftenmemberOfor custom — set plugin Groups claim to match. - Download IdP certificate / metadata → plugin Import IdP or paste cert + SSO URL + Issuer (IdP Entity ID).
- Bind user / group to the application (missing bind → JumpCloud access error).
B. SAML — plugin
| Field | Value |
|---|---|
| Protocol / Preset | Saml2 / JumpCloud |
| Issuer / IdP entity ID | JumpCloud IdP Entity ID |
| SAML SSO endpoint | JumpCloud SSO URL |
| Signing certificate | JumpCloud IdP public cert |
| Email / Username / Names / Groups | email / username / firstname / lastname / memberOf |
| Allow IdP-initiated | Off unless testing User Portal tile |
| Enabled | On when Validation = Ready |
C. OIDC (Preset JumpCloud, Protocol Oidc)
- Add Custom Application → Configure SSO with OIDC (separate app from SAML).
- Redirect URIs =
{PublicBaseUrl}/sso/oidc/callback/{providerId}. - Client Authentication = Client Secret POST (or None + keep plugin Require PKCE On).
- Login URL (optional) =
{PublicBaseUrl}/sso/login/{providerId}for User Portal. - Subject Claim in JumpCloud: default JumpCloud User ID → plugin Subject claim
sub. - Copy Client ID, Client Secret, Discovery URL from the SSO tab (often
https://oauth.id.jumpcloud.com/.well-known/openid-configuration— confirm in console). - Plugin: Protocol Oidc, Preset JumpCloud → Fetch discovery → paste credentials. Username claim preset =
email.
D. Test / errors
| Symptom | Likely cause |
|---|---|
| User cannot open app | User/group not bound to the SSO application |
| Wrong IdP Entity ID forever | SAML IdP URL immutable — recreate app if Entity ID was wrong |
customer_creation_failed |
Attribute mapping omitted email; NameID not email |
| OIDC discovery wrong host | Copied a sample URL — use the app SSO tab value |
| Groups allow-list deny | memberOf vs custom group attribute — match assertion |
E. Limitations and notes
- Group attribute naming varies by app template.
- JumpCloud SCIM provisioning is configured separately from SSO login.
27. Salesforce (as identity provider)
No dedicated preset — catalog maps to Generic + SAML. Enable Salesforce Identity Provider, then Connected App ACS/Entity ID from the plugin.
Salesforce as IdP (Preset: Generic, SAML)
Trial: developer.salesforce.com/signup → Developer Edition. There is no dedicated Salesforce SSOPreset — catalog entry maps to Generic.
A. Enable Salesforce Identity Provider
- Setup → Identity → Identity Provider → Enable; download the IdP certificate.
- Note the Salesforce IdP Entity ID / SSO URL from the Identity Provider page (or metadata).
B. Connected App (Service Provider)
- Plugin first: Protocol Saml2, Preset Generic, catalog Salesforce or Custom IDP → Save → copy ACS + Entity ID.
- Setup → App Manager → New Connected App (or Enable IdP for an existing Connected App):
- Entity ID = plugin Entity ID
- ACS URL =
{PublicBaseUrl}/sso/saml/acs/{providerId}(HTTP-POST) - Subject Type / NameID: Email or Federation ID (align with plugin Subject / Email claims)
- Map custom attributes so the assertion includes a mailbox the plugin can read (
email, or set Email claim to the Salesforce attribute Name). - Profiles / Permission Sets: grant the Connected App to the test user.
C. Plugin
| Field | Value |
|---|---|
| Protocol / Preset | Saml2 / Generic |
| Import | Salesforce IdP metadata URL or paste Issuer + SSO + cert |
| Email / Username / Names | Match Connected App attribute Names (often email / Federation ID) |
| Allow IdP-initiated | On only if users launch from Salesforce App Launcher |
| Public base URL | HTTPS host Salesforce can POST to |
| Enabled | On when Validation = Ready |
D. Test / errors
| Symptom | Likely cause |
|---|---|
| Insufficient Privileges / app not authorized | Profile/Permission Set missing Connected App access |
customer_creation_failed |
Subject is Federation ID but Email claim empty — map email attribute |
| Signature failures | Wrong/rolled IdP cert — re-download from Identity Provider |
| ACS rejected | Connected App ACS ≠ plugin ACS (trailing slash / http vs https) |
E. Limitations and notes
- Salesforce as SP (Salesforce login via external IdP) is a different product surface — this section is Salesforce as IdP only.
- OIDC via Salesforce is uncommon for this plugin path; prefer SAML Generic.
28. Generic / custom identity provider
Standards-compliant catch-all (Shibboleth, ForgeRock, Duo, WSO2, …). Catalog logos are not verified integrations. Prefer first-class presets when available (including JumpCloud OIDC).
Generic / Custom IDP and catalog vendors
Use for Shibboleth, ForgeRock/OpenAM, CyberArk, SiteMinder, FusionAuth, SimpleSAMLphp, Duo SSO, WSO2, Gluu, SURFconext, ClassLink, Absorb LMS, WordPress-as-IdP, Salesforce (section 27), and any other provider without a dedicated preset. (JumpCloud OIDC now has a first-class dual preset — prefer JumpCloud OIDC over Generic.)
A. OIDC
- Obtain Client ID, Client Secret, discovery URL (or Auth / Token / JWKS / Issuer manually).
- Plugin: Protocol Oidc, Preset Generic → Discovery → Fetch OIDC discovery.
- Pin Issuer to discovery
issuer; set Email / Username / Groups from a decoded ID token. - Allowlist redirect URI exactly; match Client Secret Post vs Basic vs None+PKCE.
- PKCE S256 is sent when Require PKCE is On — IdP must accept
code_challenge. - Confidential client (secret) or Private Key JWT / None+PKCE as configured — no silent public-client fallback beyond those options.
- Nested claims: dotted paths work (e.g.
realm_access.roles). Arrays such as B2C-styleemailsresolve to the first usable mailbox.
B. SAML
- Protocol Saml2, Preset Generic.
- Prefer Import IdP from federation metadata (URL or XML). If URL fails (BOM, TLS, auth wall), paste XML.
- On IdP: register SP Entity ID + ACS (+ SLO) from plugin SP URLs / SP metadata. ACS must be
/sso/saml/acs/{id}— never/sso/login/{id}. - Attribute Name and FriendlyName both resolve — Shibboleth long URIs or short FriendlyNames work.
- NameID format: align EmailAddress / Persistent / Transient with IdP; Transient needs a stable Subject claim mapping plus a separate Email attribute for JIT.
- Encrypted assertions: upload SP decryption cert/key; signed AuthnRequests: upload SP signing cert/key.
C. Generic checklist
- Validation = Ready (replace all
{placeholder}hints before enable) - Login → Links + Audit success
- Email claim present for JIT (or NameID email-shaped)
- Groups claim if Dynamic B2B / allow lists used
- Optional: logout (OIDC end_session or SAML SLO), IdP-initiated (Allow IdP-initiated On)
D. Limitations and notes
- Catalog logo ≠ verified integration.
- Artifact binding, SOAP SLO, WS-Fed, PAR, DPoP, JWE — not supported.
- Object-valued UserInfo JSON properties are retained as raw JSON for dotted paths; non-scalar nested objects are not JIT fields by themselves.
Need help setting up SSO?
Book a session with the nopStation team to walk through your identity provider, store setup and role mapping.















