Authentication and Session Modules

An authentication module specifies how a user or client is authenticated. You configure authentication and session modules in your project's conf/authentication.json file.

IDM evaluates authentication modules in the order in which they appear in that file, and uses the first "successful" authentication module it finds. Subsequent modules are not evaluated. In a production environment, you should remove any unused authentication modules from your authentication.json file.

To authenticate a user or client, IDM validates the provided credentials against some resource. That resource can be either an IDM resource such as managed/user or internal/user, or it can be an external resource such as an LDAP server or social identity provider. You should prioritize the authentication modules that query IDM resources over those that query external resources. Prioritizing modules that query external resources can lead to authentication problems for internal users such as openidm-admin.

You can also configure authentication modules in the Admin UI. Select Configure > Authentication then select the Session or Module tab to configure the session module or authentication modules respectively. To change the order of authentication modules in the Admin UI, simply drag the modules up or down so that they appear in the order in which they should be evaluated.

Note

Modifying an authentication module in the Admin UI might affect your current session. In this case, IDM prompts you with the following message:

Your current session may be invalid. Click here to logout and re-authenticate.

When you select the Click here link, IDM logs you out of any current session and returns you to the login screen.

This section describes the supported authentication and session modules and how to configure them to authenticate clients securely.

IDM supports the following authentication and session modules:

JWT_SESSION

IDM supports one session module, the JSON Web Token (JWT) Session Module. When a client authenticates successfully, the JWT Session Module creates a JWT and sets it as a cookie on the response. On subsequent requests, the module checks for the presence of the JWT as a cookie on the request, validates the signature and decrypts it, and checks the expiration time of the JWT.

JWT sessions are entirely stateless, that is, they are not persisted in the backend. All information pertaining to the session is encrypted in the JWT.

When a request to IDM produces a JWT, that value replaces the previous one used to send that request. In this way the JWT is always updated to the latest copy. The idle timeout in the JWT is therefore continuously updated and active sessions are not abruptly killed mid-session.

By default, the JWT cookie is deleted on logout. Deleting the cookie manually ends the session. You can modify what happens to the session after a browser restart by changing the value of the sessionOnly property.

The default JWT Session Module configuration, in conf/authentication.json, is as follows:

"sessionModule" : {
    "name" : "JWT_SESSION",
    "properties" : {
        "maxTokenLifeMinutes" : 120,
        "tokenIdleTimeMinutes" : 30,
        "sessionOnly" : true,
        "isHttpOnly" : true,
        "enableDynamicRoles" : false
    }
}

Important

In a production environment, ensure that only secure cookies are used. To do so, add the following property to the session module configuration:

"isSecure" : true

For more information about this module, see the Class JwtSessionModule JavaDoc.

Attempting to access IDM without the appropriate headers or session cookie results in an HTTP 401 Unauthorized, or HTTP 403 Forbidden, depending on the situation. If you authenticate using a session cookie, you must include an additional header that indicates the origin of the request.

The following example shows a successful authentication attempt and the return of a session cookie:

curl \
--dump-header /dev/stdout \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--cacert ca-cert.pem \
"https://localhost:8443/openidm/managed/user?_queryFilter=true&_fields=_id"
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Cache-Control: no-cache
Set-Cookie: session-jwt=2l0zobpuk6st1b2m7gvhg5zas ...;Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Vary: Accept-Encoding, User-Agent
Content-Length: 82
Server: Jetty(8.y.z-SNAPSHOT)

The following example uses the cookie returned in the response to the previous request, and includes the X-Requested-With header to indicate the origin of the request. The value of the header can be any string, but should be informative for logging purposes. If you do not include the X-Requested-With header, IDM returns HTTP 403 Forbidden:

curl \
--dump-header /dev/stdout \
--header "Cookie: session-jwt=2l0zobpuk6st1b2m7gvhg5zas ..." \
--header "X-Requested-With: OpenIDM Plugin" \
--header "Accept-API-Version: resource=1.0" \
--cacert ca-cert.pem \
"https://localhost:8443/openidm/managed/user?_queryFilter=true&_fields=_id"
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json; charset=UTF-8
Cache-Control: no-cache
Vary: Accept-Encoding, User-Agent
Content-Length: 82
Server: Jetty(8.y.z-SNAPSHOT)

The expiration date of the JWT cookie, January 1, 1970, corresponds to the start of UNIX time. Since that time is in the past, browsers will not store that cookie after the browser session is closed.

To request one-time authentication without a session:

