Guide to developing REST clients and scripts. ForgeRock® Access Management provides authentication, authorization, entitlement and federation software.

Preface

This guide provides an introduction to the ForgeRock Access Management REST API, and to developing scripts for client-side and server-side authentication, policy conditions, and handling OpenID Connect claims.

For additional examples of the customizations you can write, see the list below:

  • Custom OAuth 2.0 scopes plugins define how Access Management, when playing the role of authorization server, handles scopes, including which token information to return for scopes set when authorization was granted.

    For more information, see "Customizing OAuth 2.0 Scope Handling" in the OAuth 2.0 Guide.

  • Custom authentication plugins let Access Management authenticate users against a new authentication service or an authentication service specific to your deployment

    For more information, see "Creating a Custom Authentication Module" in the Authentication and Single Sign-On Guide.

  • Post authentication plugins perform additional processing at the end of the authentication process, but before the subject is authenticated. Post authentication plugins can, for example, store information about the authentication in the user's profile, or call another system for audit logging purposes.

    For more information, see "Creating Post-Authentication Plugins for Chains" in the Authentication and Single Sign-On Guide.

  • Policy evaluation plugins implement new policy conditions, send attributes from the user profile as part of a policy response, extend the definition of the subjects to whom the policy applies, or customize how policy management is delegated.

    For more information, see "Customizing Policy Evaluation With a Plug-In" in the Authorization Guide.

  • Identity repository plugins let Access Management employ a new or custom user data store.

    For more information, see "Customizing Identity Data Storage" in the Setup and Maintenance Guide.

About ForgeRock Identity Platform™ Software

ForgeRock Identity Platform™ serves as the basis for our simple and comprehensive Identity and Access Management solution. We help our customers deepen their relationships with their customers, and improve the productivity and connectivity of their employees and partners. For more information about ForgeRock and about the platform, see https://www.forgerock.com.

Chapter 1. Introducing AM APIs

Although web and Java agents and standards support make it possible for applications to use AM for access management without changing your code, some deployments require tighter integration, or direct use of APIs.

AM provides the following application programming interfaces:

  • REST APIs

    AM REST APIs can return JSON or XML over HTTP, allowing you to access authentication, authorization, and identity services from your web applications using REST clients in the language of your choice.

    For more information, see "Developing with the REST API".

  • Java APIs

    AM Java APIs let your Java and Java applications call on AM for authentication and authorization.

    For more information, see the ForgeRock Access Management Java API Specification.

1.1. IPv4 and IPv6

AM provides functionality for IPv4, IPv6, and a hybrid of the two. While the majority of the interaction is done on the backend, there are a few places where the GUI requires some inputs, such as setting up policy conditions. These areas follow the same standard that applies to IPv4 and IPv6. IPv4 uses a 32-bit integer value, with a dot-decimal system. IPv6 uses a hexadecimal system, and the eight groups of hexadecimal digits are separated by a colon.

Chapter 2. Developing with the REST API

This chapter shows how to use the AM RESTful interfaces for direct integration between web client applications and AM.

2.1. Introducing REST

Representational State Transfer (REST) is an architectural style that sets certain constraints for designing and building large-scale distributed hypermedia systems.

As an architectural style, REST has very broad applications. The designs of both HTTP 1.1 and URIs follow RESTful principles. The World Wide Web is no doubt the largest and best known REST application. Many other web services also follow the REST architectural style. Examples include OAuth 2.0, OpenID Connect 1.0, and User-Managed Access (UMA).

The ForgeRock Common REST (CREST) API applies RESTful principles to define common verbs for HTTP-based APIs that access web resources and collections of web resources.

Interface Stability: Evolving

Most native AM REST APIs use the CREST verbs. (In contrast, OAuth 2.0, OpenID Connect 1.0 and UMA APIs follow their respective standards.)

2.2. Introducing the API Explorer

AM provides an online AM REST API reference that can be accessed through the AM administration console. It displays the REST API endpoints that allow client applications to access AM's services.

Tip

The API Explorer is enabled by default. To disable it in production environments, navigate to Configure > Global Services > REST APIs, and select Disabled in the API Descriptors drop-down list.

The key features of the API Explorer are the following:

  • API Versioning. The API Explorer displays the different API versions available depending on your deployment.

    API Explorer
    API Explorer page, which is accessible from the AM console.

  • Detailed Information. The API Explorer provides an Expand Operations button for each available CRUDPAQ method. When Expand Operations is pressed, you can view implementation notes, successful response class, headers, parameters, and response messages with examples. For example, the requestPayload field can be populated with an example value. Also, if you select Model, you can view the schema for each parameter, as seen below:

    API Explorer Request Payload
    The API Explorer page provides a Try It Out function that allows you to see the possible responses to an example request.

  • Try It Out. The API Explorer also provides a Try It Out feature, which allows you to send a sample request to the endpoint and view the possible responses.

    API Explorer Detailed Information
    The API Explorer page displays detailed information for each method.

To Access the API Explorer
  1. Log into the AM console as an administrator.

  2. You can access the API Explorer in one of two ways:

    Point your browser to the following URL:

    https://openam.example.com:8443/openam/XUI/#api/explorer/applications

    You can also click the help icon in the top-right corner, and then click API Explorer.

    API Explorer
    API Explorer page, which is also accessible from the help icon on the AM console.


2.3. About ForgeRock Common REST

ForgeRock® Common REST is a common REST API framework. It works across the ForgeRock platform to provide common ways to access web resources and collections of resources. Adapt the examples in this section to your resources and deployment.

2.3.1. Common REST Resources

Servers generally return JSON-format resources, though resource formats can depend on the implementation.

Resources in collections can be found by their unique identifiers (IDs). IDs are exposed in the resource URIs. For example, if a server has a user collection under /users, then you can access a user at /users/user-id. The ID is also the value of the _id field of the resource.

Resources are versioned using revision numbers. A revision is specified in the resource's _rev field. Revisions make it possible to figure out whether to apply changes without resource locking and without distributed transactions.

2.3.2. Common REST Verbs

The Common REST APIs use the following verbs, sometimes referred to collectively as CRUDPAQ. For details and HTTP-based examples of each, follow the links to the sections for each verb.

Create

Add a new resource.

This verb maps to HTTP PUT or HTTP POST.

For details, see "Create".

Read

Retrieve a single resource.

This verb maps to HTTP GET.

For details, see "Read".

Update

Replace an existing resource.

This verb maps to HTTP PUT.

For details, see "Update".

Delete

Remove an existing resource.

This verb maps to HTTP DELETE.

For details, see "Delete".

Patch

Modify part of an existing resource.

This verb maps to HTTP PATCH.

For details, see "Patch".

Action

Perform a predefined action.

This verb maps to HTTP POST.

For details, see "Action".

Query

Search a collection of resources.

This verb maps to HTTP GET.

For details, see "Query".

2.3.3. Common REST Parameters

Common REST reserved query string parameter names start with an underscore, _.

Reserved query string parameters include, but are not limited to, the following names:

_action
_api
_crestapi
_fields
_mimeType
_pageSize
_pagedResultsCookie
_pagedResultsOffset
_prettyPrint
_queryExpression
_queryFilter
_queryId
_sortKeys
_totalPagedResultsPolicy

Note

Some parameter values are not safe for URLs, so URL-encode parameter values as necessary.

Continue reading for details about how to use each parameter.

2.3.4. Common REST Extension Points

The action verb is the main vehicle for extensions. For example, to create a new user with HTTP POST rather than HTTP PUT, you might use /users?_action=create. A server can define additional actions. For example, /tasks/1?_action=cancel.

A server can define stored queries to call by ID. For example, /groups?_queryId=hasDeletedMembers. Stored queries can call for additional parameters. The parameters are also passed in the query string. Which parameters are valid depends on the stored query.

2.3.5. Common REST API Documentation

Common REST APIs often depend at least in part on runtime configuration. Many Common REST endpoints therefore serve API descriptors at runtime. An API descriptor documents the actual API as it is configured.

Use the following query string parameters to retrieve API descriptors:

_api

Serves an API descriptor that complies with the OpenAPI specification.

This API descriptor represents the API accessible over HTTP. It is suitable for use with popular tools such as Swagger UI.

_crestapi

Serves a native Common REST API descriptor.

This API descriptor provides a compact representation that is not dependent on the transport protocol. It requires a client that understands Common REST, as it omits many Common REST defaults.

Note

Consider limiting access to API descriptors in production environments in order to avoid unnecessary traffic.

To provide documentation in production environments, see "To Publish OpenAPI Documentation" instead.

To Publish OpenAPI Documentation

In production systems, developers expect stable, well-documented APIs. Rather than retrieving API descriptors at runtime through Common REST, prepare final versions, and publish them alongside the software in production.

Use the OpenAPI-compliant descriptors to provide API reference documentation for your developers as described in the following steps:

  1. Configure the software to produce production-ready APIs.

    In other words, the software should be configured as in production so that the APIs are identical to what developers see in production.

  2. Retrieve the OpenAPI-compliant descriptor.

    The following command saves the descriptor to a file, myapi.json:

    $ curl -o myapi.json endpoint?_api
        
  3. (Optional) If necessary, edit the descriptor.

    For example, you might want to add security definitions to describe how the API is protected.

    If you make any changes, then also consider using a source control system to manage your versions of the API descriptor.

  4. Publish the descriptor using a tool such as Swagger UI.

    You can customize Swagger UI for your organization as described in the documentation for the tool.

2.3.6. Create

There are two ways to create a resource, either with an HTTP POST or with an HTTP PUT.

To create a resource using POST, perform an HTTP POST with the query string parameter _action=create and the JSON resource as a payload. Accept a JSON response. The server creates the identifier if not specified:

POST /users?_action=create HTTP/1.1
Host: example.com
Accept: application/json
Content-Length: ...
Content-Type: application/json
{ JSON resource }
  

To create a resource using PUT, perform an HTTP PUT including the case-sensitive identifier for the resource in the URL path, and the JSON resource as a payload. Use the If-None-Match: * header. Accept a JSON response:

PUT /users/some-id HTTP/1.1
Host: example.com
Accept: application/json
Content-Length: ...
Content-Type: application/json
If-None-Match: *
{ JSON resource }
  

The _id and content of the resource depend on the server implementation. The server is not required to use the _id that the client provides. The server response to the create request indicates the resource location as the value of the Location header.

If you include the If-None-Match header, its value must be *. In this case, the request creates the object if it does not exist, and fails if the object does exist. If you include the If-None-Match header with any value other than *, the server returns an HTTP 400 Bad Request error. For example, creating an object with If-None-Match: revision returns a bad request error. If you do not include If-None-Match: *, the request creates the object if it does not exist, and updates the object if it does exist.

Parameters

You can use the following parameters:

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in the body of the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

2.3.7. Read

To retrieve a single resource, perform an HTTP GET on the resource by its case-sensitive identifier (_id) and accept a JSON response:

GET /users/some-id HTTP/1.1
Host: example.com
Accept: application/json
  
Parameters

You can use the following parameters:

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in the body of the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

_mimeType=mime-type

Some resources have fields whose values are multi-media resources such as a profile photo for example.

By specifying both a single field and also the mime-type for the response content, you can read a single field value that is a multi-media resource.

In this case, the content type of the field value returned matches the mime-type that you specify, and the body of the response is the multi-media resource.

The Accept header is not used in this case. For example, Accept: image/png does not work. Use the _mimeType query string parameter instead.

2.3.8. Update

To update a resource, perform an HTTP PUT including the case-sensitive identifier (_id) as the final element of the path to the resource, and the JSON resource as the payload. Use the If-Match: _rev header to check that you are actually updating the version you modified. Use If-Match: * if the version does not matter. Accept a JSON response:

