OpenIDConnect (OIDC) Providers

Introduction

OpenID Connect (OIDC) is the main protocol used to connect to external identity providers. At the heart of this framework are two pivotal entities: the OpenID Provider (OP) and the Relying Party (RP):

  1. OpenID Provider (OP): Acting as the Identity Provider (IdP), the OP is responsible for authenticating the end-user and issuing identity tokens to Relying Parties (RPs). The OP serves as the trusted authority in the OIDC ecosystem. An example of an OP is Keycloak or Microsoft Entra ID.
  2. Relying Party (RP): This is the client application that depends on the OP for authentication. The RP requests and obtains identity information from the OP and then uses it to offer personalized, secure access to its services. FNZ Studio assumes the role of the RP.

When setting up a connection between these two entities, there are specific configuration options to consider. This ensures seamless integration and secure communication. This documentation aims at guiding you through these configuration options, thus ensuring a robust and secure link between FNZ Studio and your chosen OP.

OP General Configuration

One or more OPs can be configured to be available for an FNZ Studio environment. The configuration of an OP is stored in JSON format.

The easiest and best way to configure OPs is to raise a ticket with the FNZ Studio Cloud Operations team and provide the configuration as required.

Note: The configuration might contain sensitive information, in particular a client secret which should not be added to a ticket but shared in a secure way.

As soon as the configuration has been applied, the (non-hidden) OPs will show up on the login screen: OpenIDLogin.png

OP Configuration in FNZ Studio

OpenID Connect Provider configuration in FNZ Studio Composition is available through the OIDCAuth Extension 3.0.0 and higher. Moreover, note that only Administrators with the OpenID Connect Providers Permission (Advanced Studio Permissions) can read/write OP configurations.

During development or testing phases, it might be necessary to set up additional OPs or try different configurations. For this purpose, FNZ Studio Composition offers a configuration interface for OPs under System Configuration > OpenID Connect Providers.

Important note! Changes to OpenID Connect Providers performed in FNZ Studio Composition will be overwritten by any cloud operation - such as a Platform upgrade or the addition of a Data Source. To avoid losing data, please raise a Support Ticket with any updated provider configuration as described in section 1 before requesting any Platform operation.

Several actions are possible in the OpenID Connect Providers submodule:

  1. From the top-left menu:
    • Adding new OPs (only with write permission)
    • Exporting OPs (exports config json file — client secrets are masked)
  2. From the context menu, for existing OPs:
    • Editing the provider configuration (only with write permission)
    • Testing the authorization code flow
    • Testing the client credential flow

OP Configuration Details

Main Configuration Options

Each provider needs at least three properties configured:

  1. Name: The name to be used for the OP, both on the button on the login pages as well as if using it for the client credentials flow.
  2. Issuer: The OP's unique Issuer Identifier corresponding to the iss claim in the ID tokens it provides. The issuer identifier is a URL used for identifying the OP to the application, validating the ID Token iss claim and, unless the documentConfigurationUrl property is included (see below), to load the OP configuration document according to the OpenID Connect Discovery's Obtaining OpenID Provider Configuration Information process (by adding .well-known/openid-configuration to the issuer identifier to form the OP configuration document URL).
  3. Client ID: The client id associated with the RP (Studio) at the OP.

Additional Configuration Options

There are several additional configuration options for OpenId Providers. The attached tables illustrate:

  1. The most frequently used configuration properties (Configuration Properties - Main (PDF))
  2. Additional configuration properties (Configuration Properties - Others (PDF))

Configuration Examples

Following you can see some configuration examples:

Copy

[

    {

        "name": "Amazon Cognito",

        "issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_AGKCjG3dQ",

        "clientId": "a-client-id",

        "clientSecret": "a-client-secret"

    },

    {

        "name": "Microsoft Azure AD",

        "issuer": "https://sts.windows.net/45185e72-2ac1-4371-acec-d0b6d4469ce2/",

        "clientId": "a-client-id",

        "clientSecret": "a-client-secret",

        "usernameClaim": ["name", "appid"],

        "rolesClaim": "roles",

        "rolesMapping": {

          "Studio-Admin": ["Administrator", "User"],

          "Studio-User": "User"

        }

    },

    {

        "name": "Microsoft Azure AD - Client Credentials",

        "issuer": "https://login.microsoftonline.com/45185e72-2ac1-4371-acec-d0b6d4469ce2/v2.0",

        "clientId": "another-client-id",

        "clientSecret": "a-client-secret",

        "hidden": "true",

        "Optional": "true"

    },

    {

        "name": "Special Provider",

        "issuer": "http://localhost:8080/appway",

        "clientId": "a-client-id",

        "rolesClaim": "roles",

        "rolesMapping": { "(.*)": "$1" }

        "optional" : true

    }

]

Mapping

Usernames and roles extracted from an ID token can be "mapped" to match local usernames and roles.