curl \
--dump-header /dev/stdout \
--header "X-OpenIDM-NoSession: true" \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--cacert ca-cert.pem \
--header "Accept-API-Version: resource=1.0" \
"https://localhost:8443/openidm/managed/user?_queryFilter=true&_fields=_id"
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Cache-Control: no-cache
Vary: Accept-Encoding, User-Agent
Content-Length: 82
Server: Jetty(8.y.z-SNAPSHOT)

Authentication requests are logged in the authentication.audit.json file. A successful authentication request is logged as follows:

{
  "_id": "389d15d3-bdd5-4521-ae3c-bf096d334405-915",
  "timestamp": "2019-08-02T11:53:31.110Z",
  "eventName": "SESSION",
  "transactionId": "389d15d3-bdd5-4521-ae3c-bf096d334405-912",
  "trackingIds": [
    "5f9f4941-bcbd-4cbc-97f7-e763808e4310",
    "88973bcf-0d60-41b8-9922-73718ce76e11"
  ],
  "userId": "openidm-admin",
  "principal": [
    "openidm-admin"
  ],
  "entries": [
    {
      "moduleId": "JwtSession",
      "result": "SUCCESSFUL",
      "info": {
        "org.forgerock.authentication.principal": "openidm-admin"
      }
    }
  ],
  "result": "SUCCESSFUL",
  "provider": null,
  "method": "JwtSession"
}

For information about querying this log, see Query the Authentication Audit Log.

Deterministic ECDSA signatures

By default, JWTs are signed with deterministic Elliptic Curve Digital Signature Algorithm (ECDSA). In order to use this more secure signing method, you must install Bouncy Castle. If Bouncy Castle is unavailable or the key is incompatible, IDM falls back to normal ECDSA.

Note

If you need to turn off the use of deterministic ECDSA, add the following line to conf/system.properties:

org.forgerock.secrets.preferDeterministicEcdsa=false

STATIC_USER

The STATIC_USER module provides an authentication mechanism that avoids database lookups by hard coding a static user. IDM includes a default anonymous static user, but you can create any static user for this module.

The following sample REST call uses STATIC_USER authentication with the anonymous user in the self-registration process:

curl \
--header "X-OpenIDM-Password: anonymous" \
--header "X-OpenIDM-Username: anonymous" \
--header "Accept-API-Version: resource=1.0" \
--cacert ca-cert.pem \
--header "Content-Type: application/json" \
--request POST \
--data '{
  "userName": "steve",
  "givenName": "Steve",
  "sn": "Carter",
  "telephoneNumber": "0828290289",
  "mail": "scarter@example.com",
  "password": "Passw0rd"
}' \
"https://localhost:8443/openidm/managed/user/?_action=create"

Note

This is not the same as an anonymous request that is issued without headers.

Authenticating with the STATIC_USER module avoids the performance cost of reading the database for self-registration, certain UI requests, and other actions that can be performed anonymously. Authenticating the anonymous user with the STATIC_USER module is identical to authenticating the anonymous user with the INTERNAL_USER module, except that the database is not accessed. So, STATIC_USER authentication provides an authentication mechanism for the anonymous user that avoids the database lookups incurred when using INTERNAL_USER.

A sample STATIC_USER authentication configuration follows:

{
    "name" : "STATIC_USER",
    "enabled" : true,
    "properties" : {
        "queryOnResource" : "internal/user",
        "username" : "anonymous",
        "password" : "anonymous",
        "defaultUserRoles" : [
            "internal/role/openidm-reg"
        ]
    }
}

IDM also uses the STATIC_USER module to set the password and default roles of the openidm-admin internal user on startup. The following configuration in the authentication.json file sets up the openidm-admin user:

{
    "name" : "STATIC_USER",
    "properties" : {
        "queryOnResource" : "internal/user",
        "username" : "openidm-admin",
        "password" : "&{openidm.admin.password}",
        "defaultUserRoles" : [
            "internal/role/openidm-authorized",
            "internal/role/openidm-admin"
        ]
    },
    "enabled" : true
}

For information on changing the default openidm-admin password, see "Change the Administrator User Password".

TRUSTED_ATTRIBUTE

The TRUSTED_ATTRIBUTE authentication module lets you configure IDM to trust a specific HttpServletRequest attribute. To enable this module, add it to your authentication.json file as follows:

{
    "name" : "TRUSTED_ATTRIBUTE",
    "properties" : {
        "queryOnResource" : "managed/user",
        "propertyMapping" : {
            "authenticationId" : "userName",
            "userRoles" : "authzRoles"
        },
        "defaultUserRoles" : [ ],
        "authenticationIdAttribute" : "X-ForgeRock-AuthenticationId",
        "augmentSecurityContext" : {
            "type" : "text/javascript",
            "file" : "auth/populateRolesFromRelationship.js"
        }
    },
    "enabled" : true
}