PUT /users/some-id HTTP/1.1
Host: example.com
Accept: application/json
Content-Length: ...
Content-Type: application/json
If-Match: _rev
{ JSON resource }
  

When updating a resource, include all the attributes to be retained. Omitting an attribute in the resource amounts to deleting the attribute unless it is not under the control of your application. Attributes not under the control of your application include private and read-only attributes. In addition, virtual attributes and relationship references might not be under the control of your application.

Parameters

You can use the following parameters:

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in the body of the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

2.3.9. Delete

To delete a single resource, perform an HTTP DELETE by its case-sensitive identifier (_id) and accept a JSON response:

DELETE /users/some-id HTTP/1.1
Host: example.com
Accept: application/json
  
Parameters

You can use the following parameters:

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in the body of the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

2.3.10. Patch

To patch a resource, send an HTTP PATCH request with the following parameters:

  • operation

  • field

  • value

  • from (optional with copy and move operations)

You can include these parameters in the payload for a PATCH request, or in a JSON PATCH file. If successful, you'll see a JSON response similar to:

PATCH /users/some-id HTTP/1.1
Host: example.com
Accept: application/json
Content-Length: ...
Content-Type: application/json
If-Match: _rev
{ JSON array of patch operations }
  

PATCH operations apply to three types of targets:

  • single-valued, such as an object, string, boolean, or number.

  • list semantics array, where the elements are ordered, and duplicates are allowed.

  • set semantics array, where the elements are not ordered, and duplicates are not allowed.

ForgeRock PATCH supports several different operations. The following sections show each of these operations, along with options for the field and value:

2.3.10.1. Patch Operation: Add

The add operation ensures that the target field contains the value provided, creating parent fields as necessary.

If the target field is single-valued, then the value you include in the PATCH replaces the value of the target. Examples of a single-valued field include: object, string, boolean, or number.

An add operation has different results on two standard types of arrays:

  • List semantic arrays: you can run any of these add operations on that type of array:

    • If you add an array of values, the PATCH operation appends it to the existing list of values.

    • If you add a single value, specify an ordinal element in the target array, or use the {-} special index to add that value to the end of the list.

  • Set semantic arrays: The list of values included in a patch are merged with the existing set of values. Any duplicates within the array are removed.

As an example, start with the following list semantic array resource:

{
    "fruits" : [ "orange", "apple" ]
}

The following add operation includes the pineapple to the end of the list of fruits, as indicated by the - at the end of the fruits array.

{
    "operation" : "add",
    "field" : "/fruits/-",
    "value" : "pineapple"
}

The following is the resulting resource:

{
    "fruits" : [ "orange", "apple", "pineapple" ]
}

2.3.10.2. Patch Operation: Copy

The copy operation takes one or more existing values from the source field. It then adds those same values on the target field. Once the values are known, it is equivalent to performing an add operation on the target field.

The following copy operation takes the value from a field named mail, and then runs a replace operation on the target field, another_mail.

[
  {
     "operation":"copy",
     "from":"mail",
     "field":"another_mail"
  }
]

If the source field value and the target field value are configured as arrays, the result depends on whether the array has list semantics or set semantics, as described in "Patch Operation: Add".

2.3.10.3. Patch Operation: Increment

The increment operation changes the value or values of the target field by the amount you specify. The value that you include must be one number, and may be positive or negative. The value of the target field must accept numbers. The following increment operation adds 1000 to the target value of /user/payment.

[
  {
    "operation" : "increment",
    "field" : "/user/payment",
    "value" : "1000"
  }
]

Since the value of the increment is a single number, arrays do not apply.

2.3.10.4. Patch Operation: Move

The move operation removes existing values on the source field. It then adds those same values on the target field. It is equivalent to performing a remove operation on the source, followed by an add operation with the same values, on the target.

The following move operation is equivalent to a remove operation on the source field, surname, followed by a replace operation on the target field value, lastName. If the target field does not exist, it is created.

[
  {
     "operation":"move",
     "from":"surname",
     "field":"lastName"
  }
]

To apply a move operation on an array, you need a compatible single-value, list semantic array, or set semantic array on both the source and the target. For details, see the criteria described in "Patch Operation: Add".

2.3.10.5. Patch Operation: Remove

The remove operation ensures that the target field no longer contains the value provided. If the remove operation does not include a value, the operation removes the field. The following remove deletes the value of the phoneNumber, along with the field.

[
  {
    "operation" : "remove",
    "field" : "phoneNumber"
  }
]

If the object has more than one phoneNumber, those values are stored as an array.

A remove operation has different results on two standard types of arrays:

  • List semantic arrays: A remove operation deletes the specified element in the array. For example, the following operation removes the first phone number, based on its array index (zero-based):

    [
       {
          "operation" : "remove",
          "field" : "/phoneNumber/0"
       }
    ]
  • Set semantic arrays: The list of values included in a patch are removed from the existing array.

2.3.10.6. Patch Operation: Replace

The replace operation removes any existing value(s) of the targeted field, and replaces them with the provided value(s). It is essentially equivalent to a remove followed by a add operation. If the arrays are used, the criteria is based on "Patch Operation: Add". However, indexed updates are not allowed, even when the target is an array.

The following replace operation removes the existing telephoneNumber value for the user, and then adds the new value of +1 408 555 9999.

[
  {
    "operation" : "replace",
    "field" : "/telephoneNumber",
    "value" : "+1 408 555 9999"
  }
]

A PATCH replace operation on a list semantic array works in the same fashion as a PATCH remove operation. The following example demonstrates how the effect of both operations. Start with the following resource:

{
    "fruits" : [ "apple", "orange", "kiwi", "lime" ],
}

Apply the following operations on that resource:

[
  {
    "operation" : "remove",
    "field" : "/fruits/0",
    "value" : ""
  },
  {
    "operation" : "replace",
    "field" : "/fruits/1",
    "value" : "pineapple"
  }
]

The PATCH operations are applied sequentially. The remove operation removes the first member of that resource, based on its array index, (fruits/0), with the following result:

[
  {
    "fruits" : [ "orange", "kiwi", "lime" ],
  }
]

The second PATCH operation, a replace, is applied on the second member (fruits/1) of the intermediate resource, with the following result:

[
  {
    "fruits" : [ "orange", "pineapple", "lime" ],
  }
]

2.3.10.7. Patch Operation: Transform

The transform operation changes the value of a field based on a script or some other data transformation command. The following transform operation takes the value from the field named /objects, and applies the something.js script as shown:

[
  {
    "operation" : "transform",
    "field" : "/objects",
    "value" : {
      "script" : {
        "type" : "text/javascript",
        "file" : "something.js"
      }
    }
  }
]

2.3.10.8. Patch Operation Limitations

Some HTTP client libraries do not support the HTTP PATCH operation. Make sure that the library you use supports HTTP PATCH before using this REST operation.

For example, the Java Development Kit HTTP client does not support PATCH as a valid HTTP method. Instead, the method HttpURLConnection.setRequestMethod("PATCH") throws ProtocolException.

Parameters

You can use the following parameters. Other parameters might depend on the specific action implementation:

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in the body of the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

2.3.11. Action

Actions are a means of extending Common REST APIs and are defined by the resource provider, so the actions you can use depend on the implementation.

The standard action indicated by _action=create is described in "Create".

Parameters

You can use the following parameters. Other parameters might depend on the specific action implementation:

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in the body of the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

2.3.12. Query

To query a resource collection (or resource container if you prefer to think of it that way), perform an HTTP GET and accept a JSON response, including at least a _queryExpression, _queryFilter, or _queryId parameter. These parameters cannot be used together:

GET /users?_queryFilter=true HTTP/1.1
Host: example.com
Accept: application/json
  

The server returns the result as a JSON object including a "results" array and other fields related to the query string parameters that you specify.

Parameters

You can use the following parameters:

_queryFilter=filter-expression

Query filters request that the server return entries that match the filter expression. You must URL-escape the filter expression.

The string representation is summarized as follows. Continue reading for additional explanation:

Expr           = OrExpr
OrExpr         = AndExpr ( 'or' AndExpr ) *
AndExpr        = NotExpr ( 'and' NotExpr ) *
NotExpr        = '!' PrimaryExpr | PrimaryExpr
PrimaryExpr    = '(' Expr ')' | ComparisonExpr | PresenceExpr | LiteralExpr
ComparisonExpr = Pointer OpName JsonValue
PresenceExpr   = Pointer 'pr'
LiteralExpr    = 'true' | 'false'
Pointer        = JSON pointer
OpName         = 'eq' |  # equal to
                 'co' |  # contains
                 'sw' |  # starts with
                 'lt' |  # less than
                 'le' |  # less than or equal to
                 'gt' |  # greater than
                 'ge' |  # greater than or equal to
                 STRING  # extended operator
JsonValue      = NUMBER | BOOLEAN | '"' UTF8STRING '"'
STRING         = ASCII string not containing white-space
UTF8STRING     = UTF-8 string possibly containing white-space
     

JsonValue components of filter expressions follow RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format. In particular, as described in section 7 of the RFC, the escape character in strings is the backslash character. For example, to match the identifier test\, use _id eq 'test\\'. In the JSON resource, the \ is escaped the same way: "_id":"test\\".

