Single Sign-On (OAuth2/OIDC)
The CIB seven webclient supports Single Sign-On with any identity provider that implements OpenID Connect (OIDC), for example Microsoft Entra ID (Azure AD) or Keycloak. When SSO is active, the login page redirects the user to the identity provider, and after a successful login the user is redirected back to the webclient.
Webclient SSO is a feature of the webclient itself and does not require Spring Security. It works the same way on all distributions: CIB seven Run, Tomcat and WildFly. Also, it can be enabled for Spring Boot applications without Spring Security.
Activation
To activate SSO, select the OAuth2UserProvider as user provider and set cibseven.webclient.sso.active to true:
cibseven:
webclient:
user:
provider: org.cibseven.webapp.auth.OAuth2UserProvider
authentication:
jwtSecret: <jwtSecret>
sso:
active: true
endpoints:
authorization: <authorizationUri>
token: <tokenUri>
jwks: <jwksUri>
user: <userInfoUri>
clientId: <clientId>
clientSecret: <clientSecret>
scopes: openid email profile
userIdProperty: preferred_username
userNameProperty: name
scopesis the list of scopes (separated by spaces) that the webclient requests from the identity provider. You can configure it freely, for example to addoffline_accessor a custom API scope.userIdPropertyanduserNamePropertyare the claims of the ID token that are used as CIB seven user ID and display name.authentication.jwtSecretis always required: the webclient uses it to sign the session token exchanged between the browser and the webclient.- With
sso.accessTokenToEngineRest: false(default), the webclient also sends this token to the engine REST API, which validates it with JWT authentication. In that case, the engine must be configured with the same secret. - With
sso.accessTokenToEngineRest: true, the webclient sends the access token from the identity provider to the engine instead. The secret is then only used for the webclient session. This requires an engine REST API secured with OAuth2.
- With
All available properties are listed in the cibseven.webclient.sso property reference.
Redirect URI
Register the following redirect URI for the client at your identity provider:
<scheme>://<host>:<port>/<webclient path>/sso-login.html
For example, https://cibseven.example.com/webapp/sso-login.html. The path /webapp is the default value of camunda.bpm.webapp.applicationPath, so adjust it if you deploy the webclient under another path.
Redirect URI must match the browser URL
The webclient builds the redirect URI from the URL in the browser, so the registered URI must match exactly the URL users open (scheme, host name, port and path), including when the webclient runs behind a reverse proxy.
In Microsoft Entra ID, register the redirect URI under the platform type Web, because the webclient exchanges the login code on the server with the client secret or client assertion.
Where to Configure the Properties
The cibseven.webclient.* properties can be set in the following places, depending on the distribution:
| Distribution | Where to configure |
|---|---|
| CIB seven Run | The configuration file configuration/default.yml or configuration/production.yml. |
| Spring Boot | The application.yaml (or application.properties) of your application. |
| Tomcat |
You can place a cibseven-webclient.yaml file in the $CATALINA_HOME/lib folder. Alternatively, properties can be added to cibseven-webclient.properties, which is automatically generated the first time by start-cibseven.bat/start-cibseven.sh. You can also pass the properties as -D options, for example in CATALINA_OPTS in bin/setenv.sh / bin/setenv.bat, or as environment variables (for example CIBSEVEN_WEBCLIENT_SSO_ACTIVE=true).
|
| WildFly |
You can define system properties in the standalone.xml.Alternatively, properties can be added to cibseven-webclient.properties, which is automatically generated the first time by start-cibseven.bat/start-cibseven.sh for JWT mechanism purposes and placed in $JBOSS_HOME/modules/org/cibseven/config/main/.
|
No need to change the WAR file
The webclient imports the optional files cibseven-webclient.properties and cibseven-webclient.yaml from the classpath, so you do not need to modify the application.yaml inside the WAR file.
Example for cibseven-webclient.properties:
cibseven.webclient.user.provider=org.cibseven.webapp.auth.OAuth2UserProvider
cibseven.webclient.sso.active=true
cibseven.webclient.sso.endpoints.authorization=<authorizationUri>
cibseven.webclient.sso.endpoints.token=<tokenUri>
cibseven.webclient.sso.endpoints.jwks=<jwksUri>
cibseven.webclient.sso.endpoints.user=<userInfoUri>
cibseven.webclient.sso.clientId=<clientId>
cibseven.webclient.sso.clientSecret=<clientSecret>
cibseven.webclient.sso.scopes=openid email profile
cibseven.webclient.sso.userIdProperty=preferred_username
cibseven.webclient.sso.userNameProperty=name
Users, Groups and Authorizations
After the login, the value of the userIdProperty claim becomes the CIB seven user ID. The webclient uses this ID to call the engine, and the engine applies groups, tenants and authorizations for this user ID.
By default, the engine resolves the groups and tenants of the user from its configured identity service: the CIB seven database or LDAP. Therefore, a user with the same user ID must exist there, with the required group memberships and authorizations.
Choose a userIdProperty whose value matches the user IDs in your identity service, for example preferred_username or a custom claim. If userIdProperty is empty or wrong, the login will fail.
Granting Initial Administrator Permissions
To grant initial administrator permissions to an SSO user or group, use the Administrator Authorization Plugin. If you run a Spring Boot application or the CIB seven Run distro, you can also use the camunda.bpm.admin-user property. The ID you use must match the value of the userIdProperty claim, otherwise the permissions do not apply to the SSO user.
When Spring Security Is Required
| Use case | Spring Security required |
|---|---|
SSO login to the webclient (OAuth2UserProvider, cibseven.webclient.sso.*) |
No. Works on all distributions. |
Secure the engine REST API with OAuth2 (resource server), together with cibseven.webclient.sso.accessTokenToEngineRest=true |
Yes, cibseven-bpm-spring-boot-starter-security |
Read the groups of the user from the token instead of the CIB seven database or LDAP (OAuth2IdentityProvider) |
Yes, cibseven-bpm-spring-boot-starter-security |
The cibseven-bpm-spring-boot-starter-security is available for Spring Boot and CIB seven Run. See Spring Security OAuth2 Integration for these scenarios.
Assertion-based Authentication
A secretless client authentication approach can be configured so that no client secret is used or transmitted during the authentication process. The following authentication methods are supported:
- JWT Bearer Client Assertion: The client authenticates using a signed JWT. A PEM-encoded private key must be configured as the
keyLocationto sign the client assertion. - Azure Workload Identity: The client authenticates using Azure Workload Identity without requiring a client secret or certificate.
The CIB seven webclient can be configured to use assertion-based authentication by setting its cibseven.webclient.sso.assertion properties.
For more information about assertion-based authentication, refer to RFC 7521.
Microsoft Entra ID
Microsoft Entra ID provides the endpoints of a tenant at https://login.microsoftonline.com/<tenantId>/v2.0/.well-known/openid-configuration. Use the v2.0 endpoints.
App registration checklist
- Redirect URI: register the redirect URI with the platform type Web, not Single-page application. The webclient redeems the login code on the server with a client secret or client assertion, which Entra ID does not allow for a Single-page application redirect URI.
- Expose an API and define a scope: set the Application ID URI to
api://<clientId>and define a custom scope, for examplecibseven. - API permissions: in the API permissions section, select Add a permission, find your app registration among the APIs my organization uses, select it and choose Delegated permissions to add the custom scope.
- If you defined the scope with Admins only consent, grant admin consent.
- Client secret: create a client secret. Alternatively, you can use a client assertion.
Configuration for Entra ID
cibseven:
webclient:
user:
provider: org.cibseven.webapp.auth.OAuth2UserProvider
sso:
active: true
endpoints:
authorization: https://login.microsoftonline.com/<tenantId>/oauth2/v2.0/authorize
token: https://login.microsoftonline.com/<tenantId>/oauth2/v2.0/token
jwks: https://login.microsoftonline.com/<tenantId>/discovery/v2.0/keys
user: https://graph.microsoft.com/oidc/userinfo
clientId: <Application (client) ID>
clientSecret: <secret>
scopes: openid profile email offline_access api://<clientId>/cibseven
userIdProperty: preferred_username
userNameProperty: name
- The custom scope
api://<clientId>/<customScope>is mandatory. Without it, Entra ID issues a Microsoft Graph access token. The webclient validates the signature of the access token, and third parties cannot validate Graph tokens. The user then sees a certificate or signature validation error after the login.- If you defined a custom Application ID URI (different than the recommended one), notice that the custom scope must match it, like
<applicationIdUri>/<customScope>.
- If you defined a custom Application ID URI (different than the recommended one), notice that the custom scope must match it, like
userIdPropertyanduserNamePropertyare read from the ID token on the browser login. With the scopeprofile, a v2.0 ID token containspreferred_username(usually the user principal name, UPN) andname.- The user ID must match the user IDs in your identity service. If your LDAP user IDs are, for example,
sAMAccountName, thenpreferred_username(user@domain) does not match. You can provide a matching claim in Entra ID (token configuration or claims mapping), or create the users with their UPN. Alternatives areemail(can be empty) andoid(a stable GUID, but not human-readable). endpoints.useris mandatory. It has no default value, and the application does not start without it.offline_accessscope is mandatory (for OAuth2). Without it, Entra ID issues no refresh token.
Refresh Tokens
The OAuth2UserProvider does not support rolling refresh tokens (refresh tokens that are invalidated once they have been used). Take this into account when you configure the token policies of your identity provider.
Entra ID Troubleshooting
If you checked the generic troubleshooting and did not find the cause of your login failure, the following problems are specific to Microsoft Entra ID. To investigate further, open the developer tools (F12) before you log in: the login page sso-login.html stops at a breakpoint, and you can inspect the URL and the response of the login request. Entra ID reports its errors in the URL.
SignatureException
A pop-up shows a SignatureException. The login request returns HTTP 500, and the backend log contains:
io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
Cause: the custom scope is missing in sso.scopes. Entra ID then issues a Microsoft Graph access token, which the webclient cannot validate. Add the custom scope api://<clientId>/<customScope>, see the example configuration.
AuthenticationException
A pop-up shows an AuthenticationException. The login request returns HTTP 401.
Cause: resource not found. The login stops at the breakpoint, and the URL contains an error from Entra ID:
<scheme>://<host>:<port>/webapp/sso-login.html#error=invalid_resource&error_description=AADSTS500011: The resource principal named api://<clientId> was not found in the tenant named <tenantId>. ...
The login request then returns HTTP 401 with AADSTS900144: The request body must contain the following parameter: 'code'. This second error is a consequence of the first: the browser came back without a code. Nothing is written to the backend log. Check the Application ID URI under Expose an API, check that it matches the custom scope in sso.scopes, and check the tenant ID in sso.endpoints.
Frontend loop after the login
After the login, the browser keeps redirecting between the webclient and the login page. Possible causes:
offline_accessis missing insso.scopes.
Other errors
If your error is not among these, check the response of the login request in the developer tools. Entra ID often gives more information in the URL.
Troubleshooting
If the login fails, the user sees one of three symptoms: a pop-up with a SignatureException, a pop-up with an AuthenticationException, or a loop in the frontend after the login. To read the server response, open the browser developer tools (F12) before you log in.
AuthenticationException
A pop-up shows an AuthenticationException. The login request returns HTTP 401.
Cause: wrong client secret. The response is {"type":"AuthenticationException","params":[""]}, and the backend log has no entry. Check sso.clientSecret.
Frontend loop after the login
After the login, the browser keeps redirecting between the webclient and the login page. Possible causes:
userIdPropertyis empty or does not match a claim of the token. The backend log containsjava.lang.NullPointerException: Cannot invoke "String.equals(Object)" because the return value of "org.cibseven.webapp.auth.User.getId()" is null.- A component rejects the token that the webclient sends to the engine REST API (HTTP 401).
- With the webclient SSO only: if
sso.accessTokenToEngineRestistrue, the webclient sends the access token of the identity provider. A servlet filter such as the composite authentication rejects it, because it only accepts tokens that are HMAC-signed withauthentication.jwtSecret. - With OAuth2 on the engine REST API: if
sso.accessTokenToEngineRestisfalse, the webclient sends its own HMAC-signed token, and Spring Security rejects it. Set the property totrue.
- With the webclient SSO only: if