TRUSTED_ATTRIBUTE authentication queries the managed/user resource, and allows authentication when credentials match, based on the username and authzRoles assigned to that user, specifically the X-ForgeRock-AuthenticationId attribute.

For a sample implementation of a custom servlet filter and the Trusted Request Attribute Authentication Module, see Authenticate Using a Trusted Servlet Filter.

MANAGED_USER

MANAGED_USER authentication queries the repository and allows authentication if the credentials match. Despite the module name, the query is not restricted to managed/user objects. The resource that is queried is configurable. The default configuration uses the username and password of a managed user to authenticate, as shown in the following sample configuration:

{
    "name" : "MANAGED_USER",
    "properties" : {
        "augmentSecurityContext": {
            "type" : "text/javascript",
            "source" : "require('auth/customAuthz').setProtectedAttributes(security)"
        },
        "queryId" : "credential-query",
        "queryOnResource" : "managed/user",
        "propertyMapping" : {
            "authenticationId" : "username",
            "userCredential" : "password",
            "userRoles" : "authzRoles"
        },
        "defaultUserRoles" : [
            "internal/role/openidm-authorized"
        ]
    },
    "enabled" : true
}

Use the augmentSecurityContext property to add custom properties to the security context of users who authenticate with this module. By default, this property adds a list of protected properties to the user's security context. These protected properties are defined in the managed object schema. The isProtected property is described in "Create and Modify Object Types".

INTERNAL_USER

INTERNAL_USER authentication queries the internal/user objects in the repository and allows authentication if the credentials match. The default configuration uses the username and password of the internal user to authenticate, as shown in the following sample configuration:

{
    "name" : "INTERNAL_USER",
    "enabled" : true,
    "properties" : {
        "queryId" : "credential-internaluser-query",
        "queryOnResource" : "internal/user",
        "propertyMapping" : {
            "authenticationId" : "username",
            "userCredential" : "password",
            "userRoles" : "authzRoles"
        },
        "defaultUserRoles" : [ ]
    }
}

CLIENT_CERT

The client certificate module, CLIENT_CERT, authenticates by validating a client certificate, transmitted through an HTTP request. IDM compares the subject DN of the request certificate with the subject DN of the truststore.

A sample CLIENT_CERT authentication configuration follows:

{
  "name" : "CLIENT_CERT",
  "properties" : {
    "augmentSecurityContext" : {
      "type" : "text/javascript",
      "globals" : { },
      "file" : "auth/mapUserFromClientCert.js"
    },
    "queryOnResource" : "managed/user",
    "defaultUserRoles" : [
      "internal/role/openidm-cert",
      "internal/role/openidm-authorized"
    ],
    "allowedAuthenticationIdPatterns" : [
      ".*CN=localhost, O=ForgeRock.*"
    ]
  },
  "enabled" : true
}

Client certificate authentication occurs as part of the SSL or TLS handshake, which takes place before any data is transmitted in an SSL or TLS session. This is also called mutual SSL authentication and is typically used in the following scenarios:

  • When the client is a password plugin, such as those described in the Password Synchronization Plugin Guide, the client authenticates with IDM using the CLIENT_CERT module. This process is similar to an administrative request to modify the passwords of regular users.

  • When users have secure certificates that they install in their browsers for authentication and authorization.

To enable IDM to authenticate client certificates, add the CLIENT_CERT module to your project's conf/authentication.json file and modify the module to match your deployment. You can use the sample file, /path/to/openidm/samples/example-configurations/conf/client-cert/authentication.json, as a basis for your configuration.

Note

When a user authenticates with a client certificate, they receive the roles listed in the defaultUserRoles property of the CLIENT_CERT module. There is no further role retrieval and population.

Test Client Certificate Authentication

This procedure demonstrates client certificate authentication by generating a self-signed certificate, adding that certificate to the truststore, then authenticating with the certificate. At the end of this procedure, you will verify the certificate over port 8444 as defined in your project's resolver/boot.properties file:

openidm.auth.clientauthonlyports=8444