When using a query filter in a URL, be aware that the filter expression is part of a query string parameter. A query string parameter must be URL encoded as described in RFC 3986: Uniform Resource Identifier (URI): Generic Syntax For example, white space, double quotes ("), parentheses, and exclamation characters need URL encoding in HTTP query strings. The following rules apply to URL query components:

query       = *( pchar / "/" / "?" )
pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
                  / "*" / "+" / "," / ";" / "="
     

ALPHA, DIGIT, and HEXDIG are core rules of RFC 5234: Augmented BNF for Syntax Specifications:

ALPHA       =  %x41-5A / %x61-7A   ; A-Z / a-z
DIGIT       =  %x30-39             ; 0-9
HEXDIG      =  DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
     

As a result, a backslash escape character in a JsonValue component is percent-encoded in the URL query string parameter as %5C. To encode the query filter expression _id eq 'test\\', use _id+eq+'test%5C%5C', for example.

A simple filter expression can represent a comparison, presence, or a literal value.

For comparison expressions use json-pointer comparator json-value, where the comparator is one of the following:

eq (equals)
co (contains)
sw (starts with)
lt (less than)
le (less than or equal to)
gt (greater than)
ge (greater than or equal to)

For presence, use json-pointer pr to match resources where:

  • The JSON pointer is present.

  • The value it points to is not null.

Literal values include true (match anything) and false (match nothing).

Complex expressions employ and, or, and ! (not), with parentheses, (expression), to group expressions.

_queryId=identifier

Specify a query by its identifier.

Specific queries can take their own query string parameter arguments, which depend on the implementation.

_pagedResultsCookie=string

The string is an opaque cookie used by the server to keep track of the position in the search results. The server returns the cookie in the JSON response as the value of pagedResultsCookie.

In the request _pageSize must also be set and non-zero. You receive the cookie value from the provider on the first request, and then supply the cookie value in subsequent requests until the server returns a null cookie, meaning that the final page of results has been returned.

The _pagedResultsCookie parameter is supported when used with the _queryFilter parameter. The _pagedResultsCookie parameter is not guaranteed to work when used with the _queryExpression and _queryId parameters.

The _pagedResultsCookie and _pagedResultsOffset parameters are mutually exclusive, and not to be used together.

_pagedResultsOffset=integer

When _pageSize is non-zero, use this as an index in the result set indicating the first page to return.

The _pagedResultsCookie and _pagedResultsOffset parameters are mutually exclusive, and not to be used together.

_pageSize=integer

Return query results in pages of this size. After the initial request, use _pagedResultsCookie or _pageResultsOffset to page through the results.

_totalPagedResultsPolicy=string

When a _pageSize is specified, and non-zero, the server calculates the "totalPagedResults", in accordance with the totalPagedResultsPolicy, and provides the value as part of the response. The "totalPagedResults" is either an estimate of the total number of paged results (_totalPagedResultsPolicy=ESTIMATE), or the exact total result count (_totalPagedResultsPolicy=EXACT). If no count policy is specified in the query, or if _totalPagedResultsPolicy=NONE, result counting is disabled, and the server returns value of -1 for "totalPagedResults".

_sortKeys=[+-]field[,[+-]field...]

Sort the resources returned based on the specified field(s), either in + (ascending, default) order, or in - (descending) order.

Because ascending order is the default, including the + character in the query is unnecessary. If you do include the +, it must be URL-encoded as %2B, for example:

http://localhost:8080/api/users?_prettyPrint=true&_queryFilter=true&_sortKeys=%2Bname/givenName

The _sortKeys parameter is not supported for predefined queries (_queryId).

_prettyPrint=true

Format the body of the response.

_fields=field[,field...]

Return only the specified fields in each element of the "results" array in the response.

The field values are JSON pointers. For example if the resource is {"parent":{"child":"value"}}, parent/child refers to the "child":"value".

If the field is left blank, the server returns all default values.

2.3.13. HTTP Status Codes

When working with a Common REST API over HTTP, client applications should expect at least the following HTTP status codes. Not all servers necessarily return all status codes identified here:

200 OK

The request was successful and a resource returned, depending on the request.

201 Created

The request succeeded and the resource was created.

204 No Content

The action request succeeded, and there was no content to return.

304 Not Modified

The read request included an If-None-Match header, and the value of the header matched the revision value of the resource.

400 Bad Request

The request was malformed.

401 Unauthorized

The request requires user authentication.

403 Forbidden

Access was forbidden during an operation on a resource.

404 Not Found

The specified resource could not be found, perhaps because it does not exist.

405 Method Not Allowed

The HTTP method is not allowed for the requested resource.

406 Not Acceptable

The request contains parameters that are not acceptable, such as a resource or protocol version that is not available.

409 Conflict

The request would have resulted in a conflict with the current state of the resource.

410 Gone

The requested resource is no longer available, and will not become available again. This can happen when resources expire for example.

412 Precondition Failed

The resource's current version does not match the version provided.

415 Unsupported Media Type

The request is in a format not supported by the requested resource for the requested method.

428 Precondition Required

The resource requires a version, but no version was supplied in the request.

500 Internal Server Error

The server encountered an unexpected condition that prevented it from fulfilling the request.

501 Not Implemented

The resource does not support the functionality required to fulfill the request.

503 Service Unavailable

The requested resource was temporarily unavailable. The service may have been disabled, for example.

2.4. REST API Versioning

In OpenAM 12.0.0 and later, REST API features are assigned version numbers.

Providing version numbers in the REST API helps ensure compatibility between releases. The version number of a feature increases when AM introduces a non-backwards-compatible change that affects clients making use of the feature.

AM provides versions for the following aspects of the REST API.

resource

Any changes to the structure or syntax of a returned response will incur a resource version change. For example changing errorMessage to message in a JSON response.

protocol

Any changes to the methods used to make REST API calls will incur a protocol version change. For example changing _action to $action in the required parameters of an API feature.

To ensure your clients are always compatible with a newer version of AM, you should always include resource versions in your REST calls.

2.4.1. Supported REST API Versions

The REST API version numbers supported in AM 6 are as follows:

Supported protocol versions

The protocol versions supported in AM 6 are:

1.0
Supported resource versions

The resource versions supported in AM 6 are shown in the following table.

Supported resource Versions
BaseEnd PointSupported Versions
/json/authenticate1.1, 2.0
/users1.1, 1.2, 2.0, 2.1, 3.0
/groups1.1, 2.0, 2.1, 3.0
/agents1.1, 2.0, 2.1, 3.0
/realms1.0
/dashboard1.0
/sessions1.2, 2.1, 3.1
/serverinfo/*1.1
/users/{user}/devices/trusted1.0
/users/{user}/uma/policies1.0
/applications1.0, 2.0
/resourcetypes1.0
/policies1.0, 2.0
/applicationtypes1.0
/conditiontypes1.0
/subjecttypes1.0
/subjectattributes1.0
/decisioncombiners1.0
/subjectattributes1.0
/xacml/policies1.0
/frrest/token1.0
/client1.0

For information about the supported protocol and resource versions available in AM 6, see the API Explorer available in the AM console.

The AM Release Notes section, "Changes and Deprecated Functionality" in the Release Notes describes the differences between API versions.

2.4.2. Specifying an Explicit REST API Version

You can specify which version of the REST API to use by adding an Accept-API-Version header to the request. The following example requests resource version 2.0 and protocol version 1.0:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: demo" \
--header "X-OpenAM-Password: changeit" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--data "{}" \
https://openam.example.com:8443/openam/json/realms/root/authenticate

You can configure the default behavior AM will take when a REST call does not specify explicit version information. For more information, see "Configuring the Default REST API Version for a Deployment".

2.4.3. Configuring the Default REST API Version for a Deployment

You can configure the default behavior AM will take when a REST call does not specify explicit version information using either of the following procedures:

The available options for default behavior are as follows:

Latest

The latest available supported version of the API is used.

This is the preset default for new installations of AM.

Oldest

The oldest available supported version of the API is used.

This is the preset default for upgraded AM instances.

Note

The oldest supported version may not be the first that was released, as APIs versions become deprecated or unsupported. See "Deprecated Functionality" in the Release Notes.

None

No version will be used. When a REST client application calls a REST API without specifying the version, AM returns an error and the request fails.

Configure Versioning Behavior by using the AM Console
  1. Log in as AM administrator, amadmin.

  2. Click Configure > Global Services, and then click REST APIs.

  3. In Default Version, select the required response to a REST API request that does not specify an explicit version: Latest, Oldest, or None.

  4. (Optional) Optionally, enable Warning Header to include warning messages in the headers of responses to requests.

  5. Save your work.

Configure Versioning Behavior by Using the ssoadm Command
  • Use the ssoadm set-attr-defs command with the openam-rest-apis-default-version attribute set to either Latest, Oldest or None, as in the following example:

    $ ssh openam.example.com
    $ cd /path/to/openam-tools/admin/openam/bin
    $ ./ssoadm \
     set-attr-defs \
     --adminid amadmin \
     --password-file /tmp/pwd.txt \
     --servicename RestApisService \
     --schematype Global \
     --attributevalues openam-rest-apis-default-version=None
    Schema attribute defaults were set.

2.4.4. REST API Versioning Messages

AM provides REST API version messages in the JSON response to a REST API call. You can also configure AM to return version messages in the response headers.

Messages include:

  • Details of the REST API versions used to service a REST API call.

  • Warning messages if REST API version information is not specified or is incorrect in a REST API call.

The resource and protocol version used to service a REST API call are returned in the Content-API-Version header, as shown below:

$ curl \
-i \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: demo" \
--header "X-OpenAM-Password: changeit" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--data "{}" \
https://openam.example.com:8443/openam/json/realms/root/authenticate
HTTP/1.1 200 OK
Content-API-Version: protocol=1.0,resource=2.0
Server: Restlet-Framework/2.1.7
Content-Type: application/json;charset=UTF-8

{
    "tokenId":"AQIC5wM...TU3OQ*",
    "successUrl":"/openam/console"
}

If the default REST API version behavior is set to None, and a REST API call does not include the Accept-API-Version header, or does not specify a resource version, then a 400 Bad Request status code is returned, as shown below:

$ curl \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=1.0" \
https://openam.example.com:8443/openam/json/realms/root/serverinfo/*
{
    "code":400,
    "reason":"Bad Request",
    "message":"No requested version specified and behavior set to NONE."
}

If a REST API call does include the Accept-API-Version header, but the specified resource or protocol version does not exist in AM, then a 404 Not Found status code is returned, as shown below:

$ curl \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=1.0, resource=999.0" \
https://openam.example.com:8443/openam/json/realms/root/serverinfo/*
{
    "code":404,
    "reason":"Not Found",
    "message":"Accept-API-Version: Requested version \"999.0\" does not match any routes."
}

Tip

For more information on setting the default REST API version behavior, see "Specifying an Explicit REST API Version".

2.5. Cross-Site Request Forgery (CSRF) Protection

AM includes a global filter to harden AM's protection against CSRF attacks. The filter applies to all REST endpoints under json/ and requires that all requests other than GET, HEAD, or OPTIONS include, at least, one of the following headers:

  • X-Requested-With

    This header is often sent by Javascript frameworks, and the XUI already sends it on all requests.

  • Accept-API-Version

    This header specifies which version of the REST API to use. Use this header in your requests to ensure future changes to the API do not affect your clients.

    For more information about API versioning, see "REST API Versioning".

Failure to include at least one of the headers would cause the REST call to fail with a 403 Forbidden error, even if the SSO token is valid.

To disable the filter, navigate to Configure > Global Services > REST APIs > and turn off Enable CSRF Protection.

The json/ endpoint is not vulnerable to CSRF attacks when the filter is disabled, since it requires the "Content-Type: application/json" header, which currently triggers the same protection in browsers. This may change in the future, so it is recommended to enable the CSRF filter.

2.6. Specifying Realms in REST API Calls

This section describes how to work with realms when making REST API calls to AM.

Realms can be specified in the following ways when making a REST API call to AM:

DNS Alias

When making a REST API call, the DNS alias of a realm can be specified in the subdomain and domain name components of the REST endpoint.

To list all users in the top-level realm use the DNS alias of the AM instance, for example the REST endpoint would be:

https://openam.example.com:8443/openam/json/users?_queryId=*

To list all users in a realm with DNS alias suppliers.example.com the REST endpoint would be:

https://suppliers.example.com:8443/openam/json/users?_queryId=*

Path

When making a REST API call, specify the realm in the path component of the endpoint. You must specify the entire hierarchy of the realm, starting at the top-level realm. Prefix each realm in the hierarchy with the realms/ keyword. For example /realms/root/realms/customers/realms/europe.

To authenticate a user in the top-level realm, use the root keyword. For example:

https://openam.example.com:8443/openam/json/realms/root/authenticate

To authenticate a user in a subrealm named customers within the top-level realm, the REST endpoint would be:

https://openam.example.com:8443/openam/json/realms/root/realms/customers/authenticate

If realms are specified using both the DNS alias and path methods, the path is used to determine the realm.

For example, the following REST endpoint returns users in a subrealm of the top-level realm named europe, not the realm with DNS alias suppliers.example.com:

https://suppliers.example.com:8443/openam/json/realms/root/realms/europe/users?_queryId=*

2.7. Authentication and Logout

You can use REST-like APIs under /json/authenticate and /json/sessions for authentication and for logout.

The /json/authenticate endpoint does not support the CRUDPAQ verbs and therefore does not technically satisfy REST architectural requirements. The term REST-like describes this endpoint better than REST.

The simplest user name/password authentication returns a tokenId that applications can present as a cookie value for other operations that require authentication. The type of tokenId returned varies depending on whether client-based sessions are enabled in the realm to which the user authenticates:

  • If client-based sessions are not enabled, the tokenId is an AM SSO token.

  • If client-based sessions are enabled, the tokenId is an AM SSO token that includes an encoded AM session.

Developers should be aware that the size of the tokenId for client-based sessions—2000 bytes or greater—is considerably longer than for CTS-based sessions—approximately 100 bytes. For more information about session tokens, see "Session Cookies" in the Authentication and Single Sign-On Guide.

When authenticating with a user name and password, use HTTP POST to prevent the web container from logging the credentials. Pass the user name in an X-OpenAM-Username header, and the password in an X-OpenAM-Password header:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "X-OpenAM-Username: demo" \
--header "X-OpenAM-Password: changeit" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--data "{}" \
https://openam.example.com:8443/openam/json/realms/root/authenticate
{
    "tokenId": "AQIC5w...NTcy*",
    "successUrl": "/openam/console",
    "realm":"/"
}

To use UTF-8 user names and passwords in calls to the /json/authenticate endpoint, base64-encode the string, and then wrap the string as described in RFC 2047:

encoded-word = "=?" charset "?" encoding "?" encoded-text "?="

For example, to authenticate using a UTF-8 username, such as ɗëɱø, perform the following steps:

  1. Encode the string in base64 format: yZfDq8mxw7g=.

  2. Wrap the base64-encoded string as per RFC 2047: =?UTF-8?B?yZfDq8mxw7g=?=.

  3. Use the result in the X-OpenAM-Username header passed to the authentication endpoint as follows:

    $ curl \
    --request POST \
    --header "Content-Type: application/json" \
    --header "X-OpenAM-Username: =?UTF-8?B?yZfDq8mxw7g=?=" \
    --header "X-OpenAM-Password: changeit" \
    --header "Accept-API-Version: resource=2.0, protocol=1.0" \
    --data "{}" \
    https://openam.example.com:8443/openam/json/realms/root/authenticate
    {
        "tokenId": "AQIC5w...NTcy*",
        "successUrl": "/openam/console",
        "realm":"/"
    }

This zero page login mechanism works only for name/password authentication. If you include a POST body with the request, it must be an empty JSON string as shown in the example. Alternatively, you can leave the POST body empty. Otherwise, AM interprets the body as a continuation of an existing authentication attempt, one that uses a supported callback mechanism.

The authentication service at /json/authenticate supports callback mechanisms that make it possible to perform other types of authentication in addition to simple user name/password login.

Callbacks that are not completed based on the content of the client HTTP request are returned in JSON as a response to the request. Each callback has an array of output suitable for displaying to the end user, and input which is what the client must complete and send back to AM. The default is still user name/password authentication:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
https://openam.example.com:8443/openam/json/realms/root/authenticate
{
    "authId": "...jwt-value...",
    "template": "",
    "stage": "DataStore1",
    "callbacks": [
        {
            "type": "NameCallback",
            "output": [
                {
                    "name": "prompt",
                    "value": " User Name: "
                }
            ],
            "input": [
                {
                    "name": "IDToken1",
                    "value": ""
                }
            ]
        },
        {
            "type": "PasswordCallback",
            "output": [
                {
                    "name": "prompt",
                    "value": " Password: "
                }
            ],
            "input": [
                {
                    "name": "IDToken2",
                    "value": ""
                }
            ]
        }
    ]
}

The authID value is a JSON Web Token (JWT) that uniquely identifies the authentication context to AM, and so must also be sent back with the requests.

To respond to the callback, send back the JSON object with the missing values filled, as in this case where the user name is demo and the password is changeit:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--data '{ "authId": "...jwt-value...", "template": "", "stage": "DataStore1",
        "callbacks": [ { "type": "NameCallback", "output": [ { "name": "prompt",
        "value": " User Name: " } ], "input": [ { "name": "IDToken1", "value": "demo" } ] },
        { "type": "PasswordCallback", "output": [ { "name": "prompt", "value": " Password: " } ],
        "input": [ { "name": "IDToken2", "value": "changeit" } ] } ] }' \
https://openam.example.com:8443/openam/json/realms/root/authenticate
{
    "tokenId":"AQIC5wM2...U3MTE4NA..*",
    "successUrl": "/openam/console",
    "realm":"/"
}

The response is a token ID holding the SSO token value.

Alternatively, you can authenticate without requesting a session using the noSession query string parameter:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--data '{ "authId": "...jwt-value...", "template": "", "stage": "DataStore1",
        "callbacks": [ { "type": "NameCallback", "output": [ { "name": "prompt",
        "value": " User Name: " } ], "input": [ { "name": "IDToken1", "value": "demo" } ] },
        { "type": "PasswordCallback", "output": [ { "name": "prompt", "value": " Password: " } ],
        "input": [ { "name": "IDToken2", "value": "changeit" } ] } ] }' \
https://openam.example.com:8443/openam/json/realms/root/authenticate?noSession=true
{
    "message":"Authentication Successful",
    "successUrl":"/openam/console",
    "realm":"/"
}

AM can be configured to return a failure URL value when authentication fails. No failure URL is configured by default. The Default Failure Login URL can be set per realm; see "Post Authentication Processing" in the Authentication and Single Sign-On Guide for details. Alternatively, failure URLs can be configured per authentication chain, which your client can specify using the service parameter described below. On failure AM then returns HTTP status code 401 Unauthorized, and the JSON in the reply indicates the failure URL:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--header "X-OpenAM-Username: demo" \
--header "X-OpenAM-Password: badpassword" \
https://openam.example.com:8443/openam/json/realms/root/authenticate
{
    "code":401,
    "reason":"Unauthorized",
    "message":"Invalid Password!!",
    "failureUrl": "http://www.example.com/401.html"
}

When making a REST API call, specify the realm in the path component of the endpoint. You must specify the entire hierarchy of the realm, starting at the top-level realm. Prefix each realm in the hierarchy with the realms/ keyword. For example /realms/root/realms/customers/realms/europe.

For example, to authenticate to a subrealm customers within the top-level realm, then the authentication endpoint URL is as follows: https://openam.example.com:8443/openam/json/realms/root/realms/customers/authenticate

The following additional parameters are supported:

You can use the authIndexType and authIndexValue query string parameters as a pair to provide additional information about how you are authenticating. The authIndexType can be one of the following types:

composite

Set the value to a composite advice string.

level

Set the value to the authentication level.

module

Set the value to the name of an authentication module.

resource

Set the value to a URL protected by an AM policy.

role

Set the value to an AM role.

service

Set the value to the name of an authentication tree or authentication chain.

user

Set the value to an AM user ID.

For example, to log into AM using the built-in ldapService authentication chain, you could use the following:

$ curl \
--request POST \
--header 'Accept-API-Version: resource=2.0, protocol=1.0' \
--header 'X-OpenAM-Username: demo' \
--header 'X-OpenAM-Password: changeit' \
'http://openam.example.com:8080/openam/json/realms/root/authenticate?authIndexType=service&authIndexValue=ldapService'

You can use the query string parameter, sessionUpgradeSSOTokenId=tokenId, to request session upgrade. Before the tokenId is searched for in the query string for session upgrade, the token is grabbed from the cookie. For an explanation of session upgrade, see "Session Upgrade" in the Authentication and Single Sign-On Guide.

AM uses the following callback types depending on the authentication module in use:

  • ChoiceCallback: Used to display a list of choices and retrieve the selected choice.

  • ConfirmationCallback: Used to ask for a confirmation such as Yes, No, or Cancel and retrieve the selection.

  • HiddenValueCallback: Used to return form values that are not visually rendered to the end user.

  • HttpCallback: Used for HTTP handshake negotiations.

  • LanguageCallback: Used to retrieve the locale for localizing text presented to the end user.

  • NameCallback: Used to retrieve a name string.

  • PasswordCallback: Used to retrieve a password value.

  • PollingWaitCallback: Used to restrict polling requests by specifying an amount of time to wait before responding.

  • RedirectCallback: Used to redirect the client user-agent.

  • ScriptTextOutputCallback: Used to insert a script into the page presented to the end user. The script can, for example, collect data about the user's environment.

  • TextInputCallback: Used to retrieve text input from the end user.

  • TextOutputCallback: Used to display a message to the end user.

  • X509CertificateCallback: Used to retrieve the content of an x.509 certificate.

2.7.1. Logout

Authenticated users can log out with the token cookie value and an HTTP POST to /json/sessions/?_action=logout:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Cache-Control: no-cache" \
--header "iplanetDirectoryPro: AQIC5wM2...U3MTE4NA..*" \
--header "Accept-API-Version: resource=3.1, protocol=1.0" \
https://openam.example.com:8443/openam/json/realms/root/sessions/?_action=logout
{
    "result":"Successfully logged out"
}

2.7.2. logoutByHandle

To log out a session using a session handle, first perform an HTTP GET to the resource URL, /json/sessions/, using the queryFilter action to get the session handle:

$ curl \
--request GET \
--header "Content-Type: application/json" \
--header "Cache-Control: no-cache" \
--header "iPlanetDirectoryPro: AQICS...NzEz*" \
--header "Accept-API-Version: resource=3.1, protocol=1.0" \
https://openam.example.com:8443/openam/json/realms/root/sessions?_queryFilter=username%20eq%20%22demo%22%20and%20realm%20eq%20%22%2F%22
{
    "result": [
        {
            "username": "demo",
            "universalId": "id=demo,ou=user,dc=openam,dc=forgerock,dc=org",
            "realm":"/",
            "sessionHandle":"shandle:SJ80.*AA....JT.*",
            "latestAccessTime":"2018-10-23T09:37:54.387Z",
            "maxIdleExpirationTime":"2018-10-23T10:07:54Z",
            "maxSessionExpirationTime":"2018-10-23T11:37:54Z"
        },
         {
            "username": "demo",
            "universalId": "id=demo,ou=user,dc=openam,dc=forgerock,dc=org",
            "realm":"/",
            "sessionHandle":"shandle:H4CV.*DV....FM.*",
            "latestAccessTime":"2018-10-23T09:37:43.780Z",
            "maxIdleExpirationTime":"2018-10-23T10:07:43Z",
            "maxSessionExpirationTime":"2018-10-23T11:37:43Z"
        }
    ],
    "resultCount": 2,
    "pagedResultsCookie": null,
    "totalPagedResultsPolicy": "NONE",
    "totalPagedResults": -1,
    "remainingPagedResults": -1
}

To log out a session using a session handle, perform an HTTP POST to the resource URL, /json/sessions/, using the logoutByHandle action.

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Cache-Control: no-cache" \
--header "iplanetDirectoryPro: AQIC5w...NTcy*" \
--header "Accept-API-Version: resource=3.1, protocol=1.0" \
--data '{
    "sessionHandles": [
        "shandle:SJ80.*AA....JT.*",
        "shandle:H4CV.*DV....FM.*"
    ]
}' \
https://openam.example.com:8443/openam/json/realms/root/sessions/?_action=logoutByHandle
{
    "result": {
        "shandle:SJ80.*AA....JT.*": true,
        "shandle:H4CV.*DV....FM.*": true
    }
}

2.7.3. Load Balancer and Proxy Layer Requirements

When authentication depends on the client IP address and AM lies behind a load balancer or proxy layer, configure the load balancer or proxy to send the address by using the X-Forwarded-For header, and configure AM to consume and forward the header as necessary. For details, see "Handling HTTP Request Headers" in the Installation Guide.

2.7.4. Windows Desktop SSO Requirements

When authenticating with Windows Desktop SSO, add an Authorization header containing the string Basic , followed by a base64-encoded string of the username, a colon character, and the password. In the following example, the credentials demo:changeit are base64-encoded into the string ZGVtbzpjaGFuZ2VpdA==:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=2.0, protocol=1.0" \
--header "X-OpenAM-Username: demo" \
--header "X-OpenAM-Password: changeit" \
--header "Authorization: Basic ZGVtbzpjaGFuZ2VpdA==" \
--data "{}" \
https://openam.example.com:8443/openam/json/realms/root/authenticate
{
    "tokenId":"AQIC5w...NTcy*",
    "successUrl":"/openam/console",
    "realm":"/"
}

2.8. Using the Session Token After Authentication

The following is a common scenario when accessing AM by using REST API calls:

  • First, call the /json/authenticate endpoint to log a user in to AM. This REST API call returns a tokenID value, which is used in subsequent REST API calls to identify the user:

    $ curl \
    --request POST \
    --header "Content-Type: application/json" \
    --header "X-OpenAM-Username: demo" \
    --header "X-OpenAM-Password: changeit" \
    --header "Accept-API-Version: resource=2.0, protocol=1.0" \
    --data "{}" \
    https://openam.example.com:8443/openam/json/realms/root/authenticate
    {
        "tokenId":"AQIC5wM...TU3OQ*",
        "successUrl":"/openam/console",
        "realm":"/"
    }

    The returned tokenID is known as a session token (also referred to as an SSO token). REST API calls made after successful authentication to AM must present the session token in the HTTP header as proof of authentication.

  • Next, call one or more additional REST APIs on behalf of the logged-in user. Each REST API call passes the user's tokenID back to AM in the HTTP header as proof of previous authentication.

    The following is a partial example of a curl command that inserts the token ID returned from a prior successful AM authentication attempt into the HTTP header:

    $ curl \
    --request POST \
    --header "Content-Type: application/json" \
    --header "iPlanetDirectoryPro: AQIC5w...NTcy*" \
    --header "Accept-API-Version: resource=2.0, protocol=1.0" \
    --data '{
      ...
    

    Observe that the session token is inserted into a header field named iPlanetDirectoryPro. This header field name must correspond to the name of the AM session cookie—by default, iPlanetDirectoryPro. You can find the cookie name in the AM console by navigating to Deployment > Servers > Server Name > Security > Cookie, in the Cookie Name field of the AM console.

    Once a user has authenticated, it is not necessary to insert login credentials in the HTTP header in subsequent REST API calls. Note the absence of X-OpenAM-Username and X-OpenAM-Password headers in the preceding example.

    Users are required to have appropriate privileges in order to access AM functionality using the REST API. For example, users who lack administrative privileges cannot create AM realms. For more information on the AM privilege model, see "Delegating Realm Administration Privileges" in the Setup and Maintenance Guide.

  • Finally, call the REST API to log the user out of AM as described in "Authentication and Logout". As with other REST API calls made after a user has authenticated, the REST API call to log out of AM requires the user's tokenID in the HTTP header.

2.9. Server Information

You can retrieve AM server information by using HTTP GET on /json/serverinfo/* as follows:

$ curl \
--request GET \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=1.1, protocol=1.0" \
https://openam.example.com:8443/openam/json/serverinfo/*
{
    "domains": [
        ".example.com"
    ],
    "protectedUserAttributes": [],
    "cookieName": "iPlanetDirectoryPro",
    "secureCookie": false,
    "forgotPassword": "false",
    "forgotUsername": "false",
    "kbaEnabled": "false",
    "selfRegistration": "false",
    "lang": "en-US",
    "successfulUserRegistrationDestination": "default",
    "socialImplementations": [
        {
            "iconPath": "XUI/images/logos/facebook.png",
            "authnChain": "FacebookSocialAuthenticationService",
            "displayName": "Facebook",
            "valid": true
        }
    ],
    "referralsEnabled": "false",
    "zeroPageLogin": {
        "enabled": false,
        "refererWhitelist": [
            ""
        ],
        "allowedWithoutReferer": true
    },
    "realm": "/",
    "xuiUserSessionValidationEnabled": true,
    "FQDN": "openam.example.com"
}

2.10. Token Encoding

Valid tokens in AM requires configuration either in percent encoding or in C66Encode format. C66Encode format is encouraged. It is the default token format for AM, and is used in this section. The following is an example token that has not been encoded:

AQIC5wM2LY4SfczntBbXvEAOuECbqMY3J4NW3byH6xwgkGE=@AAJTSQACMDE=#

This token includes reserved characters such as +, /, and = (The @, #, and * are not reserved characters per se, but substitutions are still required). To c66encode this token, you would substitute certain characters for others, as follows:

+ is replaced with -
/ is replaced with _
= is replaced with .
@ is replaced with *
# is replaced with *
* (first instance) is replaced with @
* (subsequent instances) is replaced with #

In this case, the translated token would appear as shown here:

AQIC5wM2LY4SfczntBbXvEAOuECbqMY3J4NW3byH6xwgkGE.*AAJTSQACMDE.*

2.11. Logging

AM 6 supports two Audit Logging Services: a new common REST-based Audit Logging Service, and the legacy Logging Service, which is based on a Java SDK and is available in AM versions prior to OpenAM 13. The legacy Logging Service is deprecated.

Both audit facilities log AM REST API calls.

2.11.1. Common Audit Logging of REST API Calls

AM logs information about all REST API calls to the access topic. For more information about AM audit topics, see "Audit Log Topics" in the Setup and Maintenance Guide.

Locate specific REST endpoints in the http.path log file property.

2.11.2. Legacy Logging of REST API Calls

AM logs information about REST API calls to two files:

  • amRest.access. Records accesses to a CREST endpoint, regardless of whether the request successfully reached the endpoint through policy authorization.

    An amRest.access example is as follows:

    $ cat openam/openam/log/amRest.access
    #Version: 1.0
    #Fields: time  Data  LoginID  ContextID  IPAddr  LogLevel  Domain  LoggedBy  MessageID  ModuleName
    NameID  HostName
    "2011-09-14 16:38:17"   /home/user/openam/openam/log/ "cn=dsameuser,ou=DSAME Users,o=openam"
    aa307b2dcb721d4201 "Not Available" INFO  o=openam   "cn=dsameuser,ou=DSAME Users,o=openam"
    LOG-1  amRest.access  "Not Available"  192.168.56.2
    "2011-09-14 16:38:17"  "Hello World"  id=bjensen,ou=user,o=openam 8a4025a2b3af291d01  "Not Available"
    INFO  o=openam id=amadmin,ou=user,o=openam "Not Available" amRest.access "Not Available"
    192.168.56.2
  • amRest.authz. Records all CREST authorization results regardless of success. If a request has an entry in the amRest.access log, but no corresponding entry in amRest.authz, then that endpoint was not protected by an authorization filter and therefore the request was granted access to the resource.

    The amRest.authz file contains the Data field, which specifies the authorization decision, resource, and type of action performed on that resource. The Data field has the following syntax:

    ("GRANT"||"DENY") > "RESOURCE | ACTION"
    
    where
      "GRANT > " is prepended to the entry if the request was allowed
      "DENY  > " is prepended to the entry if the request was not allowed
      "RESOURCE" is "ResourceLocation | ResourceParameter"
         where
           "ResourceLocation" is the endpoint location (e.g., subrealm/applicationtypes)
           "ResourceParameter" is the ID of the resource being touched
            (e.g., myApplicationType) if applicable. Otherwise, this field is empty
            if touching the resource itself, such as in a query.
    
      "ACTION" is "ActionType | ActionParameter"
         where
           "ActionType" is "CREATE||READ||UPDATE||DELETE||PATCH||ACTION||QUERY"
           "ActionParameter" is one of the following depending on the ActionType:
              For CREATE: the new resource ID
              For READ: empty
              For UPDATE: the revision of the resource to update
              For DELETE: the revision of the resource to delete
              For PATCH: the revision of the resource to patch
              For ACTION: the actual action performed (e.g., "forgotPassword")
              For QUERY: the query ID if any
    $ cat openam/openam/log/amRest.authz
    #Version: 1.0
    #Fields: time   Data  ContextID  LoginID  IPAddr  LogLevel  Domain  MessageID  LoggedBy  NameID
    ModuleName    HostName
    "2014-09-16 14:17:28"   /var/root/openam/openam/log/   7d3af9e799b6393301
    "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" "Not Available" INFO
    dc=openam,dc=forgerock,dc=org  LOG-1  "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org"
    "Not Available" amRest.authz    10.0.1.5
    "2014-09-16 15:56:12"  "GRANT > sessions|ACTION|logout|AdminOnlyFilter"  d3977a55a2ee18c201
    id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org "Not Available" INFO  dc=openam,dc=forgerock,dc=org
    OAuth2Provider-2  "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org"  "Not Available"
    amRest.authz    127.0.0.1
    "2014-09-16 15:56:40"   "GRANT > sessions|ACTION|logout|AdminOnlyFilter"  eedbc205bf51780001
    id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org  "Not Available" INFO dc=openam,dc=forgerock,dc=org
    OAuth2Provider-2  "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org"  "Not Available"
    amRest.authz    127.0.0.1

AM also provides additional information in its debug notifications for accesses to any endpoint, depending on the message type (error, warning or message) including realm, user, and result of the operation.

2.12. REST Goto URL Validation

You can set valid goto URLs using the AM console by following the instructions in "Constraining Post-Login Redirects" in the Authentication and Single Sign-On Guide.

To validate a goto URL over REST, use the endpoint: /json/user?_action=validateGoto.

$ curl \
--request POST \
--header "Accept-API-Version: protocol=2.1,resource=3.0" \
--header "Content-Type: application/json" \
--header "iPlanetDirectoryPro: AQIC5...ACMDE.*" \
--data '{"goto":"http://www.example.com/"}' \
http://openam.example.com:8080/openam/json/users?_action=validateGoto
{
    "successURL":"http://www.example.com/"
}

2.13. Reference

This reference section covers return codes and system settings relating to REST API support in AM.

2.13.1. REST APIs

amster service name: rest

The following settings are available in this service:

Default Resource Version

The API resource version to use when the REST request does not specify an explicit version. Choose from:

  • Latest. If an explicit version is not specified, the latest resource version of an API is used.

  • Oldest. If an explicit version is not specified, the oldest supported resource version of an API is used. Note that since APIs may be deprecated and fall out of support, the oldest supported version may not be the first version.

  • None. If an explicit version is not specified, the request will not be handled and an error status is returned.

The possible values for this property are:

  • Latest

  • Oldest

  • None

Default value: Latest

amster attribute: defaultVersion

Warning Header

Whether to include a warning header in the response to a request which fails to include the Accept-API-Version header.

Default value: false

amster attribute: warningHeader

API Descriptions

Whether API Explorer and API Docs are enabled in OpenAM and how the documentation for them is generated. Dynamic generation includes descriptions from any custom services and authentication modules you may have added. Static generation only includes services and authentication modules that were present when OpenAM was built. Note that dynamic documentation generation may not work in some application containers.

The possible values for this property are:

  • DYNAMIC. Enabled with Dynamic Documentation

  • STATIC. Enabled with Static Documentation

  • DISABLED

Default value: STATIC

amster attribute: descriptionsState

Default Protocol Version

The API protocol version to use when a REST request does not specify an explicit version. Choose from:

  • Oldest. If an explicit version is not specified, the oldest protocol version is used.

  • Latest. If an explicit version is not specified, the latest protocol version is used.

  • None. If an explicit version is not specified, the request will not be handled and an error status is returned.

The possible values for this property are:

  • Oldest

  • Latest

  • None

Default value: Latest

amster attribute: defaultProtocolVersion

Enable CSRF Protection

If enabled, all non-read/query requests will require the X-Requested-With header to be present.

Requiring a non-standard header ensures requests can only be made via methods (XHR) that have stricter same-origin policy protections in Web browsers, preventing Cross-Site Request Forgery (CSRF) attacks. Without this filter, cross-origin requests are prevented by the use of the application/json Content-Type header, which is less robust.

Default value: true

amster attribute: csrfFilterEnabled

Chapter 3. Developing with Scripts

You can use scripts for client-side and server-side authentication, policy conditions, and handling OpenID Connect claims.

3.1. The Scripting Environment

This section introduces how AM executes scripts, and covers thread pools and security configuration.

You can use scripts to modify default AM behavior in the following situations, also known as contexts:

Client-side Authentication

Scripts that are executed on the client during authentication. Client-side scripts must be in JavaScript.

Server-side Authentication

Scripts are included in an authentication module and are executed on the server during authentication.

Policy Condition

Scripts used as conditions within policies.

OIDC Claims

Scripts that gather and populate the claims in a request when issuing an ID token or making a request to the userinfo endpoint.

AM implements a configurable scripting engine for each of the context types that are executed on the server.

The scripting engines in AM have two main components: security settings, and the thread pool.

Diagram of the scripting environment within AM.

3.1.1. Security

AM scripting engines provide security features for ensuring that malicious Java classes are not directly called. The engines validate scripts by checking all directly-called Java classes against a configurable blacklist and whitelist, and, optionally, against the JVM SecurityManager, if it is configured.

Whitelists and blacklists contain class names that are allowed or denied execution respectively. Specify classes in whitelists and blacklists by name or by using regular expressions.

Classes called by the script are checked against the whitelist first, and must match at least one pattern in the list. The blacklist is applied after the whitelist, and classes matching any pattern are disallowed.

You can also configure the scripting engine to make an additional call to the JVM security manager for each class that is accessed. The security manager throws an exception if a class being called is not allowed to execute.

For more information on configuring script engine security, see "Scripting".

Important Points About Script Engine Security

The following points should be considered when configuring the security settings within each script engine:

The scripting engine only validates directly accessible classes.

The security settings only apply to classes that the script directly accesses. If the script calls Foo.a() and then that method calls Bar.b(), the scripting engine will be unable to prevent it. You must consider the whole chain of accessible classes.

Note

Access includes actions such as:

  • Importing or loading a class.

  • Accessing any instance of that class. For example, passed as a parameter to the script.

  • Calling a static method on that class.

  • Calling a method on an instance of that class.

  • Accessing a method or field that returns an instance of that class.

Potentially dangerous Java classes are blacklisted by default.

All Java reflection classes (java.lang.Class, java.lang.reflect.*) are blacklisted by default to avoid bypassing the security settings.

The java.security.AccessController class is also blacklisted by default to prevent access to the doPrivileged() methods.

Caution

You should not remove potentially dangerous Java classes from the blacklist.

The whitelists and blacklists match class or package names only.

The whitelist and blacklist patterns apply only to the exact class or package names involved. The script engine does not know anything about inheritance, so it is best to whitelist known, specific classes.

3.1.2. Thread Pools

Each script is executed in an individual thread. Each scripting engine starts with an initial number of threads available for executing scripts. If no threads are available for execution, AM creates a new thread to execute the script, until the configured maximum number of threads is reached.

If the maximum number of threads is reached, pending script executions are queued in a number of buffer threads, until a thread becomes available for execution. If a created thread has completed script execution and has remained idle for a configured amount of time, AM terminates the thread, shrinking the pool.

For more information on configuring script engine thread pools, see "Scripting".

3.2. Global Scripting API Functionality

This section covers functionality available to each of the server-side script types.

Global API functionality includes:

3.2.1. Accessing HTTP Services

AM passes an HTTP client object, httpClient, to server-side scripts. Server-side scripts can call HTTP services with the httpClient.send method. The method returns an HttpClientResponse object.

Configure the parameters for the HTTP client object by using the org.forgerock.http.protocol package. This package contains the Request class, which has methods for setting the URI and type of request.

The following example, taken from the default server-side Scripted authentication module script, uses these methods to call an online API to determine the longitude and latitude of a user based on their postal address:

function getLongitudeLatitudeFromUserPostalAddress() {

    var request = new org.forgerock.http.protocol.Request();

    request.setUri("http://maps.googleapis.com/maps/api/geocode/json?address=" + encodeURIComponent(userPostalAddress));
    request.setMethod("GET");

    var response = httpClient.send(request).get();
    logResponse(response);

    var geocode = JSON.parse(response.getEntity());
    var i;

    for (i = 0; i < geocode.results.length; i++) {
        var result = geocode.results[i];
        latitude = result.geometry.location.lat;
        longitude = result.geometry.location.lng;

        logger.message("latitude:" + latitude + " longitude:" + longitude);
    }
}

HTTP client requests are synchronous and blocking until they return. You can, however, set a global timeout for server-side scripts. For details, see "Scripted Authentication Module Properties" in the Authentication and Single Sign-On Guide.

Server-side scripts can access response data by using the methods listed in the table below.

HTTP Client Response Methods
MethodParametersReturn TypeDescription

HttpClientResponse.getCookies

Void

Map<String, String>

Get the cookies for the returned response, if any exist.

HttpClientResponse.getEntity

Void

String

Get the entity of the returned response.

HttpClientResponse.getHeaders

Void

Map<String, String>

Get the headers for the returned response, if any exist.

HttpClientResponse.getReasonPhrase

Void

String

Get the reason phrase of the returned response.

HttpClientResponse.getStatusCode

Void

Integer

Get the status code of the returned response.

HttpClientResponse.hasCookies

Void

Boolean

Indicate whether the returned response had any cookies.

HttpClientResponse.hasHeaders

Void

Boolean

Indicate whether the returned response had any headers.


3.2.2. Debug Logging

Server-side scripts can write messages to AM debug logs by using the logger object.

AM does not log debug messages from scripts by default. You can configure AM to log such messages by setting the debug log level for the amScript service. For details, see "Debug Logging By Service" in the Setup and Maintenance Guide.

The following table lists the logger methods.

Logger Methods
MethodParametersReturn TypeDescription

logger.error

Error Message (type: String)

Void

Write Error Message to AM debug logs if ERROR level logging is enabled.

logger.errorEnabled

Void

Boolean

Return true when ERROR level debug messages are enabled.

logger.message

Message (type: String)

Void

Write Message to AM debug logs if MESSAGE level logging is enabled.

logger.messageEnabled

Void

Boolean

Return true when MESSAGE level debug messages are enabled.

logger.warning

Warning Message (type: String)

Void

Write Warning Message to AM debug logs if WARNING level logging is enabled.

logger.warningEnabled

Void

Boolean

Return true when WARNING level debug messages are enabled.


3.3. Managing Scripts

This section shows you how to manage scripts used for client-side and server-side scripted authentication, custom policy conditions, and handling OpenID Connect claims using the AM console, the ssoadm command, and the REST API.

3.3.1. Managing Scripts With the AM Console

The following procedures describe how to create, modify, and delete scripts using the AM console:

To Create Scripts by Using the AM Console
  1. Log in to the AM console as an AM administrator, for example, amadmin.

  2. Navigate to Realms > Realm Name > Scripts.

  3. Click New Script.

    The New Script page appears:

    Creating a script by using the AM console.
  4. Specify a name for the script.

  5. Select the type of script from the Script Type drop-down list.

  6. Click Create.

    The Script Name page appears:

    Creating a Script Using the AM console.
  7. Enter values on the Script Name page as follows:

    1. Enter a description of the script.

    2. Choose the script language, either JavaScript or Groovy. Note that not every script type supports both languages.

    3. Enter the source code in the Script field.

      On supported browsers, you can click Upload, navigate to the script file, and then click Open to upload the contents to the Script field.

    4. Click Validate to check for compilation errors in the script.

      Correct any compilation errors, and revalidate the script until all errors have been fixed.

    5. Save your changes.

To Modify Scripts by Using the AM Console
  1. Log in to the AM console as an AM administrator, for example, amadmin.

  2. Navigate to Realms > Realm Name > Scripts.

  3. Select the script you want to modify from the list of scripts.

    The Script Name page appears.

  4. Modify values on the Script Name page as needed. Note that if you change the Script Type, existing code in the script is replaced.

  5. If you modified the code in the script, click Validate to check for compilation errors.

    Correct any compilation errors, and revalidate the script until all errors have been fixed.

  6. Save your changes.

To Delete Scripts by Using the AM Console
  1. Log in to the AM console as an AM administrator, for example, amadmin.

  2. Navigate to Realms > Realm Name > Scripts.

  3. Choose one or more scripts to delete by activating the checkboxes in the relevant rows. Note that you can only delete user-created scripts—you cannot delete the global sample scripts provided with AM.

  4. Click Delete.

3.3.2. Managing Scripts With the REST API

This section shows you how to manage scripts used for client-side and server-side scripted authentication, custom policy conditions, and handling OpenID Connect claims by using the REST API.

User-created scripts are realm-specific, hence the URI for the scripts' API can contain a realm component, such as /json{/realm}/scripts. If the realm is not specified in the URI, the top level realm is used.

Tip

AM includes some global example scripts that can be used in any realm.

Scripts are represented in JSON and take the following form. Scripts are built from standard JSON objects and values (strings, numbers, objects, sets, arrays, true, false, and null). Each script has a system-generated universally unique identifier (UUID), which must be used when modifying existing scripts. Renaming a script will not affect the UUID:

{
  "_id": "7e3d7067-d50f-4674-8c76-a3e13a810c33",
  "name": "Scripted Module - Server Side",
  "description": "Default global script for server side Scripted Authentication Module",
  "script": "dmFyIFNUQVJUX1RJ...",
  "language": "JAVASCRIPT",
  "context": "AUTHENTICATION_SERVER_SIDE",
  "createdBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
  "creationDate": 1433147666269,
  "lastModifiedBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
  "lastModifiedDate": 1433147666269
}

The values for the fields shown in the example above are explained below:

_id

The UUID that AM generates for the script.

name

The name provided for the script.

description

An optional text string to help identify the script.

script

The source code of the script. The source code is in UTF-8 format and encoded into Base64.

For example, a script such as the following:

var a = 123;
var b = 456;

When encoded into Base64 becomes:

dmFyIGEgPSAxMjM7IA0KdmFyIGIgPSA0NTY7
language

The language the script is written in - JAVASCRIPT or GROOVY.

Language Support per Context
Script ContextSupported Languages
POLICY_CONDITIONJAVASCRIPT, GROOVY
AUTHENTICATION_SERVER_SIDEJAVASCRIPT, GROOVY
AUTHENTICATION_CLIENT_SIDEJAVASCRIPT
OIDC_CLAIMSJAVASCRIPT, GROOVY
AUTHENTICATION_TREE_DECISION_NODEJAVASCRIPT, GROOVY

context

The context type of the script.

Supported values are:

POLICY_CONDITION

Policy Condition

AUTHENTICATION_SERVER_SIDE

Server-side Authentication

AUTHENTICATION_CLIENT_SIDE

Client-side Authentication

Note

Client-side scripts must be written in JavaScript.

OIDC_CLAIMS

OIDC Claims

AUTHENTICATION_TREE_DECISION_NODE

Authentication scripts used by Scripted Tree Decision authentication nodes.

createdBy

A string containing the universal identifier DN of the subject that created the script.

creationDate

An integer containing the creation date and time, in ISO 8601 format.

lastModifiedBy

A string containing the universal identifier DN of the subject that most recently updated the resource type.

If the script has not been modified since it was created, this property will have the same value as createdBy.

lastModifiedDate

A string containing the last modified date and time, in ISO 8601 format.

If the script has not been modified since it was created, this property will have the same value as creationDate.

3.3.2.1. Querying Scripts

To list all the scripts in a realm, as well as any global scripts, perform an HTTP GET to the /json{/realm}/scripts endpoint with a _queryFilter parameter set to true.

Note

If the realm is not specified in the URL, AM returns scripts in the top level realm, as well as any global scripts.

The iPlanetDirectoryPro header is required and should contain the SSO token of an administrative user, such as amAdmin, who has access to perform the operation.

$ curl \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Accept-API-Version: resource=1.1" \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts?_queryFilter=true
{
    "result": [
        {
            "_id": "9de3eb62-f131-4fac-a294-7bd170fd4acb",
            "name": "Scripted Policy Condition",
            "description": "Default global script for Scripted Policy Conditions",
            "script": "LyoqCiAqIFRoaXMg...",
            "language": "JAVASCRIPT",
            "context": "POLICY_CONDITION",
            "createdBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
            "creationDate": 1433147666269,
            "lastModifiedBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
            "lastModifiedDate": 1433147666269
        },
        {
            "_id": "7e3d7067-d50f-4674-8c76-a3e13a810c33",
            "name": "Scripted Module - Server Side",
            "description": "Default global script for server side Scripted Authentication Module",
            "script": "dmFyIFNUQVJUX1RJ...",
            "language": "JAVASCRIPT",
            "context": "AUTHENTICATION_SERVER_SIDE",
            "createdBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
            "creationDate": 1433147666269,
            "lastModifiedBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
            "lastModifiedDate": 1433147666269
        }
    ],
    "resultCount": 2,
    "pagedResultsCookie": null,
    "remainingPagedResults": -1
}
Supported _queryFilter Fields and Operators
FieldSupported Operators
_id Equals (eq), Contains (co), Starts with (sw)
name Equals (eq), Contains (co), Starts with (sw)
description Equals (eq), Contains (co), Starts with (sw)
script Equals (eq), Contains (co), Starts with (sw)
language Equals (eq), Contains (co), Starts with (sw)
context Equals (eq), Contains (co), Starts with (sw)

3.3.2.2. Reading a Script

To read an individual script in a realm, perform an HTTP GET using the /json{/realm}/scripts endpoint, specifying the UUID in the URL.

Tip

To read a script in the top-level realm, or to read a built-in global script, do not specify a realm in the URL.

The iPlanetDirectoryPro header is required and should contain the SSO token of an administrative user, such as amAdmin, who has access to perform the operation.

$ curl \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Accept-API-Version: resource=1.1" \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts/9de3eb62-f131-4fac-a294-7bd170fd4acb
{
    "_id": "9de3eb62-f131-4fac-a294-7bd170fd4acb",
    "name": "Scripted Policy Condition",
    "description": "Default global script for Scripted Policy Conditions",
    "script": "LyoqCiAqIFRoaXMg...",
    "language": "JAVASCRIPT",
    "context": "POLICY_CONDITION",
    "createdBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
    "creationDate": 1433147666269,
    "lastModifiedBy": "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
    "lastModifiedDate": 1433147666269
}

3.3.2.3. Validating a Script

To validate a script, perform an HTTP POST using the /json{/realm}/scripts endpoint, with an _action parameter set to validate. Include a JSON representation of the script and the script language, JAVASCRIPT or GROOVY, in the POST data.

The value for script must be in UTF-8 format and then encoded into Base64.

The iPlanetDirectoryPro header is required and should contain the SSO token of an administrative user, such as amAdmin, who has access to perform the operation.

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Accept-API-Version: resource=1.1" \
--data '{
    "script": "dmFyIGEgPSAxMjM7dmFyIGIgPSA0NTY7Cg==",
    "language": "JAVASCRIPT"
}' \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts/?_action=validate
{
    "success": true
}

If the script is valid the JSON response contains a success key with a value of true.

If the script is invalid the JSON response contains a success key with a value of false, and an indication of the problem and where it occurs, as shown below:

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Accept-API-Version: resource=1.1" \
--data '{
    "script": "dmFyIGEgPSAxMjM7dmFyIGIgPSA0NTY7ID1WQUxJREFUSU9OIFNIT1VMRCBGQUlMPQo=",
    "language": "JAVASCRIPT"
}' \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts/?_action=validate
{
    "success": false,
    "errors": [
        {
            "line": 1,
            "column": 27,
            "message": "syntax error"
        }
    ]
}

3.3.2.4. Creating a Script

To create a script in a realm, perform an HTTP POST using the /json{/realm}/scripts endpoint, with an _action parameter set to create. Include a JSON representation of the script in the POST data.

The value for script must be in UTF-8 format and then encoded into Base64.

Note

If the realm is not specified in the URL, AM creates the script in the top level realm.

The iPlanetDirectoryPro header is required and should contain the SSO token of an administrative user, such as amAdmin, who has access to perform the operation.

$ curl \
--request POST \
--header "Content-Type: application/json" \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Accept-API-Version: resource=1.1" \
--data '{
    "name": "MyJavaScript",
    "script": "dmFyIGEgPSAxMjM7CnZhciBiID0gNDU2Ow==",
    "language": "JAVASCRIPT",
    "context": "POLICY_CONDITION",
    "description": "An example script"
}' \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts/?_action=create
{
    "_id": "0168d494-015a-420f-ae5a-6a2a5c1126af",
    "name": "MyJavaScript",
    "description": "An example script",
    "script": "dmFyIGEgPSAxMjM7CnZhciBiID0gNDU2Ow==",
    "language": "JAVASCRIPT",
    "context": "POLICY_CONDITION",
    "createdBy": "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
    "creationDate": 1436807766258,
    "lastModifiedBy": "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
    "lastModifiedDate": 1436807766258
}

3.3.2.5. Updating a Script

To update an individual script in a realm, perform an HTTP PUT using the /json{/realm}/scripts endpoint, specifying the UUID in both the URL and the PUT body. Include a JSON representation of the updated script in the PUT data, alongside the UUID.

Note

If the realm is not specified in the URL, AM uses the top level realm.

The iPlanetDirectoryPro header is required and should contain the SSO token of an administrative user, such as amAdmin, who has access to perform the operation.

$ curl \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Content-Type: application/json" \
--header "Accept-API-Version: resource=1.1" \
--request PUT \
--data '{
    "name": "MyUpdatedJavaScript",
    "script": "dmFyIGEgPSAxMjM7CnZhciBiID0gNDU2Ow==",
    "language": "JAVASCRIPT",
    "context": "POLICY_CONDITION",
    "description": "An updated example script configuration"
}' \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts/0168d494-015a-420f-ae5a-6a2a5c1126af
{
    "_id": "0168d494-015a-420f-ae5a-6a2a5c1126af",
    "name": "MyUpdatedJavaScript",
    "description": "An updated example script configuration",
    "script": "dmFyIGEgPSAxMjM7CnZhciBiID0gNDU2Ow==",
    "language": "JAVASCRIPT",
    "context": "POLICY_CONDITION",
    "createdBy": "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
    "creationDate": 1436807766258,
    "lastModifiedBy": "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
    "lastModifiedDate": 1436808364681
}

3.3.2.6. Deleting a Script

To delete an individual script in a realm, perform an HTTP DELETE using the /json{/realm}/scripts endpoint, specifying the UUID in the URL.

Note

If the realm is not specified in the URL, AM uses the top level realm.

The iPlanetDirectoryPro header is required and should contain the SSO token of an administrative user, such as amAdmin, who has access to perform the operation.

$ curl \
--request DELETE \
--header "iPlanetDirectoryPro: AQIC5..." \
--header "Accept-API-Version: resource=1.1" \
https://openam.example.com:8443/openam/json/realms/root/realms/myrealm/scripts/0168d494-015a-420f-ae5a-6a2a5c1126af
{}

3.3.3. Managing Scripts With the ssoadm Command

Use the ssoadm command's create-sub-cfg, get-sub-cfg, and delete-sub-cfg subcommands to manage AM scripts.

Create an AM script as follows:

  1. Create a script configuration file, for example /path/to/myScriptConfigurationFile.txt, containing the following:

    script-file=/path/to/myScriptFile.js
    language=JAVASCRIPT (1)
    name=My New Script
    context=AUTHENTICATION_SERVER_SIDE (2) 

    1

    Possible values for the language property are:

    • JAVASCRIPT

    • GROOVY

    2

    Possible values for the context property are:

    • POLICY_CONDITION

    • AUTHENTICATION_SERVER_SIDE

    • AUTHENTICATION_CLIENT_SIDE

    • OIDC_CLAIMS

    • AUTHENTICATION_TREE_DECISION_NODE

  2. Run the ssoadm create-sub-cfg command. The --datafile argument references the script configuration file you created in the previous step:

    $ ssoadm \
      create-sub-cfg \
      --realm /myRealm \
      --adminid amadmin \
      --password-file /tmp/pwd.txt \
      --servicename ScriptingService \
      --subconfigname scriptConfigurations/scriptConfiguration \
      --subconfigid myScriptID \
      --datafile /path/to/myScriptConfigurationFile.txt
    Sub Configuration scriptConfigurations/scriptConfiguration was added to realm /myRealm

To list the properties of a script, run the ssoadm get-sub-cfg command:

$ ssoadm \
  get-sub-cfg \
  --realm /myRealm \
  --adminid amadmin \
  --password-file /tmp/pwd.txt \
  --servicename ScriptingService \
  --subconfigname scriptConfigurations/myScriptID
createdBy=
lastModifiedDate=
lastModifiedBy=
name=My New Script
context=AUTHENTICATION_SERVER_SIDE
description=
language=JAVASCRIPT
creationDate=
script=...Script output follows...

To delete a script, run the ssoadm delete-sub-cfg command:

$ ssoadm \
  delete-sub-cfg \
  --realm /myRealm \
  --adminid amadmin \
  --password-file /tmp/pwd.txt \
  --servicename ScriptingService \
  --subconfigname scriptConfigurations/myScriptID
Sub Configuration scriptConfigurations/myScriptID was deleted from realm /myRealm

Chapter 4. Reference

This reference section covers settings and other information relating to developing with AM.

4.1. Scripting

amster service name: scripting

4.1.1. Configuration

The following settings appear on the Configuration tab:

Default Script Type

The default script context type when creating a new script.

The possible values for this property are:

  • POLICY_CONDITION. Policy Condition

  • AUTHENTICATION_SERVER_SIDE. Server-side Authentication

  • AUTHENTICATION_CLIENT_SIDE. Client-side Authentication

  • OIDC_CLAIMS. OIDC Claims

  • AUTHENTICATION_TREE_DECISION_NODE. Decision node script for authentication trees

Default value: POLICY_CONDITION

amster attribute: defaultContext

4.1.2. Secondary Configurations

This service has the following Secondary Configurations.

4.1.2.1. Engine Configuration

The following properties are available for Scripting Service secondary configuration instances:

Engine Configuration

Configure script engine parameters for running a particular script type in OpenAM.

ssoadm attribute: engineConfiguration

To access a secondary configuration instance using the ssoadm command, use: --subconfigname [primary configuration]/[secondary configuration] For example:

$ ssoadm set-sub-cfg \
  --adminid amAdmin \
  --password-file admin_pwd_file \
  --servicename ScriptingService \
  --subconfigname OIDC_CLAIMS/engineConfiguration \
  --operation set \
  --attributevalues maxThreads=300 queueSize=-1

Note

Supports server-side scripts only. OpenAM cannot configure engine settings for client-side scripts.

The configurable engine settings are as follows:

Server-side Script Timeout

The maximum execution time any individual script should take on the server (in seconds). OpenAM terminates scripts which take longer to run than this value.

ssoadm attribute: serverTimeout

Core thread pool size

The initial number of threads in the thread pool from which scripts operate. OpenAM will ensure the pool contains at least this many threads.

ssoadm attribute: coreThreads

Maximum thread pool size

The maximum number of threads in the thread pool from which scripts operate. If no free thread is available in the pool, OpenAM creates new threads in the pool for script execution up to the configured maximum.

ssoadm attribute: maxThreads

Thread pool queue size

The number of threads to use for buffering script execution requests when the maximum thread pool size is reached.

ssoadm attribute: queueSize

Thread idle timeout (seconds)

Length of time (in seconds) for a thread to be idle before OpenAM terminates created threads. If the current pool size contains the number of threads set in Core thread pool size idle threads will not be terminated, to maintain the initial pool size.

ssoadm attribute: idleTimeout

Java class whitelist

Specifies the list of class-name patterns allowed to be invoked by the script. Every class accessed by the script must match at least one of these patterns.

You can specify the class name as-is or use a regular expression.

ssoadm attribute: whiteList

Java class blacklist

Specifies the list of class-name patterns that are NOT allowed to be invoked by the script. The blacklist is applied AFTER the whitelist to exclude those classes - access to a class specified in both the whitelist and the blacklist will be denied.

You can specify the class name to exclude as-is or use a regular expression.

ssoadm attribute: blackList

Use system SecurityManager

If enabled, OpenAM will make a call to System.getSecurityManager().checkPackageAccess(...) for each class that is accessed. The method throws SecurityException if the calling thread is not allowed to access the package.

Note

This feature only takes effect if the security manager is enabled for the JVM.

ssoadm attribute: useSecurityManager

Scripting languages

Select the languages available for scripts on the chosen type. Either GROOVY or JAVASCRIPT.

ssoadm attribute: languages

Default Script

The source code that is presented as the default when creating a new script of this type.

ssoadm attribute: defaultScript

Appendix A. Getting Support

For more information or resources about AM and ForgeRock Support, see the following sections:

A.1. Accessing Documentation Online

ForgeRock publishes comprehensive documentation online:

  • The ForgeRock Knowledge Base offers a large and increasing number of up-to-date, practical articles that help you deploy and manage ForgeRock software.

    While many articles are visible to community members, ForgeRock customers have access to much more, including advanced information for customers using ForgeRock software in a mission-critical capacity.

  • ForgeRock product documentation, such as this document, aims to be technically accurate and complete with respect to the software documented. It is visible to everyone and covers all product features and examples of how to use them.

A.2. Using the ForgeRock.org Site

The ForgeRock.org site has links to source code for ForgeRock open source software, as well as links to the ForgeRock forums and technical blogs.

If you are a ForgeRock customer, raise a support ticket instead of using the forums. ForgeRock support professionals will get in touch to help you.

A.3. Getting Support and Contacting ForgeRock

ForgeRock provides support services, professional services, training through ForgeRock University, and partner services to assist you in setting up and maintaining your deployments. For a general overview of these services, see https://www.forgerock.com.

ForgeRock has staff members around the globe who support our international customers and partners. For details, visit https://www.forgerock.com, or send an email to ForgeRock at info@forgerock.com.

Glossary

Access control

Control to grant or to deny access to a resource.

Account lockout

The act of making an account temporarily or permanently inactive after successive authentication failures.

Actions

Defined as part of policies, these verbs indicate what authorized identities can do to resources.

Advice

In the context of a policy decision denying access, a hint to the policy enforcement point about remedial action to take that could result in a decision allowing access.

Agent administrator

User having privileges only to read and write agent profile configuration information, typically created to delegate agent profile creation to the user installing a web or Java agent.

Agent authenticator

Entity with read-only access to multiple agent profiles defined in the same realm; allows an agent to read web service profiles.

Application

In general terms, a service exposing protected resources.

In the context of AM policies, the application is a template that constrains the policies that govern access to protected resources. An application can have zero or more policies.

Application type

Application types act as templates for creating policy applications.

Application types define a preset list of actions and functional logic, such as policy lookup and resource comparator logic.

Application types also define the internal normalization, indexing logic, and comparator logic for applications.

Attribute-based access control (ABAC)

Access control that is based on attributes of a user, such as how old a user is or whether the user is a paying customer.

Authentication

The act of confirming the identity of a principal.

Authentication chaining

A series of authentication modules configured together which a principal must negotiate as configured in order to authenticate successfully.

Authentication level

Positive integer associated with an authentication module, usually used to require success with more stringent authentication measures when requesting resources requiring special protection.

Authentication module

AM authentication unit that handles one way of obtaining and verifying credentials.

Authorization

The act of determining whether to grant or to deny a principal access to a resource.

Authorization Server

In OAuth 2.0, issues access tokens to the client after authenticating a resource owner and confirming that the owner authorizes the client to access the protected resource. AM can play this role in the OAuth 2.0 authorization framework.

Auto-federation

Arrangement to federate a principal's identity automatically based on a common attribute value shared across the principal's profiles at different providers.

Bulk federation

Batch job permanently federating user profiles between a service provider and an identity provider based on a list of matched user identifiers that exist on both providers.

Circle of trust

Group of providers, including at least one identity provider, who have agreed to trust each other to participate in a SAML v2.0 provider federation.

Client

In OAuth 2.0, requests protected web resources on behalf of the resource owner given the owner's authorization. AM can play this role in the OAuth 2.0 authorization framework.

Client-based sessions

AM sessions for which AM returns session state to the client after each request, and require it to be passed in with the subsequent request. For browser-based clients, AM sets a cookie in the browser that contains the session information.

For browser-based clients, AM sets a cookie in the browser that contains the session state. When the browser transmits the cookie back to AM, AM decodes the session state from the cookie.

Conditions

Defined as part of policies, these determine the circumstances under which which a policy applies.

Environmental conditions reflect circumstances like the client IP address, time of day, how the subject authenticated, or the authentication level achieved.

Subject conditions reflect characteristics of the subject like whether the subject authenticated, the identity of the subject, or claims in the subject's JWT.

Configuration datastore

LDAP directory service holding AM configuration data.

Cross-domain single sign-on (CDSSO)

AM capability allowing single sign-on across different DNS domains.

CTS-based sessions

AM sessions that reside in the Core Token Service's token store. CTS-based sessions might also be cached in memory on one or more AM servers. AM tracks these sessions in order to handle events like logout and timeout, to permit session constraints, and to notify applications involved in SSO when a session ends.

Delegation

Granting users administrative privileges with AM.

Entitlement

Decision that defines which resource names can and cannot be accessed for a given identity in the context of a particular application, which actions are allowed and which are denied, and any related advice and attributes.

Extended metadata

Federation configuration information specific to AM.

Extensible Access Control Markup Language (XACML)

Standard, XML-based access control policy language, including a processing model for making authorization decisions based on policies.

Federation

Standardized means for aggregating identities, sharing authentication and authorization data information between trusted providers, and allowing principals to access services across different providers without authenticating repeatedly.

Fedlet

Service provider application capable of participating in a circle of trust and allowing federation without installing all of AM on the service provider side; AM lets you create Java Fedlets.

Hot swappable

Refers to configuration properties for which changes can take effect without restarting the container where AM runs.

Identity

Set of data that uniquely describes a person or a thing such as a device or an application.

Identity federation

Linking of a principal's identity across multiple providers.

Identity provider (IdP)

Entity that produces assertions about a principal (such as how and when a principal authenticated, or that the principal's profile has a specified attribute value).

Identity repository

Data store holding user profiles and group information; different identity repositories can be defined for different realms.

Java agent

Java web application installed in a web container that acts as a policy enforcement point, filtering requests to other applications in the container with policies based on application resource URLs.

Metadata

Federation configuration information for a provider.

Policy

Set of rules that define who is granted access to a protected resource when, how, and under what conditions.

Policy agent

Java, web, or custom agent that intercepts requests for resources, directs principals to AM for authentication, and enforces policy decisions from AM.

Policy Administration Point (PAP)

Entity that manages and stores policy definitions.

Policy Decision Point (PDP)

Entity that evaluates access rights and then issues authorization decisions.

Policy Enforcement Point (PEP)

Entity that intercepts a request for a resource and then enforces policy decisions from a PDP.

Policy Information Point (PIP)

Entity that provides extra information, such as user profile attributes that a PDP needs in order to make a decision.

Principal

Represents an entity that has been authenticated (such as a user, a device, or an application), and thus is distinguished from other entities.

When a Subject successfully authenticates, AM associates the Subject with the Principal.

Privilege

In the context of delegated administration, a set of administrative tasks that can be performed by specified identities in a given realm.

Provider federation

Agreement among providers to participate in a circle of trust.

Realm

AM unit for organizing configuration and identity information.

Realms can be used for example when different parts of an organization have different applications and user data stores, and when different organizations use the same AM deployment.

Administrators can delegate realm administration. The administrator assigns administrative privileges to users, allowing them to perform administrative tasks within the realm.

Resource

Something a user can access over the network such as a web page.

Defined as part of policies, these can include wildcards in order to match multiple actual resources.

Resource owner

In OAuth 2.0, entity who can authorize access to protected web resources, such as an end user.

Resource server

In OAuth 2.0, server hosting protected web resources, capable of handling access tokens to respond to requests for such resources.

Response attributes

Defined as part of policies, these allow AM to return additional information in the form of "attributes" with the response to a policy decision.

Role based access control (RBAC)

Access control that is based on whether a user has been granted a set of permissions (a role).

Security Assertion Markup Language (SAML)

Standard, XML-based language for exchanging authentication and authorization data between identity providers and service providers.

Service provider (SP)

Entity that consumes assertions about a principal (and provides a service that the principal is trying to access).

Authentication Session

The interval while the user or entity is authenticating to AM.

Session

The interval that starts after the user has authenticated and ends when the user logs out, or when their session is terminated. For browser-based clients, AM manages user sessions across one or more applications by setting a session cookie. See also CTS-based sessions and Client-based sessions.

Session high availability

Capability that lets any AM server in a clustered deployment access shared, persistent information about users' sessions from the CTS token store. The user does not need to log in again unless the entire deployment goes down.

Session token

Unique identifier issued by AM after successful authentication. For a CTS-based sessions, the session token is used to track a principal's session.

Single log out (SLO)

Capability allowing a principal to end a session once, thereby ending her session across multiple applications.

Single sign-on (SSO)

Capability allowing a principal to authenticate once and gain access to multiple applications without authenticating again.

Site

Group of AM servers configured the same way, accessed through a load balancer layer. The load balancer handles failover to provide service-level availability.

The load balancer can also be used to protect AM services.

Standard metadata

Standard federation configuration information that you can share with other access management software.

Stateless Service

Stateless services do not store any data locally to the service. When the service requires data to perform any action, it requests it from a data store. For example, a stateless authentication service stores session state for logged-in users in a database. This way, any server in the deployment can recover the session from the database and service requests for any user.

All AM services are stateless unless otherwise specified. See also Client-based sessions and CTS-based sessions.

Subject

Entity that requests access to a resource

When an identity successfully authenticates, AM associates the identity with the Principal that distinguishes it from other identities. An identity can be associated with multiple principals.

User data store

Data storage service holding principals' profiles; underlying storage can be an LDAP directory service or a custom IdRepo implementation.

Web Agent

Native library installed in a web server that acts as a policy enforcement point with policies based on web page URLs.

Read a different version of :