Managing dynamic clients in ISVA

Managing dynamic clients in ISVA

Dynamic client registration DCR is a specification that defines mechanism for dynamically registering an OAuth2.0 client with the authorization server.

Registration request contains client metadata, and the resulting response contains the client identifier and client metadata registered for the client.

OAuth 2.0 Dynamic Client Registration Management Protocol specification defines methods for managing dynamic registered clients.

In ISVA as a registration response we return the registration access token.

The specification states While the client secret can expire, the registration access token SHOULD NOT expire while a client is still actively registered. If this token were to expire, a developer or client could be left in a situation where they have no means of retrieving, updating, or deleting the client's registration information.

IBM Security Verify Access (ISVA) Federation module implementation of the DCR produces a registration access token whose lifetime is determined by the access token lifetime settings in the API Protection Definition configuration. We do not create a registration access token which can live forever because of security concerns. In ISVA dynamic clients can only be updated or deleted by themselves or their owner.

Essentially a self token or a token that belong to the owner. Self token is access token generated using the client credentials of the dynamic client. Owner token is the token used as Bearer to register a dynamic client.

This article describes patterns to be able to manage dynamically registered clients.

Before we start off with the patterns, here are details about dynamic clients implementation in ISVA.

Retrieving a dynamic client

  • Dynamic clients can either be retrieved using a runtime call or a management call.
  • Runtime call example, where WsgsynHIiE6jv1O1L27Q is the client identifier.
  • The Bearer token here is an access token generated using the dynamic client_id and client_secret via the client_credentials flow.
curl --location 'https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=WsgsynHIiE6jv1O1L27Q' \
--header 'Authorization: Bearer lVeUyS4XRwyL2K6NrvcX' 

Response
{
    "client_secret_expires_at": 0,
    "owner_username": "clientid",
    "company_name": "Applications Inc",
    "registration_client_uri": "https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=WsgsynHIiE6jv1O1L27Q",
    "client_secret": "5CftLyvWrZg9ew5VZOB8",
    "tos_uri": "https://app.com/tos",
    "client_id_issued_at": 1706836269,
    "redirect_uris": [
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner"
    ],
    "client_id": "WsgsynHIiE6jv1O1L27Q"
}
  • Management call to list all dynamic clients, this lists all dynamic clients irrespective of the API Protection Definition that they belong to.
  • We use Basic authorization header using the lmi username password to authenticate the REST API.
curl --location 'https://isam.myidp.ibm.com/iam/access/v8/dynamic_clients' \
--header 'Authorization: Basic YWRtaW46UGFzc3cwcmQ='

Response
[
	...
    {
        "owner": "clientid",
        "clientId": "WsgsynHIiE6jv1O1L27Q",
        "data": {
            "company_name": "Applications Inc",
            "registration_client_uri": "https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=WsgsynHIiE6jv1O1L27Q",
            "tos_uri": "https://app.com/tos",
            "redirect_uris": [
                "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner"
            ],
            "client_id_issued_at": 1706836269,
            "client_secret": "5CftLyvWrZg9ew5VZOB8"
        },
        "definitionId": 1
    },
	...
]

Updating a dynamic client

  • Dynamic clients can either be updated using a runtime call or a management call.
  • Runtime call example, where WsgsynHIiE6jv1O1L27Q is the client identifier.
curl --location --request PUT 'https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=WsgsynHIiE6jv1O1L27Q' \
--header 'Authorization: Bearer lVeUyS4XRwyL2K6NrvcX' \
--header 'Content-Type: application/json' \
--data '{
    "redirect_uris": [
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner",
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner1",
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner2"
    ],
    "company_name": "ACME Industries"
}'

Response
Status Code 204
  • Management call to update a specific dynamic client. Note that mandatory parameter such as client_secret cannot be removed.
curl --location --request PUT 'https://isam.myidp.ibm.com/iam/access/v8/dynamic_clients/WsgsynHIiE6jv1O1L27Q' \
--header 'conte;' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46UGFzc3cwcmQ=' \
--data '{
"data":{
    
    "redirect_uris": [
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner3"
    ],
    "company_name": "ACME Industries",
    "client_secret": "5CftLyvWrZg9ew5VZOB8"
}
}'

Response
Status Code 204