The example assumes an existing managed user, bjensen, with email address bjensen@example.com.

  1. Create a self-signed certificate for user bjensen as follows:

    openssl req \
    -x509 \
    -newkey rsa:1024 \
    -keyout /path/to/key.pem \
    -out /path/to/cert.pem \
    -days 3650 \
    -nodes
    Generating a 1024 bit RSA private key
    .................++++++
    ..................++++++
    writing new private key to 'key.pem'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) []:US
    State or Province Name (full name) []:Washington
    Locality Name (eg, city) []:Vancouver
    Organization Name (eg, company) []:Example.com
    Organizational Unit Name (eg, section) []:
    Common Name (eg, fully qualified host name) []:localhost
    Email Address []:bjensen@example.com

    Note

    The Email Address is used by the mapUserFromClientCert.js to map the user against an existing managed user.

  2. Import the client certificate into the IDM truststore:

    keytool \
    -importcert \
    -keystore /path/to/openidm/security/truststore \
    -storetype JKS \
    -storepass changeit \
    -file /path/to/cert.pem \
    -trustcacerts \
    -noprompt \
    -alias client-cert-example
    Certificate was added to keystore

    By default, users can authenticate only if their certificates have been issued by a Certificate Authority (CA) that is listed in the truststore. The default truststore includes several trusted root CA certificates, and any user certificate issued by those CAs will be trusted. Change the value of this property to restrict certificates to those issued to users in your domain, or use some other regular expression to limit who will be trusted. If you leave this property empty, no certificates will be trusted.

  3. Edit your project's conf/authentication.json file. Add the CLIENT_CERT module, and add at least the email address from the certificate subject DN to the allowedAuthenticationIdPatterns:

    {
      "name": "CLIENT_CERT",
      "properties": {
        "augmentSecurityContext": {
          "type": "text/javascript",
          "globals": {},
          "file": "auth/mapUserFromClientCert.js"
        },
        "queryOnResource": "managed/user",
        "defaultUserRoles": [
          "internal/role/openidm-cert",
          "internal/role/openidm-authorized"
        ],
        "allowedAuthenticationIdPatterns": [
          ".*EMAILADDRESS=bjensen@example.com.*"
        ]
      },
      "enabled": true
    }

    Note

    The allowedAuthenticationIdPatterns property is unique to this authentication module. This property contains a regular expression that defines which user distinguished names (DNs) are allowed to authenticate with a certificate.

  4. Send an HTTP request with your certificate file cert.pem to the secure port:

    curl \
    --insecure \
    --cert-type PEM \
    --key /path/to/key.pem \
    --key-type PEM \
    --cert /path/to/cert.pem \
    --request GET "https://localhost:8444/openidm/info/login"
    {
      "_id": "login",
      "authenticationId": "EMAILADDRESS=bjensen@example.com, CN=localhost, O=Example.com, L=Vancouver, ST=Washington, C=US",
      "authorization": {
        "userRolesProperty": "authzRoles",
        "component": "managed/user",
        "authLogin": false,
        "roles": [
          "internal/role/openidm-cert",
          "internal/role/openidm-authorized"
        ],
        "ipAddress": "0:0:0:0:0:0:0:1",
        "id": "aba3e666-c0db-4669-8760-0eb21f310649",
        "moduleId": "CLIENT_CERT"
      }
    }

    Note

    Because we have used a self-signed certificate in this example, you must include the --insecure option. You should not include this option if you are using a CA cert.

Note

You must use the X-Requested-With header for HTTP-based requests that use the CLIENT_CERT authentication module. You must also add the openidm-admin authorization role for bjensen before making the following example request:

curl \
--insecure \
--cert-type PEM \
--key /path/to/key.pem \
--key-type PEM \
--cert /path/to/cert.pem \
--header "X-Requested-With: curl" \
--request GET "https://localhost:8444/openidm/managed/user?_queryFilter=true"
{
  "result": [
    {
      "_id": "c7b739d3-5546-414a-9c96-29d10a97356d",
      "_rev": "0000000009cff078",
      "preferences": {
        "updates": false,
        "marketing": false
      },
      "mail": "scarter@example.com",
      "sn": "Carter",
      "givenName": "Steve",
      "userName": "scarter",
      "accountStatus": "active",
      "effectiveRoles": [],
      "effectiveAssignments": []
    }
  ],
  ...
}

PASSTHROUGH

PASSTHROUGH authentication queries an external system, such as an LDAP server, and allows authentication if the credentials included in the REST request match those in the external system.

The following excerpt of an authentication.json shows a pass-through authentication configuration for an LDAP system:

"authModules" : [
    {
       "name" : "PASSTHROUGH",
       "enabled" : true,
       "properties" : {
          "augmentSecurityContext": {
             "type" : "text/javascript",
             "file" : "auth/populateAsManagedUser.js"
          },
          "queryOnResource" : "system/ldap/account",
          "propertyMapping" : {
             "authenticationId" : "uid",
             "groupMembership" : "ldapGroups"
          },
          "groupRoleMapping" : {
             "internal/role/openidm-admin" : ["cn=admins,ou=Groups,dc=example,dc=com"]
          },
          "managedUserLink" : "systemLdapAccounts_managedUser",
          "defaultUserRoles" : [
             "internal/role/openidm-authorized"
          ]
       },
    },
    ...
]