Possible use cases are:

  1. Users use their email address to log in at the OpenID Connect provider, but local users should only use the name part of the email address.
  2. Local usernames should be prefixed with a key that is different for every configured OpenID Connect provider to avoid username clashes.
  3. Role names have prefixes to distinguish roles for different environments. Only roles with a very specific prefix should be accepted by the local system, and this prefix should be removed automatically.

All mappings are based on Java regular expressions and replacements.

Username Mapping

The simplest mapping is a pattern using a capture group to extract the actual username:

Copy

"usernameMapping": "(.*)@email.com"

Arrays of simple mappings to extract a substring from a username are supported:

Copy

"usernameMapping": [

   "(.*)@domain.com",

   "DOMAIN/(.*)",

   ...

]

However, more complex mapping rules can be used in the form of key/value pairs. Every rule consists of a regular expression (key) and a replacement with references to capture groups (value):

Copy

"usernameMapping": {

   "(.*)@gmain.com": "google:$1",

   "(.*)@hotmail.com": "microsoft:$1",

   ...

}

This last form can also be used to make one-to-one mappings for users, if desired:

Copy

"usernameMapping": {

   "peter": "peter.smith",

   "root": "administrator",

   ...

}

Important: If a username does not match any of the regular expressions, the user is not allowed to log in.

Role Mapping

Mappings for roles work similarly. However, they also support mapping to multiple roles by using an array as value:

Copy

"rolesMapping": {

   "Employees": ["User", "FrontOffice"],

   "PROD-Role-(.*)": ["$1", "ProdUser"]

   ...

}

Remarks

Consider the following information on mapping:

  1. Mapping order is relevant: if multiple regular expressions match, the first match is always used.
  2. Whitespaces at the start or end of a mapping result are removed.
  3. If the result of a mapping is an empty string, it is ignored.
  4. If multiple roles are mapped to the same role, this is is included only once.

Other Mappings

The LoginScript Extension can be used to sync more information from ID or access token to the current user.

Example:

Copy
Function Example:Login() : Nothing Begin
   // Fetch the ID Token stored in the user's session
   String $idToken := Auth:GetIdToken();
   String $userId := User:CurrentUserGetId();
   // If the login did not use OIDC, there will be no ID token, in this case the script is ended
   If EMPTY($userId) || EMPTY($idToken) Then
      Return null;
   End
   User $user := User:Get($userId);
   String $firstName := CAST(String, Auth:GetJwtClaim($idToken, 'given_name'));
   String $lastName := CAST(String, Auth:GetJwtClaim($idToken, 'family_name'));
   If ! EMPTY($firstName) Then
      $user.setFirstName($firstName);
   End
   If ! EMPTY($lastName) Then
      $user.setLastName($lastName);
   End
End

OIDC Token Endpoint Client Authentication Methods

The OpenID Connect (OIDC) protocol defines several methods for client authentication when interacting with the token endpoint.

These methods can be configured by setting the Token Endpoint Authentication Method in OpenID Connect Providers configuration page. If this field is not set, the client_secret_basic method is used.

The following values can be configured:

  • client_secret_basic — HTTP Basic authentication with client secret as the password.
  • client_secret_post — Client id and secret are sent in the POST body.
  • private_key_jwt — Uses JWT Bearer Token for client authentication by including the client_assertion_type and client_assertion parameters in POST body, where:
    • client_assertion_type is set to urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
    • client_assertion contains a JWT that follows this specification: RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants. The JWT is signed using RS256 algorithm and a private key stored in FNZ Studio key store with the following alias: privatekeyjwt_<client_id> where <client_id> is the values configured in Client ID field. See the Key Handling section below for more details.

Key Handling in FNZ Studio

For handling keys in FNZ Studio, the following options are available:

  • You can use the JsonWebKeys Extension to generate and store a Key Pair and a certificate in FNZ Studio. Example:

    Copy

          String $clientId := '031517c6-a96c-4f16-be44-e2c55279029d';

          Auth:GenerateKeyPair('privatekeyjwt_' & $clientId, '')`;

    The public key will be made available at <studio-host>/.well-known/jwks.json. This endpoint can be set up in the OpenID Connect Provider configuration, or alternatively, the key can be formatted as required (e.g. PEM format) and uploaded through the Provider interface.

  • You can generate a key pair using a tool such as OpenSSL, and then import the key into FNZ Studio. Following is an example of how to generate the key pair and certificate (ensure that you modify the parameters and specify the correct expiration date of the certificate):

    Copy
          # Generate a private key and a self-signed certificate
          openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout private_key.pem -out certificate.pem -subj "/C=CH/ST=State/L=City/O=Organization/CN=CommonName"

          # Combine the private key and the certificate into a PKCS#12 file
          openssl pkcs12 -export -out keystore.p12 -inkey private_key.pem -in certificate.pem -password pass:

    Following is an example of how to import the above key in FNZ Studio:

    Copy
          String $clientId := '031517c6-a96c-4f16-be44-e2c55279029d';
          AddPrivateKey('privatekeyjwt_' & $clientId, 'keystore.p12', '');