OpenID Connect
To configure the Valsight application to use the OpenID Connect SSO, edit conf/config.yml and restart the server after making changes.
To enable OpenID Connect login configure the following value:
| Configuration Key (loginMethodConfigurations → openIdConnect →) | Description | Example Value | Default Value |
|---|---|---|---|
| enabled | Whether OpenID Connect authentication should be used or not | true | false |
To configure an OpenID Connect client enter the following configuration keys:
spring:
security:
oauth2:
client:
registration:
openIdConnect:
.....
Then configure the OpenID Connection client values as follows:
| Configuration key | Description | Example | Default |
|---|---|---|---|
client-id | OAuth 2.0 client identifier, valid at the authorization server | jmxDcfi1gEffVMktJ | n/a |
client-authentication-method | The type of client authentication to perform with the authorization server. See Client authentication methods. | client_secret_basic | client_secret_basic |
client-secret | Client secret token, provided by the authorization server. Since 6.3.0 this is no longer mandatory unless client_secret_basic is the client authentication mode. | aZWAuRZUSxT-Sh8-xDLdHI | n/a |
scope | Comma-separated list of scopes to request, when additional claims are needed | openid, email, profile | n/a |
provider | The name of the OpenID Connect provider to use. Required unless a provider with the registration id openIdConnect exists. | openIdConnect | n/a |
valsightOpenIdConnectProperties → userProfileMapping → username | The claim used to uniquely identify a user. Must always be present in the provider’s response, and unique per user. See Claim names are case sensitive. | preferred_username | sub |
valsightOpenIdConnectProperties → userProfileMapping → email | The claim that contains the user’s e-mail address. Optional. | email | n/a |
valsightOpenIdConnectProperties → userProfileMapping → fullName | The claim that contains the user’s full name. Optional. | name | n/a |
valsightOpenIdConnectProperties → loginSuccessfulUrl | The absolute URL, starting with http or https, of the application’s main page. The user is redirected there after a successful login. | https://valsight.example.com/ | n/a |
valsightOpenIdConnectProperties → forceGroupsOverage | Forces the application to always use the https://graph.microsoft.com/v1.0 API to fetch the user’s groups. No effect unless groupsClaim is enabled. Optional. | true | false |
valsightOpenIdConnectProperties → acr_values | Passes additional authentication-related information to the user service. Optional. | myvalue1:myvalue2:myvalue3:myvalue4 | n/a |
valsightOpenIdConnectProperties → mandatoryClaims | Customizes which claims must be present, and with which values, beyond those requested by the OpenID Connect specification. See Mandatory claims. Optional. | See Mandatory claims | n/a |
valsightOpenIdConnectProperties → groupsClaim | The claim holding the groups the user belongs to. See Group synchronization. Optional. | groupsInOpenIDConnectResponse | n/a |
valsightOpenIdConnectProperties → requiredGroupNamePrefix | Removed in 6.0.0. See Removed: requiredGroupNamePrefix. | AcceptedGroup_ | n/a |
valsightOpenIdConnectProperties → userInfoEndpointScopes | Scopes that are accessible only from the user info endpoint, not from the token. See User info endpoint scopes. | See User info endpoint scopes | profile, email, address, phone |
Three further settings under valsightOpenIdConnectProperties control what the login page offers and which scopes each login option requests: buttonText (see Login button label), additionalScopes (see Additional scopes), and the alternativeLogin group (see Alternative login flow).
Client authentication methods
The supported forms of authentication are client_secret_basic and private_key_jwt.
With client_secret_basic a client-secret must be provided; with private_key_jwt a privateRSAKeyPath must be provided instead. For more on private_key_jwt, see OAuth 2.0 with private key JWT client authentication.
Claim names are case sensitive
Ensure the configured string matches the IdP claim name exactly. This applies to every userProfileMapping entry, to groupsClaim, and to the claim values under mandatoryClaims.
Mandatory claims
Every claim configured here must be present in the provider’s response and carry the specified value. Where a claim has multiple values in the response — a list of the user’s groups, for example — one of those values must match the configured value exactly.
MIGRATETOKEN1ENDTOKEN
Group synchronization
Setting groupsClaim turns on group synchronization. If the claim is absent or empty, groups must be managed inside the application instead. The value should be a claim name that contains the groups the provider supplies.
Group matching then happens as follows:
- Read the groups from the OpenID Connect response.
- Create groups that are missing in the application.
- Add the user to all groups from the response.
- Remove the user from all groups not in the response.
This functionality never automatically deletes groups in the application.
Removed: requiredGroupNamePrefix
Available since 5.9.1, removed in 6.0.0 and replaced by loginMethodConfigurations → commonSSOOptions → requiredGroupNamePrefixes. See Common SSO Options.
Before 6.0.0 this determined whether group names had to carry a given prefix to be recognised by the application: any group name in the OpenID Connect response not starting with the value was treated as absent. When mandatoryGroupName was also set, the mandatory group name had to carry the required prefix.
User info endpoint scopes
To stop the user info endpoint being invoked at all, populate this list with none of the scopes listed under scope. Setting it to an empty list means the user info endpoint is always invoked.
Available since 6.0.26.
MIGRATETOKEN2ENDTOKEN
Login button label
Available since 7.2.5 and 7.3.0.
| Configuration key | Description | Example | Default |
|---|---|---|---|
valsightOpenIdConnectProperties → buttonText | Label of the OpenID Connect button on the login page. Optional. | Log in with Acme ID | OpenID Connect |
This key sets a default, it does not override: whatever an administrator has saved under Login Page Settings wins whenever it is set. See Login Page Customization for that setting.
Use buttonText to ship a label together with the configuration file, so a newly installed instance already shows the right wording before anyone opens the settings page. If neither is set, the button reads OpenID Connect.
Additional scopes
Available since 7.2.5 and 7.3.0.
| Configuration key | Description | Example | Default |
|---|---|---|---|
valsightOpenIdConnectProperties → additionalScopes | Scopes the login button requests in addition to those listed under scope. Optional. | urn:zitadel:iam:org:id:123456789456132 | n/a |
Write the value either as a YAML list or as a single string with the scopes separated by commas, whitespace, or both. The scopes are added to scope; nothing is removed.
The typical use is an identity provider that accepts an organization scope. Sending it pins the login to one organization, so the user reaches their own identity provider directly instead of first having to enter an email address for domain discovery.
That same scope excludes everyone who is not a member of that organization. Those users need the alternative login flow.
Alternative login flow
Available since 7.2.5 and 7.3.0.
A second login option that requests a different set of scopes from the same OpenID Connect client. It exists for the users an organization scope in additionalScopes would otherwise lock out, for example staff who authenticate against a different organization’s identity provider.
Configuration key (valsightOpenIdConnectProperties → alternativeLogin →) | Description | Example | Default |
|---|---|---|---|
additionalScopes | Scopes this flow requests instead of additionalScopes. May be left empty. See An empty scope list is a valid configuration. Optional. | urn:zitadel:iam:org:id:987654321098765 | n/a |
buttonText | Label of the link on the login page. Without it the flow stays reachable by its URL but is not listed. Optional. | Log in with a different organization | n/a |
enabled | Switches the flow on or off explicitly. See When the enabled key is needed. Optional. | false | On when additionalScopes or buttonText is set |
requiredHeader | Lists the link only for clients whose request carries this header. See Listing the link for some clients only. Optional. | x-internal-client | Unset, so the link is listed for every client |
The flow is requested with a query parameter on the authorization URL:
<server_url>/<contextPath>/oauth2/authorization/openIdConnect?loginFlow=alternative
That parameter only selects between scope sets already configured on the server. An absent, unknown, or unconfigured value falls back to the primary scopes, so no caller can request scopes of their own.
On the login page the option is rendered as a link below the OpenID Connect button rather than as a second button, because it is a variant of the same provider and not a login method of its own.
When the enabled key is needed
Configuring either additionalScopes or buttonText under alternativeLogin already enables the flow, so most instances need no enabled key at all. Set it explicitly in two cases:
enabled: truefor a flow that has neither scopes nor a label of its own, which is otherwise indistinguishable from an unconfigured one.enabled: falseto switch a configured flow off without deleting its keys.
An empty scope list is a valid configuration
Leaving alternativeLogin → additionalScopes empty is a meaningful configuration rather than a pointless one. The flow then sends only the scopes listed under scope, and so no organization scope at all, which is what makes the identity provider fall back to its own account chooser.
For that reason the alternative flow never falls back to the primary additionalScopes. Once the flow is enabled, requesting it always replaces the primary scopes, even when it defines none.
Listing the link for some clients only
Name a request header in requiredHeader and the link is listed only for clients whose request carries it; leave the key unset and the link is listed for everyone. Use it where a login page carries one customer’s branding and the alternative option is meant for a different group of users — staff, say — who can be told apart by something the infrastructure in front of Valsight already knows.
Which clients get the header is decided in that infrastructure and not in Valsight. The application never interprets the value, only whether the header is there with a non-blank value, so the header can mean whatever the deployment needs it to mean.
Two requirements on whichever component injects it:
- It has to set the header on every request, so that a copy sent by the client is always overwritten. If a client could supply the header itself, the setting would gate on nothing.
- It has to be a component the request cannot bypass. Valsight reads the configured header alone, with no fallback to
X-Forwarded-FororX-Real-IP, because a client writes those freely. See Reverse Proxy.
Hiding the link decides what the login page offers; it is not an access rule. The flow’s URL keeps working without the header, and opening the login page with ?alternativeLogin=1 lists the link for any client:
<server_url>/<contextPath>/app/index.html#/login?alternativeLogin=1
Give that URL to the users the flow is for who reach the login page without the header. Where nothing injects the header, no client ever carries it and the link is only reached this way — so leave requiredHeader unset until the header is actually in place.
While requiredHeader is set, the login page’s data response carries a Vary header naming it, so a cache between Valsight and the browser cannot serve one client’s login page to another.
Example configuration
spring:
security:
oauth2:
client:
registration:
openIdConnect:
scope: openid, email, profile
valsightOpenIdConnectProperties:
buttonText: Log in with Acme ID
additionalScopes: urn:zitadel:iam:org:id:123456789456132
alternativeLogin:
# deliberately empty: send no organization scope at all
additionalScopes:
buttonText: Log in with a different organization
requiredHeader: x-internal-client
With this configuration the login page shows one Log in with Acme ID button that pins the login to the Acme organization. Clients whose request carries x-internal-client additionally get a Log in with a different organization link below it, which sends no organization scope. Drop the requiredHeader line to offer that link to everyone.
To configure an OpenID Connect provider enter the following configuration keys:
spring:
security:
oauth2:
client:
provider:
openIdConnect:
.....
Then configure the OpenID Connection provider values as follows:
| Configuration Key (….provider.openIdConnect →) | Description | Example Value | Default Value |
|---|---|---|---|
| issuer-uri | Identifier for the Issuer of the authorization response. | https://my-oidc.com/ | n/a |
| authorization-uri | The Authorization endpoint of the OpenID Connect flow | https://my-oidc.com/authorize | n/a |
| token-uri | The Token endpoint of the OpenID Connect flow | https://my-oidc.com/oauth/token | n/a |
| jwk-set-uri | The endpoint that contains certificates to verify the token | https://my-oidc.com/oauth2/certs | n/a |
Full example YAML configuration
Below is an example of all the available configuration keys for OpenID connect, with no values supplied except where stated:
spring:
security:
oauth2:
client:
registration:
openIdConnect:
client-id:
client-secret:
scope:
valsightOpenIdConnectProperties:
userProfileMapping:
username:
email:
fullName:
forceGroupOverage:
loginSuccessfulUrl:
mandatoryClaims:
#example value
group: groupName
acr_values:
groupsClaim:
requiredGroupNamePrefix:
userInfoEndpointScopes:
provider:
openIdConnect:
issuer-uri:
authorization-uri:
token-uri:
jwk-set-uri:
Logging
For logging purpose, add in the log level view (Configuration UI), the following package:
org.springframework.securityorg.springframework.security.oauth2com.valsight.authentication.oauthcom.valsight.services.authentication.SSOServicecom.valsight.authenticationorg.springframework.web.client
Set the log level to DEBUG
Redirect/callback URL
When configuring the IdP the redirect/callback URL for the application is:
<server_url>/
Reverse proxy configuration
If the application is running behind a reverse proxy it will be required to configure the reverse proxy such that the OpenID connect authentication flow can be performed A guide to doing this can be found here: Reverse Proxy