This is an old revision of the document!


Configure OpenID Connect (OIDC) Authentication

This feature is in the beta stage.

OpenID Connect (OIDC) is an identity layer built on OAuth 2.0. Stages acts as an OIDC relying party (RP), also called a client, and delegates user authentication to an OpenID Provider (OP), also called an identity provider (IdP).

Stages uses the provider's discovery document and a client registration to establish the OIDC login flow.

Register Stages with the identity provider

Create an OIDC client/application in your identity provider. Ask your identity or access management team for the values required to configure it in Stages.

Register the following redirect URIs (callback URLs) for the client. Stages uses three different redirect URIs, which must all be registered exactly as shown, including scheme, host, path, and query parameter:

https://stages.example.com/stages/auth/public/acs?client_name=oidc-idp
https://stages.example.com/stages/auth/public/acs?client_name=passive-oidc-idp
https://stages.example.com/stages/auth/public/acs?client_name=forceAuth-oidc-idp

Replace https://stages.example.com with the base URL of your Stages installation. The value oidc-idp in the client_name parameter corresponds to the name attribute of the OIDC authentication method in conf/config.xml (see Enable OIDC for Stages). If you use a different method name, adjust the redirect URIs accordingly.

Request the scopes:

  • openid
  • profile
  • email

Obtain the following values from the provider:

  • OIDC discovery URL
  • Client ID
  • Client secret

The provider's discovery document is normally available at the issuer's /.well-known/openid-configuration endpoint.

Enable OIDC for Stages

Add or enable the OIDC authentication method in conf/config.xml:

<method type="Oidc" name="oidc-idp" enabled="${idp.oidc.enabled}"><!-- TODO -->
    <properties>
        <property name="discoveryURI" value="${idp.oidc.discovery.url}" />
        <property name="scope" value="${idp.oidc.scope}" />
        <property name="clientId" value="${idp.oidc.client.id}" />
        <property name="secret" value="${idp.oidc.client.secret}" />
        <property name="clientAuthenticationMethodAsString" value="${idp.oidc.client.auth.method}" />
    </properties>
    <filters>
        <!-- This is the default matcher, identified by id and pattern attributes set to "*" -->
        <attribute-match
                id="*"
                pattern="*"
                defaultUserGroupsUsername="${user.default.username}"
                defaultLicenseType="${user.default.licenseType}"
                autocreateUser="${idp.oidc.autocreate}"
        />
    </filters>
</method>

The discoveryURI points to the OIDC provider's discovery document. The scope determines which claims are requested. Set clientAuthenticationMethodAsString to a client authentication method supported by both Stages and your provider.

The following example configuration variables are referenced above. Adjust the discovery URL, scope, client ID, and client authentication method to match your provider's client registration.

conf/config.properties:

idp.oidc.enabled = true
idp.oidc.discovery.url = https://login.microsoftonline.com/<tenant-id>/.well-known/openid-configuration
idp.oidc.scope = openid profile email
idp.oidc.client.id = 00000000-0000-0000-0000-000000000000
idp.oidc.client.auth.method = client_secret_basic
idp.oidc.autocreate = true
 
user.default.username = default
user.default.licenseType = AuthPsReader

Store the client secret in conf/secret.properties

idp.oidc.client.secret = SECRET

After you configured the service provider and identity provider in config.xml, update the configuration via “stages update'' and restart the Stages service.''

Changing the license pool and license type for existing users

By default, existing users are not modified by the OIDC authentication process when the OIDC configuration was changed after the user had been created. However, you can set the forceLicensePoolReassignment attribute on an attribute-match to true if you want changes of the licensePoolIdent or defaultLicenseType attributes to be applied to existing users.

Configuring Stages attributes in default-matcher section with JavaScript

JavaScript control flow statements (e.g. “if”,”switch“) can be used to configure values for Stages attributes. All claims of the OIDC response are accessible as variables and can be used in the JavaScript expression

JavaScript expressions can be used with the following Stages attributes:

  • defaultRolesUsername
  • defaultLicenseType
  • licensePoolIdent

General JavaScript expression notation:

 <Stages_attribute>="=<JavaScript_expression>"  

JavaScript notation of if-clauses:

 if (condition1) 'returnValue1'; else if (condition2) 'returnValue2'; else if (condition3) 'returnValue3'; else 'returnValue4';  

JavaScript notation of value conditions:

OIDC claims that are defined via identity_provider_attribute elements can be used in these scripts. E.g.

<identity-provider-attribute name="email" id="<EMailAddress>" />  

Names of license types for license assignment

License nameLicense type
ModelerQM
ContributorFloatingADev
ParticipantFloatingDev
Project ManagerFloatingPM
ViewerAuthPsReader

Example configuration:

This example creates Stages users with the following conditions:

  • The pattern matches the entry of the OIDC claim “id”.
  • Depending on the users' email address (domain-part), OIDC claim “email” is used to assign different values for defaultRolesUsername, defaultLicenseType and licensePoolIdent
<attribute-match      
    id="[oidc_attribute_id]"
    pattern="[matching_value]"      
    defaultRolesUsername="= if (email.match(/.*@company1.com/)) 'User1';
                       else if (email.match(/.*@company2.com/)) 'User2';
                       else 'default';         " 
    defaultLicenseType="= if (email.match(/.*@company1.com/)) 'QM';
                 else if (email.match(/.*@company2.com/)) 'PM';         
                 else 'none';         "      
    licensePoolIdent="= if (email.match(/.*@company2.com/)) 'company2'; 
             else '';"
    autocreateUser="true"
/>

Please note that the values of multi value attributes are provided to the scripts as one value as a comma separated string.

Configure multiple OIDC providers

Add one OIDC authentication method per provider and give each method a unique name. Use each provider's own discovery URL, client registration, and secret.

<authentication>
    [...]
    <method type="Oidc" name="oidc-company-1" enabled="${oidc1.enabled}">
        [...]
    </method>
    <method type="Oidc" name="oidc-company-2" enabled="${oidc2.enabled}">
        [...]
    </method>
</authentication>

This will create a SSO button on the login page for each IDP. Please provide a user understandable naming by defining a translation property for each login.sso.[name] propertyin each supported language: conf/local.properties, conf/local_de.properties, …

login.sso.oidc-company-1 = Single Sign-On for company 1
login.sso.oidc-company-2 = Single Sign-On for company 2

Validated IdP Vendors

Stages OIDC has successfully been deployed with the following IdP servers:

  • Azure AD IdP
  • Keycloak

Please let us know if you were able to make Stages OIDC work with your server and it is not on this list yet.