Accessing dynamic clients in pre or a post token mapping rule

  • During a runtime flow involving dynamic client, a global parameter called oauth_client is set.
  • oauth_client exposes functions similar to OAuthMappingExtUtils.getclient(client_id), for static cleint.
  • Supported utilities are
        oauth_client.getDefinitionID(),
        oauth_client.getClientId(),
        oauth_client.getClientSecret(),
        oauth_client.isConfidential(),
        oauth_client.isRequirePkce(),
        oauth_client.getDisplayName(),
        oauth_client.getRedirectUri(),
        oauth_client.getRedirectUris(),
        oauth_client.getJwksUri(), 
        oauth_client.getEncryptionDb(),
        oauth_client.getEncryptionCert(),
        oauth_client.getExtendedData(),
        oauth_client.getEmailAddress(),
        oauth_client.getContactType(),
        oauth_client.getContactPerson(),
        oauth_client.getCompanyName()
    
  • An example Snippet of the utilities in the pre token mapping.
IDMappingExtUtils.traceString("oauth_client.getDefinitionID():"+oauth_client.getDefinitionID());

IDMappingExtUtils.traceString("oauth_client.getClientId():"+oauth_client.getClientId());

IDMappingExtUtils.traceString("oauth_client.getClientSecret():"+oauth_client.getClientSecret());

IDMappingExtUtils.traceString("oauth_client.isConfidential():"+oauth_client.isConfidential());

IDMappingExtUtils.traceString("oauth_client.isRequirePkce():"+oauth_client.isRequirePkce());

IDMappingExtUtils.traceString("oauth_client.getDisplayName():"+oauth_client.getDisplayName());

IDMappingExtUtils.traceString("oauth_client.getRedirectUri():"+oauth_client.getRedirectUri());

IDMappingExtUtils.traceString("oauth_client.getJwksUri():"+oauth_client.getJwksUri());

IDMappingExtUtils.traceString("oauth_client.getEncryptionDb():"+oauth_client.getEncryptionDb());

IDMappingExtUtils.traceString("oauth_client.getEncryptionCert():"+oauth_client.getEncryptionCert());

IDMappingExtUtils.traceString("oauth_client.getDynamicData():"+oauth_client.getExtendedData());

IDMappingExtUtils.traceString("oauth_client.getEmailAddress():"+oauth_client.getEmailAddress());

IDMappingExtUtils.traceString("oauth_client.getContactType():"+oauth_client.getContactType());

IDMappingExtUtils.traceString("oauth_client.getContactPerson():"+oauth_client.getContactPerson());

IDMappingExtUtils.traceString("oauth_client.getCompanyName():"+oauth_client.getCompanyName());
  • The trace.log entries looked like this
