Common Procedure API

This section describes the common API available to all procedures in Curity.

For a full reference, check the Procedures API Documentation.

This API can effectively be extended by the use of Global Scripts because, as the common API, global scripts are also available to all procedures.

Common Procedure Objects

The following objects are available to all procedures:

They are global variables, hence can be accessed easily anywhere. Example usages are shown later on in this document.

Many more objects are exposed via the context object, explained in the next section.

Procedure Context object

All Javascript procedures in Curity also receive a context object (as an argument to their result function) which gives them access to data and functionality they may need to perform their task.

The type of each context object depends on the kind of procedure.

The following tables associate each kind of procedure to its context type:

Table 34 Procedure context types
Procedure kind Context type
validation-procedure ValidationProcedureContext
claims-provider-procedure ClaimsProviderProcedureContext
transformation-procedure TransformationProcedureContext
credential-transformation-procedure CredentialTransformationProcedureContext
filter-procedure AuthenticatorFilterProcedureContext
event-listener-procedure EventListenerProcedureContext
signing-consentor-display-text SigningConsentorDisplayTextProcedureContext
pre-processing-procedure DcrPreProcessingProcedureContext
post-processing-procedure DcrPostProcessingProcedureContext

Token procedure context types are shown separately below as they may have different types depending on whether OpenID Connect is enabled:

Table 35 Token Procedure context types
Endpoint kind Context type Context type
  OAuth OpenID Connect
oauth-assisted-token AssistedTokenProcedureContext AssistedTokenProcedureContext
oauth-authorize-authorization-code AuthorizeTokenProcedureContext OpenIdConnectAuthorizeTokenProcedureContext
oauth-authorize-implicit AuthorizeTokenProcedureContext OpenIdConnectAuthorizeTokenProcedureContext
oauth-device-authorization DeviceAuthorizationTokenProcedureContext DeviceAuthorizationTokenProcedureContext
oauth-introspect IntrospectionTokenProcedureContext IntrospectionTokenProcedureContext
oauth-introspect-application-jwt IntrospectionTokenProcedureContext IntrospectionTokenProcedureContext
oauth-token-assertion AssertionTokenProcedureContext AssertionTokenProcedureContext
oauth-token-authorization-code AuthorizationCodeTokenProcedureContext OpenIdConnectAuthorizationCodeTokenProcedureContext
oauth-token-backchannel-authentication BackchannelAuthenticationTokenProcedureContext BackchannelAuthenticationTokenProcedureContext
oauth-token-client-credentials ClientCredentialsTokenProcedureContext ClientCredentialsTokenProcedureContext
oauth-token-device-code DeviceCodeTokenProcedureContext OpenIdConnectDeviceCodeTokenProcedureContext
oauth-token-refresh RefreshTokenProcedureContext RefreshTokenProcedureContext
oauth-token-resource-owner-password-credentials PasswordTokenProcedureContext PasswordTokenProcedureContext
oauth-token-token-exchange TokenExchangeProcedureContext TokenExchangeProcedureContext
openid-authorize-hybrid AuthorizeTokenProcedureContext OpenIdConnectAuthorizeTokenProcedureContext
openid-userinfo N/A OpenIdConnectUserinfoTokenProcedureContext

The base class of all context types is ProcedureContext.

The following section shows some common utility objects that may be available to different procedures via the context object. Check each procedure type documentation for a comprehensive list of which objects are available for each type of procedure.

Note

global scripts cannot make use of these objects unless they receive the context from a procedure as a function argument.

Common Operations Examples

Logging information

The logger object is an instance of SLF4J Logger. Usage from JavaScript is as from Java.

Example usage:

Listing 273 Using the logger object
1
2
3
   logger.debug("Format message: {}", parameter)

   logger.warn("Something about {} went wrong: {}", parameter, error)

Using a Data Store

Curity’s Data Sources are accessible from most context objects.

Listing 275 Attributes as Table
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var subjectMap = {"subject": context.subject};
var attributes = dataStore.getAttributes(subjectMap);
var dataRows = attributes.allRows.iterator();
var attributeClaims = {};

 while (dataRows.hasNext()) {
     // row is a Map
     var row = dataRows.next();

     if (row.containsKey("linked_account_id") &&
         row.containsKey("linked_account_domain_name")) {

         console.log("Attributes found and contain linked account");

         // se.curity.identityserver.data.attribute.Attribute
         var linkedAccountId = row["linked_account_id"];
         var linkedAccountDomainName = row["linked_account_domain_name"];

         attribute_data["linked_accounts"].push({
             "id": linkedAccountId,
             "domain": linkedAccountDomainName
         });
     } else {
         console.log("Attributes do not contain linked account: " + attributes);
     }
 }

Throwing Exceptions

Prefer to use errors created by using the exceptionFactory object, as JavaScript errors have no significance in Curity, hence will always result in 500 (Server Error) responses, which may not always be desired.

Listing 276 ExceptionFactory example
1
2
3
4
5
6
function result(context) {
  ...
   //Respond with 400 Bad request
   throw exceptionFactory.badRequestException("your message here");
  ...
}

Serializing and de-serializing JSON

The json object, present in all context objects, can be used to (de)serialize any object, including Java and JS objects, unlike JavaScript’s JSON object, which can only handle JS objects.

Example usage:

Listing 277 context.json usage
1
2
3
4
5
6
7
8
   // serialize JS object
   var jsonString = context.json.toJson({
      data: "example",
      headers: { "Accept": "application/json" }
   });

   // de-serializing an object from a JSON string
   var data = context.json.fromJson(jsonString);

Sending HTTP requests

Many types of context include a ScriptWebServiceClient to make HTTP requests.

This is a configurable object which is normally configured together with the procedure itself.

Example usage:

Listing 278 WebServiceClient usage
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
   var response = context.webServiceClient.get({
      path: "/some/resource",
      headers: { "Accept": "application/json" },
      query: { type: "thing", filter: ["value > 10", "account_id == 'joe'"] }
   });

   if (response.statusCode == 200) {
       // success
       logger.debug(response.body);
   } else {
       logger.warn("Something wrong");
   }

Storing data into a Session

Curity allows procedures to store information inside a user session, making it easy to maintain state related to a particular user flow.

This is accomplished via the ScriptSessionManager object.

Example usage:
Listing 279 SessionManager example
1
2
3
4
5
6
function result(context) {
  ...
  context.sessionManager.put("SomeKey", "SomeValue");
  ...
  var mySavedValue = context.sessionManager.get("SomeKey"); // mySavedValue = "SomeValue"
}

Issuing a token

To issue a token in a token procedure, even though the details depend on what kind of token is being issued, the pattern is normally illustrated by the example below:

Listing 280 Issuing an access token
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function result(context) {
    var delegationData = context.getDefaultDelegationData();
    var issuedDelegation = context.delegationIssuer.issue(delegationData);

    var accessTokenData = context.getDefaultAccessTokenData();
    var accessToken = context.accessTokenIssuer.issue(accessTokenData, issuedDelegation);

    return {
        scope: accessTokenData.scope,
        access_token: accessToken,
        token_type: 'bearer',
        expires_in: secondsUntil(accessTokenData.exp)
    };
}

Many other examples are available at Token Procedure Examples.