Configure external identity providers (LDAP and OIDC) for HTML5 and Rich Client operator login.
Home → Technical Reference → Platform Modules Reference → Security Module Reference → Security Designer UI Reference → Identity Providers
Security Identity Providers (Reference): configure external authentication mechanisms — LDAP directory servers and OpenID Connect (OIDC) identity providers — that the runtime consults to resolve a user's identity at login time. Each row in this table is a pluggable authentication mechanism.
Identity Providers provide:
LDAP and Active Directory authentication (RFC 4511) — replaces the legacy single-server SecurityEnableLDAP configuration.
OpenID Connect (OIDC) authentication for HTML5, WPF Rich Client, and Smart Client operator login.
Per-provider DefaultPolicy that maps the authenticated user to one of the solution's Permission Groups.
Diagnostic counters and last-error tracking, surfaced at runtime via @Security.IdentityProvider.<Name>.
Zero-modification path for PIV and smartcard authentication — configure an OIDC row pointing at a PIV-aware IdP.
An identity provider's only job is to answer who is logging in. Once identity is resolved, every downstream concern — session lifetime, Permission Group binding, password and e-sign policies, audit trail, runtime authority — stays with the platform's existing Security machinery.
What an IdP row configures: how to validate credentials against an external system, and which Permission Group the resolved user receives.
What an IdP row does NOT configure:
Silent-login or kiosked auto-login — scripted at the customer's LogOn Display CodeBehind via @Security.LogOnWithTokenAsync(providerName, idToken). The IdP table holds how to validate credentials, not which credentials to silently submit.
Session minting or browser session state — owned by the platform's HTTP layer. The OIDC callback handler resolves identity and hands off via a one-time GUID; the standard /start flow mints the operator session.
Multi-factor authentication, conditional access, device posture, anomalous-login detection — IdP-delivered. The IdP enforces these; the platform receives the resolved identity after the IdP applied them.
Audit and compliance posture — Workspace-scoped. See Security Module Reference for the audit story per Workspace.
The benefit of this layering: every audit, permission, e-sign, session-timeout, and password-policy mechanism continues to work unchanged regardless of which IdP a user signed in through. Customers swap IdPs without touching their Permission Groups, Policies, or Displays.
Access at Security → Identity Providers.
Property |
Description |
Required |
Notes |
|---|---|---|---|
Name |
Unique identifier for the identity provider. Appears on the login screen and in audit references. |
Yes |
Engineer-defined, for example |
AuthType |
Authentication standard the provider implements. |
Yes |
Dropdown: |
Active |
Provider participates in authentication when true. |
No (default |
At most one Active row of |
AuthOptions |
Packed |
No |
Designer edits this through a type-dispatched dialog — you do not hand-edit the packed string. |
Description |
Documentation of usage and purpose — which IdP server, which user population, when it was configured. |
No |
|
Category |
Classification group for organizing identity providers. |
No |
|
The discriminator column is AuthType (specific to this table), not the generic Type column reused across many tables — same every-column-unique discipline as SecuritySecrets.SecretType.
AuthOptions is a Key=Value;Key=Value packed string. The Designer's edit dialog presents named fields per AuthType and writes the packed form on save; you only handle the packed string directly when scripting or inspecting.
Key |
Description |
Required |
|---|---|---|
|
LDAP server URL (e.g., |
Yes |
|
Name of the SecurityPermissions group applied to authenticated users when no group-name match is found. Empty falls through to the platform's default behavior. |
No |
Example LDAP AuthOptions:
Server=ldaps://ad.corp.local:636;DefaultPolicy=Operators |
Key |
Description |
Required |
|---|---|---|
|
IdP discovery URL — the base of |
Yes |
|
OAuth 2.0 client_id registered at the IdP for this FrameworX deployment. |
Yes |
|
|
Yes for confidential clients |
|
OAuth redirect URI registered at the IdP. Must end in |
Yes |
|
Comma-separated OAuth scopes. Standard set: |
Yes |
|
Name of the OIDC claim whose value becomes the FrameworX username. Common: |
Yes |
|
Name of the OIDC claim whose value list maps to Permission Group names. Common: |
No |
|
Permission Group applied when no group claim matches an existing SecurityPermissions name. Empty falls through to platform default. |
No |
Example OIDC AuthOptions:
Authority=https://keycloak.corp.local/realms/factory;ClientId=fwx-runtime;ClientSecretRef=/secret:KeycloakClientSecret;RedirectUri=https://factory.corp.local/oidc/callback;Scopes=openid,profile,email,groups;UsernameClaim=preferred_username;GroupsClaim=groups;DefaultPolicy=Operators |
A single AuthType=OIDC row serves three client paths — the configuration is identical for all three; the platform handles the differences transparently.
Operator opens the LogOn Display in a browser.
Operator clicks the Sign in with SSO button and picks an Identity Provider from the dropdown.
The Display CodeBehind navigates the browser to /oidc/start?provider=<Name>&returnUrl=/.
The platform redirects to the IdP. Operator authenticates (password, MFA, PIV, WebAuthn — whatever the IdP enforces).
IdP redirects back to /oidc/callback. The platform validates the token, resolves identity, and 302-redirects the browser to the LogOn Display with a one-time identityToken GUID.
The Display CodeBehind reads @Client.QueryParams["identityToken"] and calls @Security.LogOnWithTokenAsync(providerName, identityToken).
Session is bound, @Security.CurrentUser updates, normal operator displays open.
The same flow, adapted per RFC 8252 (OAuth 2.0 for Native Apps): the client opens the operator's system browser (not an embedded WebView — enterprise IdPs reject those) and listens on a loopback HTTP endpoint for the redirect.
Operator clicks Sign in with SSO on the Rich Client LogOn Display.
Rich Client opens the system default browser to /oidc/start?provider=<Name>&returnUrl=http://127.0.0.1:<port>/handoff.
Operator authenticates against the IdP in the system browser.
The IdP redirect lands on the loopback /handoff endpoint that the Rich Client is listening on.
Rich Client extracts the identityToken GUID, hands it to the orchestrator, and the session is bound — same @Security.LogOnWithTokenAsync path as the browser flow.
Native flow is available on Rich Client and Smart Client (Windows + WPF). It is not available, and not needed, on the HTML5 Web Client, which already has a browser.
LDAP rows have no callback flow. The user types username and password into the LogOn Display; the platform forwards the credentials to the configured LDAP Server; on success the resolved user receives the row's DefaultPolicy (or a matched Permission Group).
Field | Value |
|---|---|
Name |
|
AuthType |
|
Active |
|
AuthOptions |
|
Description | Corporate Active Directory for factory operators |
Register an application in Entra ID; note the Application (client) ID and Directory (tenant) ID.
Add a Web redirect URI: https://factory.corp.local/oidc/callback.
Generate a client secret; store it in Security → Secrets as EntraIDClientSecret.
In Security → Identity Providers, create a row:
Field | Value |
|---|---|
Name |
|
AuthType |
|
Active |
|
AuthOptions |
|
In Keycloak, create a realm (e.g., factory).
Create a client fwx-runtime with client authentication on, redirect URI https://factory.corp.local/oidc/callback.
Copy the generated client secret; store it in Security → Secrets as KeycloakClientSecret.
In Security → Identity Providers, create a row pointing at the Keycloak realm:
Field | Value |
|---|---|
Name |
|
AuthType |
|
Active |
|
AuthOptions |
|
PIV is delivered through an OIDC IdP that supports certificate-based authentication (Entra ID with CBA, AD FS with smartcard, login.gov, or any OIDC-compliant IdP fronting a PIV PKI). Configure an AuthType=OIDC row pointing at the PIV-aware IdP — no special FrameworX configuration is needed. The IdP enforces the PIV cert; FrameworX receives the resolved identity.
When the OIDC IdP includes a groups claim in the ID token (per the GroupsClaim configuration), FrameworX iterates each group name in order and matches it case-exactly against the names of SecurityPermissions groups in the solution.
The first match wins. If no group name matches, the row's DefaultPolicy applies. If DefaultPolicy is empty, the platform's default behavior applies.
Practical mapping pattern: name your Permission Groups in FrameworX to match the IdP's group names exactly. Customers commonly create groups in their IdP named Operators, Engineers, Supervisors to match Permission Groups of the same names; then no per-provider mapping configuration is needed.
LDAP-side group mapping follows the same rule against the LDAP user's group memberships.
Each Identity Provider exposes runtime metrics readable from scripts and Display CodeBehind via @Security.IdentityProvider.<Name>:
Property |
Type |
Meaning |
|---|---|---|
| DateTime | Timestamp of the most recent successful auth via this provider. |
| DateTime | Timestamp of the most recent auth failure. |
| String | Diagnostic message from the most recent failure (IdP error text, certificate failure, JWKS fetch error, etc.). |
| Integer | Count of successful token validations since module start. |
| Integer | Count of failed token validations since module start. |
| String | OIDC only: |
| Integer | OIDC only: number of signing keys loaded from the IdP's JWKS endpoint. |
| Boolean | Composite indicator: |
These properties are runtime-only — they reset to zero on module restart. They do not persist across solution reload. Use them to drive an operator status panel showing IdP health.
Solutions upgraded from pre-10.1.5 automatically migrate the legacy LDAP configuration:
The SecurityEnableLDAP and SecurityLDAPServer columns on the pre-10.1.5 SecurityRuntimeSettings table are read, then materialized as a single AuthType=LDAP, Active=true row in SecurityIdentityProviders with AuthOptions = "Server=<old-server>;DefaultPolicy=AD;".
The legacy columns are then dropped from SecurityRuntimeSettings.
Migration runs once on first open of the solution under 10.1.5+.
No script or Display change is needed to keep LDAP login working post-upgrade — the runtime CheckUser LDAP branch now reads the new table and produces identical behavior. Customers wanting to add OIDC providers add rows alongside the migrated LDAP row.
Mistake |
Why it fails |
Fix |
|---|---|---|
Adding a |
The IdP table holds how to validate credentials, not which credentials to silently submit. |
Script silent-login at the LogOn Display CodeBehind via |
Routing tokens through |
Those entry points encrypt the incoming password before transport, which mangles JWTs. |
Use the parallel |
Multiple |
At most one Active LDAP row per solution (preserves the 10.1.4 single-LDAP-server semantic). Designer save validator rejects; runtime takes first-by-ID-order on duplicates and logs a warning. |
Mark all but one LDAP row |
Plain-text password in |
The OIDC validator resolves |
Create a Security Secrets row holding the client secret; reference it as |
Group names in IdP do not match Permission Group names |
Group-to-Permission matching is case-exact on the name. |
Either rename Permission Groups to match IdP group names, or rename IdP groups to match FrameworX Permission Group names. |
Security Module Reference — complete security documentation.
Security Secrets Reference — used by ClientSecretRef for OIDC client secrets.
Security Permissions Reference — the Permission Groups that group claims and DefaultPolicy map to.
Security Policies Reference — session timeout, password rules, e-sign — applied post-identity-resolution regardless of IdP.