For more information on authentication module properties, see Authentication and Session Module Configuration.

Many of the documented samples are configured for pass-through authentication. For example, the sync-with-ldap* samples use an external LDAP system for authentication.

SOCIAL_PROVIDERS

The SOCIAL_PROVIDERS module enables authentication through social identity providers that comply with OAuth 2.0 and OpenID Connect 1.0 standards. For information about configuring this module with social identity providers such as Google, LinkedIn, and Facebook, see "Configuring the Social Providers Authentication Module".

The /path/to/openidm/audit/authentication.audit.json log file shows the corresponding SOCIAL_AUTH module, used to handle authentication for each social identity provider.

OAUTH_CLIENT

The OAUTH_CLIENT authentication module lets you authenticate with any OAuth 2.0-compatible client.

Unlike the social ID providers, this module is used for authentication only, not for registration. If users have registered through one of the social ID providers, and now have managed user accounts in the IDM repository, you can effectively "turn off" the social provider module, and use only this module to let your users authenticate.

The following sample excerpt of an authentication.json file shows the module configuration for authentication after successful registration through Google:

{
    "name" : "OAUTH_CLIENT",
    "properties" : {
        "propertyMapping" : {
            "authenticationId" : "uid",
            "userRoles" : "authzRoles"
        },
        "defaultUserRoles" : [
            "internal/role/openidm-authorized"
        ],
        "idpConfig" : {
            "provider" : "Google",
            "scope" : [
                "openid"
            ],
            "authenticationIdKey" : "sub",
            "clientId" : "ID",
            "clientSecret" : "secret",
            "authorizationEndpoint" : "https://accounts.google.com/o/oauth2/v2/auth",
            "tokenEndpoint" : "https://www.googleapis.com/oauth2/v4/token",
            "wellKnownEndpoint" : "https://accounts.google.com/.well-known/openid-configuration",
            "redirectUri" : "https://openidm.example.com:8443/",
            "configClass" : "org.forgerock.oauth.clients.oidc.OpenIDConnectClientConfiguration",
            "displayIcon" : "forgerock",
            "enabled" : true
        },
        "queryOnResource" : "managed/user"
    },
    "enabled" : true
}

For more information on authentication module properties, see Authentication and Session Module Configuration.

Note

To enable a social identity provider that fully complies with OAuth 2.0 standards, use the IDM SOCIAL_PROVIDERS authentication module wrapper. This module is a specialized facility for sharing a social identity provider configuration with the authentication service, which you can configure as if it were a separate authentication module. For more information, see "Configuring the Social Providers Authentication Module".

IWA

The IWA module lets users authenticate using Integrated Windows Authentication (IWA) with Kerberos instead of a username and password.

Windows, UNIX, and Linux systems support Kerberos v5 authentication, which can operate safely on an open, unprotected network. With Kerberos authentication, the user or client application obtains temporary credentials for a service from an authorization server, in the form of tickets and session keys. The service server handles its part of the Kerberos mutual authentication process.

To enable Kerberos authentication, IDM requires a specific Kerberos user account in Active Directory, and a keytab file that maps the service principal to this user account. The client presents IDM with a Kerberos ticket. If IDM can validate the ticket, the client is granted an encrypted session key for the IDM service. That client can then access IDM without providing a username or password, for the duration of the session.

The complete Kerberos authentication process is shown in the following diagram:

Client Authentication to IDM Using a Kerberos Ticket
Client Authenticates to IDM Using a Kerberos Ticket

This section assumes that you have an active Kerberos server acting as a Key Distribution Center (KDC). If you are running Active Directory, that service includes a Kerberos KDC by default.

The steps required to set up IWA with IDM are described in the following sections:

Creating a Specific Kerberos User Account

To authenticate IDM to the Kerberos KDC you must create a specific user entry in Active Directory whose credentials will be used for this authentication. This Kerberos user account must not be used for anything else.

The Kerberos user account is used to generate the Kerberos keytab. If you change the password of this Kerberos user after you have set up IWA, you must update the keytab accordingly.

Create a new user in Active Directory as follows:

  1. Select New > User and provide a login name for the user that reflects its purpose, for example, openidm@example.com.

  2. Enter a password for the user. Check the Password never expires option and leave all other options unchecked.

    If the password of this user account expires, and is reset, you must update the keytab with the new password. It is therefore easier to create an account with a password that does not expire.

  3. Click Finish to create the user.