[2/2/24, 15:51:37:455 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getDefinitionId():1
[2/2/24, 15:51:37:455 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:455 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getClientId():WsgsynHIiE6jv1O1L27Q
[2/2/24, 15:51:37:455 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:455 AEST] 000005e5 id=00000000 com.tivoli.am.fim.pluginframework.PasswordObfuscatorUtility  > getUnObfuscatedPassword ENTRY
[2/2/24, 15:51:37:455 AEST] 000005e5 id=00000000 com.tivoli.am.fim.pluginframework.PasswordObfuscatorUtility  < getUnObfuscatedPassword RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getClientSecret():5CftLyvWrZg9ew5VZOB8
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 com.tivoli.am.fim.pluginframework.PasswordObfuscatorUtility  > getUnObfuscatedPassword ENTRY
...
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.isConfidential():true
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.isRequirePkce():false
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getDisplayName():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getRedirectUri():https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getJwksUri():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getEncryptionDb():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getEncryptionCert():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getDynamicData():{"isOidc":["true"],"company_name":"ACME Industries","registration_client_uri":"https:\/\/www.myidp.ibm.com\/mga\/sps\/oauth\/oauth20\/register\/OIDCDefinition?client_id=WsgsynHIiE6jv1O1L27Q","redirect_uris":["https:\/\/www.mysp.ibm.com\/isam\/sps\/oidc\/rp\/isamrp\/redirect\/partner","https:\/\/www.mysp.ibm.com\/isam\/sps\/oidc\/rp\/isamrp\/redirect\/partner1","https:\/\/www.mysp.ibm.com\/isam\/sps\/oidc\/rp\/isamrp\/redirect\/partner2","https:\/\/www.mysp.ibm.com\/isam\/sps\/oidc\/rp\/isamrp\/redirect\/partner3"],"client_secret":"5CftLyvWrZg9ew5VZOB8","client_id_issued_at":1706836269}
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getEmailAddress():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getContactType():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getContactPerson():null
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[2/2/24, 15:51:37:456 AEST] 000005e5 id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY oauth_client.getCompanyName():ACME Industries

Using client credentials to regenerate registration access token

  • Dynamically register a client using the /register endpoint, look at an example below
curl --location 'https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition' \
--header 'Auhtorization : Bearer LIDA0C8zFu3p4SQ8deYB ' \
--data '{
    "redirect_uris": [
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner"
    ],
    "tos_uri": "https://app.com/tos",
    "company_name": "Applications Inc"
}'
  • The response will contain a registration access token, which is essentially an access token generated by performing client credentials flow using the client id and secret of the dynamic client created in the previous step.
    Response
{
    "client_secret_expires_at": 0,
    "company_name": "Applications Inc",
    "registration_client_uri": "https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=GgpbjTCxOzY2LCrfS2nS",
    "client_secret": "W1vZnxOe399PIauAENKn",
    "owner_username": "clientid",
    "tos_uri": "https://app.com/tos",
    "client_id_issued_at": 1706070187,
    "redirect_uris": [
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner"
    ],
    "registration_access_token": "CGJA0C8zFu3p4SQ8deYB",
    "client_id": "GgpbjTCxOzY2LCrfS2nS"
}
  • The token lifetime is determined by the API Protection Definition lifetime setting. A introspect response of the registration access token looks like this
{
    "scope": "",
    "active": true,
    "token_type": "bearer",
    "exp": 1706073787,
    "iat": 1706070187,
    "client_id": "GgpbjTCxOzY2LCrfS2nS",
    "username": "ggpbjtcxozy2lcrfs2ns"
}
  • When the registration access token expires, the client id and secret of the dynamic client can be used to generate a new access token which can then be used to manage the clients.
curl --location 'https://www.myidp.ibm.com/mga/sps/oauth/oauth20/token' \
--header 'Authorization: Basic Y2xpZW50SUQ6Y2xpZW50U2VjcmV0MQ' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: AMWEBJCT!%2Fmga!JSESSIONID=0000JjCjNKyD3-wkK4-mPMoX-he:5d1a27c9-e88c-475f-ad78-d60cf6c07aa7; PD-S-SESSION-ID=1_2_0_nwUQU2MRPO0I50oDM1CEPOj8lG66N2f0I83QXxm5gFIAewcL' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=GgpbjTCxOzY2LCrfS2nS' \
--data-urlencode 'client_secret=W1vZnxOe399PIauAENKn'```

Response

{
    "access_token": "9OeDwiG0rbuqKyA7QTJZ",
    "scope": "",
    "token_type": "bearer",
    "expires_in": 3599
}

Using mapping rule to extend the lifetime of the registration access token

In ISVA there are mapping rule utilities that can allow you to extend the lifetime of an access token. In this approach the registration access token is extended every time it is used to access the client.

  • Dynamically register a client using the /register endpoint, look at an example below
{
    "client_secret_expires_at": 0,
    "company_name": "Applications Inc",
    "registration_client_uri": "https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=GgpbjTCxOzY2LCrfS2nS",
    "client_secret": "W1vZnxOe399PIauAENKn",
    "tos_uri": "https://app.com/tos",
    "client_id_issued_at": 1706070187,
    "redirect_uris": [
        "https://www.mysp.ibm.com/isam/sps/oidc/rp/isamrp/redirect/partner"
    ],
    "registration_access_token": "CGJA0C8zFu3p4SQ8deYB",
    "client_id": "GgpbjTCxOzY2LCrfS2nS"
}
  • The response will contain a registration access token, which is essentially an access token generated by performing client credentials flow using the client id and secet of the dynamic client created in the previous step.
{
    "scope": "",
    "active": true,
    "token_type": "bearer",
    "exp": 1706073787,
    "iat": 1706070187,
    "client_id": "GgpbjTCxOzY2LCrfS2nS",
    "username": "ggpbjtcxozy2lcrfs2ns"
}
  • Update the post token mapping rule associated with the definition such that the registration access token's lifetime is updated every time it is used to access the dynamic client management endpoints, be it retrieval or update.
var registration_client_uri = stsuu.getContextAttributes().getAttributeValueByNameAndType("registration_client_uri","urn:ibm:names:ITFIM:oauth:response:attribute");
var client_id = stsuu.getContextAttributes().getAttributeValueByNameAndType("client_id","urn:ibm:names:ITFIM:oauth:response:attribute");
var method = stsuu.getContextAttributes().getAttributeValueByNameAndType("method","urn:ibm:names:ITFIM:oauth:method");
IDMappingExtUtils.traceString("Original registration_client_uri : "+registration_client_uri);

if(request_type == "client_register"){
	if(registration_client_uri != null && client_id != null){
		stsuu.getContextAttributes().removeAttributeByNameAndType("registration_client_uri","urn:ibm:names:ITFIM:oauth:response:attribute");
		var new_registration_uri = registration_client_uri.split("\\?")[0] + "/" + client_id;
		IDMappingExtUtils.traceString("New registration_client_uri : "+new_registration_uri);
		stsuu.addContextAttribute(new com.tivoli.am.fim.trustserver.sts.uuser.Attribute("registration_client_uri","urn:ibm:names:ITFIM:oauth:response:attribute",new_registration_uri));
		if(method=="POST"){
			var rat = stsuu.getContextAttributes().getAttributeValueByNameAndType("registration_access_token","urn:ibm:names:ITFIM:oauth:response:attribute");
		}
	}
	if(client_id != null){
		if(method == "GET" || method == "PUT"){
			var tokens = OAuthMappingExtUtils.getTokens​(client_id, client_id);
			for(var i = 0; i < tokens.length; i++) {
				OAuthMappingExtUtils.updateToken(tokens[i].getId(), 86400, null, true);
			}
		}
	}
}
  • The trace logs look like this when a GET request is made to a client.
curl --location 'https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition?client_id=CRVvHu4ZZEhPLvhkbE4G' \
--header 'Authorization: Bearer Pxk9wOKtH95uJhdCcaF8' \
--header 'Cookie: AMWEBJCT!%2Fmga!JSESSIONID=0000JjCjNKyD3-wkK4-mPMoX-he:5d1a27c9-e88c-475f-ad78-d60cf6c07aa7:211d1a84-9b7f-41c6-8886-093ef5aad12b; PD-S-SESSION-ID=1_2_0_1n1NVWIFD6UV+MNtBI+bqrfGFxipCm31dUzTGyZpKhVj1PgO' \
--data ''
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils > traceString ENTRY New registration_client_uri : https://www.myidp.ibm.com/mga/sps/oauth/oauth20/register/OIDCDefinition/CRVvHu4ZZEhPLvhkbE4G
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 om.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils < traceString RETURN
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils > getTokens(clientId, username) ENTRY
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager                           > get(Class<C>) ENTRY
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager$Configuration             > getObject(Class<C>) ENTRY
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager$Configuration             3 getObject(Class<C>) Class com.ibm.security.access.utils.DBUsername$UsernameParameters from version 1706073205595.
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager$Configuration             < getObject(Class<C>) RETURN
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager                           < get(Class<C>) RETURN
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils > getTokens ENTRY WHERE CLIENT_ID = ? AND USERNAME = ?
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.persistence.DBConnectionManager            > createConnection ENTRY
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.persistence.DBConnectionManager            1 createConnection JDBC datasource jdbc/hvdb
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.utils.sql.DataSourceWithRetry              > getConnection() ENTRY
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.utils.sql.DataSourceWithRetry              < getConnection() RETURN
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.persistence.DBConnectionManager            1 createConnection JNDI DataSource configured successfully!
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 com.tivoli.am.fim.persistence.DBConnectionManager            < createConnection RETURN
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils 3 getTokens using value Pxk9wOKtH95uJhdCcaF8
[1/24/24, 15:19:50:792 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils 3 getTokens using value Pxk9wOKtH95uJhdCcaF8
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils < getTokens RETURN
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager                           > get(Class<C>) ENTRY
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager$Configuration             > getObject(Class<C>) ENTRY
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager$Configuration             3 getObject(Class<C>) Class com.ibm.security.access.utils.DBUsername$UsernameParameters from version 1706073205595.
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager$Configuration             < getObject(Class<C>) RETURN
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 com.tivoli.am.fim.om.ObjectManager                           < get(Class<C>) RETURN
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils < getTokens(clientId, username) RETURN
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils > updateToken ENTRY Pxk9wOKtH95uJhdCcaF8 86,400 null true
[1/24/24, 15:19:50:793 AEST] 000000df id=00000000 tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils > updateToken ENTRY Pxk9wOKtH95uJhdCcaF8 86,400 null true
  • The disadvantage of this method is that, the dynamic client needs to be accessed for the lifetime of the registration access token to be renewed.