Creating a Keytab File

A Kerberos keytab file (krb5.keytab) enables IDM to validate the Kerberos tickets that it receives from client browsers. You must create a Kerberos keytab file for the host on which IDM is running.

This section describes how to use the ktpass command, included in the Windows Server toolkit, to create the keytab file. Run the ktpass command on the Active Directory domain controller.

Important

  • The keytab file is case-sensitive, so you must note the use of capitalization in this example.

  • You must disable UAC or run the ktpass command as a user with administrative privileges.

The following command creates a keytab file (named openidm.HTTP.keytab) for the IDM service located at openidm.example.com.

C:\Users\Administrator>ktpass ^
-princ HTTP/openidm.example.com@EXAMPLE.COM ^
-mapUser EXAMPLE\openidm ^
-mapOp set ^
-pass Passw0rd1 ^
-crypto ALL
-pType KRB5_NT_PRINCIPAL ^
-kvno 0 ^
-out openidm.HTTP.keytab

Targeting domain controller: host.example.com
Using legacy password setting method
Successfully mapped HTTP/openidm.example.com to openidm.
Key created.
Output keytab to openidm.HTTP.keytab:
Keytab version: 0x502
keysize 79 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
 vno 0 etype 0x1 (DES-CBC-CRC) keylength 8 (0x73a28fd307ad4f83)
keysize 79 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
 vno 0 etype 0x3 (DES-CBC-MD5) keylength 8 (0x73a28fd307ad4f83)
keysize 87 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
 vno 0 etype 0x17 (RC4-HMAC) keylength 16 (0xa87f3a337d73085c45f9416be5787d86)
keysize 103 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
 vno 0 etype 0x12 (AES256-SHA1) keylength 32 (0x6df9c282abe3be787553f23a3d1fcefc
  6fc4a29c3165a38bae36a8493e866d60)
keysize 87 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
 vno 0 etype 0x11 (AES128-SHA1) keylength 16 (0xf616977f071542cd8ef3ff4e2ebcc09c)

The ktpass command takes the following options:

  • -princ specifies the service principal name in the format service/host-name@realm

    In this example (HTTP/openidm.example.com@EXAMPLE.COM), the client browser constructs an SPN based on the following:

    • The service name (HTTP).

      The service name for SPNEGO web authentication must be HTTP.

    • The FQDN of the host on which IDM runs (openidm.example.com).

      This example assumes that users will access IDM at the URL https://openidm.example.com:8443.

    • The Kerberos realm name (EXAMPLE.COM).

      The realm name must be uppercase. A Kerberos realm defines the area of authority of the Kerberos authentication server.

  • -mapUser specifies the name of the Kerberos user account to which the principal should be mapped (the account that you created in "Creating a Specific Kerberos User Account"). The username must be specified in down-level logon name format (DOMAIN\UserName). In our example, the Kerberos user name is EXAMPLE\openidm.

  • -mapOp specifies how the Kerberos user account is linked. Use set to set the first user name to be linked. The default (add) adds the value of the specified local user name if a value already exists.

  • -pass specifies a password for the principal user name. Use * to prompt for a password.

  • -crypto specifies the cryptographic type of the keys that are generated in the keytab file. Use ALL to specify all crypto types.

    This procedure assumes a 128-bit cryptosystem, with a default RC4-HMAC-NT cryptography algorithm. You can use the ktpass command to view the crypto algorithm, as follows:

    C:\Users\Administrator>ktpass -in .\openidm.HTTP.keytab
    Existing keytab:
    Keytab version: 0x502
    keysize 79 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
     vno 0 etype 0x1 (DES-CBC-CRC) keylength 8 (0x73a28fd307ad4f83)
    keysize 79 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
     vno 0 etype 0x3 (DES-CBC-MD5) keylength 8 (0x73a28fd307ad4f83)
    keysize 87 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
     vno 0 etype 0x17 (RC4-HMAC) keylength 16 (0xa87f3a337d73085c45f9416be5787d86)
    keysize 103 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
     vno 0 etype 0x12 (AES256-SHA1) keylength 32 (0x6df9c282abe3be787553f23a3d1fcefc6
     fc4a29c3165a38bae36a8493e866d60)
    keysize 87 HTTP/openidm.example.com@EXAMPLE.COM ptype 1 (KRB5_NT_PRINCIPAL)
     vno 0 etype 0x11 (AES128-SHA1) keylength 16 (0xf616977f071542cd8ef3ff4e2ebcc09c)
    
  • -ptype Specifies the principal type. Use KRB5_NT_PRINCIPAL.

  • -kvno specifies the key version number. Set the key version number to 0.

  • -out specifies the name of the keytab file that will be generated, for example, openidm.HTTP.keytab.

    Note

    The keys that are stored in the keytab file are similar to user passwords. You must protect the Kerberos keytab file in the same way that you would protect a file containing passwords.

For more information about the ktpass command, see the ktpass reference in the Windows server documentation.

Configuring IDM for IWA

To configure the IWA authentication module, add the module to your project's conf/authentication.json file.

This section assumes that the connection from IDM to the Active Directory Server is through an LDAP connector, and that the mapping from managed users to the users in Active Directory (in your project's conf/sync.json file) identifies the Active Directory target as system/ad/account. If you have named the target differently, modify the "queryOnResource" : "system/ad/account" property accordingly.

Add the IWA authentication module towards the end of your conf/authentication.json file. For example:

"authModules" : [
    ...
    {
        "name": "IWA",
        "properties": {
            "servicePrincipal": "HTTP/openidm.example.com@EXAMPLE.COM",
            "keytabFileName": "C:\\Users\\Administrator\\openidm\\security\\openidm.HTTP.keytab",
            "kerberosRealm": "EXAMPLE.COM",
            "kerberosServerName": "kdc.example.com",
            "queryOnResource": "system/ad/account",
            "maxTokenSize": 48000,
            "propertyMapping": {
                "authenticationId": "sAMAccountName",
                "groupMembership": "memberOf"
            },
            "groupRoleMapping": {
                "internal/role/openidm-admin": [ ]
            },
            "groupComparisonMethod": "ldap",
            "defaultUserRoles": [
                "internal/role/openidm-authorized"
            ],
            "augmentSecurityContext": {
                "type": "text/javascript",
                "file": "auth/populateAsManagedUser.js"
            }
        },
        "enabled": true
    },
    ...
]

The IWA authentication module includes the following configurable properties:

servicePrincipal

The Kerberos principal for authentication, in the following format:

HTTP/host.domain@DC-DOMAIN-NAME

host and domain correspond to the host and domain names of the IDM server. DC-DOMAIN-NAME is the domain name of the Windows Kerberos domain controller server. The DC-DOMAIN-NAME can differ from the domain name for the IDM server.

keytabFileName

The full path to the keytab file for the Service Principal. On Windows systems, any backslash (\) characters in the path must be escaped, as shown in the previous example.

kerberosRealm

The Kerberos Key Distribution Center realm. For the Windows Kerberos service, this is the domain controller server domain name.

kerberosServerName

The fully qualified domain name of the Kerberos Key Distribution Center server, such as that of the domain controller server.

queryOnResource

The IDM resource to check for the authenticating user; for example, system/ad/account.

maxTokenSize

During the Kerberos authentication process, the Windows server builds a token to represent the user for authorization. This property sets the maximum size of the token, to prevent DoS attacks, if the SPENGO token in the request being made is amended with extra data. The default maximum token size is 48000 bytes.

groupRoleMapping

Enables you to grant different roles to users who are authenticated through the IWA module.

You can use the IWA module in conjunction with the PASSTHROUGH authentication module. In this case, a failure in the IWA module lets users revert to forms-based authentication.

To add the PASSTHROUGH module, follow "PASSTHROUGH".

rsFilter

IDM uses the rsFilter authentication module when you configure IDM to use AM bearer tokens for authentication. This module replaces all other authentication methods.

Important

From IDM 7.0 onwards, using AM bearer tokens for authentication is the only supported method of integrating IDM with AM.

When you use IDM and AM together as a platform, configure IDM to use AM bearer tokens for authentication, instead of setting up traditional authentication modules. This delegates all authentication to AM.

With AM bearer tokens, all IDM endpoints that require authentication are accessed using an authorization header that contains the bearer token, instead of X-OpenIDM-Username and X-OpenIDM-Password. (Endpoints that allow anonymous access can be accessed without a token.)

To use bearer tokens for authentication, your IDM conf/authentication.json file must include the rsFilter authentication module and no other authentication methods.

The following sample authentication.json file is also available in /path/to/openidm/samples/example-configurations/conf/rsfilter/:

{
  "rsFilter": {
    "clientId": "",
    "clientSecret": "",
    "tokenIntrospectUrl": "http://am.example:8080/openam/oauth2/introspect",
    "scopes": [ ],
    "cache" : {
      "maxTimeout" : "300 seconds"
    },
    "subjectMapping" : [
      {
        "queryOnResource": "managed/user",
        "propertyMapping": {
          "sub": "_id"
        },
        "userRoles": "authzRoles/*",
        "defaultRoles" : [
          "internal/role/openidm-authorized"
        ]
      }
    ],
    "staticUserMapping": [
      {
        "subject": "amadmin",
        "localUser": "internal/user/openidm-admin",
        "roles" : [
          "internal/role/openidm-authorized",
          "internal/role/openidm-admin"
        ]
      },
      {
        "subject": "idm-provisioning",
        "localUser": "internal/user/idm-provisioning",
        "roles" : [
          "internal/role/platform-provisioning"
        ]
      }
    ],
    "anonymousUserMapping" : {
      "localUser": "internal/user/anonymous",
      "roles" : [
        "internal/role/openidm-reg"
      ]
    }
  }
}

The rsFilter module includes the following properties:

clientId

The client ID of the AM OAuth 2.0 client used to introspect the bearer token.

clientSecret

The client secret of the AM OAuth 2.0 client used to introspect the bearer token. IDM will encrypt this field if it isn't encrypted already.

tokenIntrospectUrl

The URI to reach the oauth2/introspect endpoint in AM.

scopes

Any scopes that are required to be present in the access token. This will vary depending on your configuration.

cache

Sets the maxTimeout, in seconds, after which the token is removed from the cache.

subjectMapping

An array of mappings that let you map AM realms to IDM managed object types. For example:

"subjectMapping": [
  {
    "realm": "/",
    "queryOnResource": "managed/user",
    "propertyMapping": {
      "sub": "_id"
    },
    "userRoles": "authzRoles/*"
  }
]

Each subjectMapping includes the following properties:

  • realm: The AM realm to which this subject mapping applies. A value of / specifies the top-level realm. If this property is absent, the mapping can apply to any realm, which is useful if the corresponding queryOnResource property uses a dynamic handlebars template (see the example below).

    You cannot have more than one mapping for the same realm, and you cannot have more than one mapping that has no realm in the configuration.

  • queryOnResource: The IDM resource to check for the authenticating user; for example, managed/user.

    This field supports a dynamic handlebars template that lets a single subject mapping match multiple realms, if the managed objects are named prescriptively, and based on the realm name. For example:

    "queryOnResource": "managed/{{substring realm 1}}"

    This configuration lets an access token with the realm employee map to an IDM managed/employee, and an access token with the realm contractor map to an IDM managed/contractor. The configuration is useful if your AM and IDM deployments use a consistent realm and managed object naming.

  • propertyMapping: Maps fields in the AM access token to properties in IDM. This mapping is used to construct the query filter that locates the authenticating user. The default configuration maps the subject (sub) in the access token to the _id in IDM.

  • userRoles: Determines the field to consult for locating the authorization roles; usually authzRoles, unless you have changed how user roles are stored. This field must be a relationship field. IDM uses the _refId from the array elements to populate the user roles in the security context.

Although you can configure an array of subject mappings, only one mapping is selected and used during the authentication process. If there is a realm attribute in the access token, that realm is used to select an appropriate mapping. If no mapping is defined for the access token's realm, or if the realm is not provided in the access token, the authentication uses a mapping that does not define a realm.

Note

If you have a remote connector server that is authenticating against AM, you must add a subject mapping specifically for the connector server. For example:

{
    "subject" : "RCS-OAuth-clientId",
    "localUser" : "internal/user/idm-provisioning"
}

The subject must reflect the OAuth2 client in AM that has been set up for the remote connector server. The localUser can be any existing user. Do not assign that user any roles to ensure that the connector server bearer token cannot be used for any other purpose.

anonymousUserMapping

The default user that will be used when no access token is included in the request. Contains two properties: localUser and userRoles.

  • localUser: the IDM user resource referenced when no specific user is identified. For example, internal/user/anonymous.

  • userRoles: the property that determines what roles the identified user will have. Usually authzRoles, unless you have changed how user roles are stored.

staticUserMapping

Maps AM users to a matching IDM user. Can contain multiple user mappings, each with three properties: subject, localUser, and userRoles.

  • subject of the access token (the AM user).

  • localUser is the IDM user you wish to associate with the AM user identified in subject. For example, if subject is set to amAdmin, you may wish to set localUser to internal/user/openidm-admin.

  • userRoles refers to the property used to determine what roles and access the identified user should have. This will usually be authzRoles, unless you have changed how user roles are stored.

Note

The idm-provisioning user is a service account used by AM to provision users in IDM. Be sure to include this user in your staticUserMapping:

{
  "subject": "idm-provisioning",
  "localUser": "internal/user/idm-provisioning",
  "userRoles": "authzRoles/*"
}

See the Platform Setup Guide for complete instructions on setting up IDM to use AM bearer tokens for authentication.

Read a different version of :