Chapter 3. Using RESTful Web Services

Table of Contents
3.1. About the RESTful API
3.2. Token Encoding
3.3. Authentication & Logout
3.4. Cookie Information
3.5. Token Validation
3.6. Authorization & Policy Management
3.7. OAuth 2.0 Authorization
3.8. OpenID Connect 1.0
3.9. User Self-Registration
3.10. Resetting Forgotten Passwords
3.11. Logging
3.12. Identity Management
3.13. Realm Management
3.14. Displaying Dashboard Applications
3.15. REST Status Codes

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

3.1. About the RESTful API

Interface Stability: Evolving

OpenAM offers a RESTful API for these access and identity management operations:

This chapter also includes a section on Section 3.15, “REST Status Codes”.

In this chapter, long URLs are wrapped to fit the printed page, as some of the output is formatted for easier reading.

3.2. Token Encoding

Valid tokens in OpenAM requires configuration either in percent encoding or in C66Encode format. C66Encode format is encouraged. It is the default token format for OpenAM, and is used in this chapter. 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.*

3.3. Authentication & Logout

OpenAM provides REST APIs for authentication and for logout.

Tip

When authentication depends on the client IP address, and OpenAM 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 OpenAM to consume and forward the header as necessary. For details, see the Installation Guide section, Handling HTTP Request Headers.

3.3.1. Authentication & Logout

The simplest user name/password authentication returns a tokenId that applications can present as a cookie value for other operations that require authentication. In this case 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 "X-OpenAM-Username: demo" \
 --header "X-OpenAM-Password: changeit" \
 --header "Content-Type: application/json" \
 --data "{}" \
 https://openam.example.com:8443/openam/json/authenticate
{ "tokenId": "AQIC5w...NTcy*", "successUrl": "/openam/console" }
   

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, OpenAM 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 OpenAM. The default is still user name/password authentication.

$ curl \
 --request POST \
 --header "Content-Type: application/json" \
 https://openam.example.com:8443/openam/json/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 OpenAM, 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" \
 --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/authenticate

{ "tokenId": "AQIC5wM2...U3MTE4NA..*", "successUrl": "/openam/console" }
   

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" \
 --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/authenticate?noSession=true

{ "message": "Authentication Successful", "successUrl": "/openam/console" }
   

OpenAM 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 configured for the Core authentication module. Alternatively, failure URLs can be configured per authentication chain, which your client can specify using the service parameter described below. On failure OpenAM 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 "X-OpenAM-Username: demo" \
 --header "X-OpenAM-Password: badpassword" \
 https://openam.example.com:8443/openam/json/authenticate
{
  "code":401,
  "reason":"Unauthorized",
  "message":"Invalid Password!!",
  "failureUrl": "http://www.example.com/401.html"
}
   

To specify a realm in your request, first make sure that the name of your realm does not match an endpoint name to avoid any potential routing errors. Then, specify the realm in one of two ways. For example, if you have a realm titled "myRealm," you can use it in your request as follows:

  • Using the realm in the URI to the endpoint (preferred method):

    https://openam.example.com:8443/openam/json/myRealm/authenticate
  • Using the realm query string parameter:

    https://openam.example.com:8443/openam/json/authenticate?realm=myRealm

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 OpenAM policy.

role

Set the value to an OpenAM role.

service

Set the value to the name of an authentication chain.

user

Set the value to an OpenAM user ID.

You can use the query string parameter, sessionUpgrade=tokenId, to request session upgrade. For an explanation of session upgrade, see the Administration Guide section on, Authentication Levels & Session Upgrade.

OpenAM uses the following callback types depending on the authentication module in use.

  • ChoiceCallback

  • ConfirmationCallback

  • HttpCallback

  • LanguageCallback

  • NameCallback

  • PasswordCallback

  • RedirectCallback

  • TextInputCallback

  • TextOutputCallback

  • X509CertificateCallback

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

$ curl \
 --request POST \
 --header "iplanetDirectoryPro: AQIC5wM2...U3MTE4NA..*" \
 --header "Content-Type: application/json" \
 "https://openam.example.com:8443/openam/json/sessions/?_action=logout"

{"result":"Successfully logged out"}
   

3.3.2. Authentication & Logout (Legacy API)

Interface Stability: Deprecated

Simple authentication with a user name and password returns a token.

$ curl \
 --request POST \
 --data "username=bjensen&password=hifalutin" \
 https://openam.example.com:8443/openam/identity/authenticate

token.id=AQIC5wM2LY4SfcxvdvHOXjtC_eWSs2RB54tgvgK8SuYi7aQ.*AAJTSQACMDE.*
    

If you must specify parameters as when authenticating to /UI/Login, you provide a percent encoded string of the parameters as the value of the uri parameter. The /UI/Login parameter deals with the realm, module, and service parameters. Setting the client parameter sets the user's IP address as part of the token following successful authentication. The default for the client parameter is the IP of the machine making the REST request.

$ curl \
 --request POST \
 --data "username=bjensen&password=hifalutin&uri=realm%3D%2F%26module%3DDataStore\
&client=192.168.1.1" \
 https://openam.example.com:8443/openam/identity/authenticate

token.id=AQIC5wM2LY4SfcxvdvHOXjtC_eWSs2RB54tgvgK8SuYi7aQ.*AAJTSQACMDE.*
    

You log out using the token to end the user session.

$ curl \
 --request POST \
 --data "subjectid=AQIC5w...*AAJTSQACMDE.*" \
 https://openam.example.com:8443/openam/identity/logout
    

3.4. Cookie Information

You can retrieve the cookie domains that OpenAM supports by HTTP GET on /json/serverinfo/cookieDomains.

$ curl https://openam.example.com:8443/openam/json/serverinfo/cookieDomains
{"domains":[".example.com"]}
  

You can retrieve the name of the cookie used for storing the session token. By default it is iPlanetDirectoryPro.

$ curl https://openam.example.com:8443/openam/identity/getCookieNameForToken
string=iPlanetDirectoryPro
  

You can also retrieve the name of the cookie used for storing the session token and the names of the cookies to forward with requests.

$ curl https://openam.example.com:8443/openam/identity/getCookieNamesToForward
string=iPlanetDirectoryPro
string=amlbcookie
  

3.5. Token Validation

OpenAM provides REST APIs for validating SSO tokens.

3.5.1. Token Validation

To check over REST whether a token is valid, perform an HTTP POST to the resource URL, /json/sessions/tokenId, using the validate action as shown in the following example.

$ curl \
 --request POST \
 --header "Content-Type: application/json" \
 http://openam.example.com:8080/openam/json/sessions/AQIC5...?_action=validate
{"valid":true,"uid":"demo","realm":"/realm"}
   

An invalid token returns only information about the validity.

$ curl \
 --request POST \
 --header "Content-Type: application/json" \
 http://openam.example.com:8080/openam/json/sessions/AQIC5...?_action=validate
{"valid":false}
   

3.5.2. Token Validation, Attribute Retrieval (Legacy API)

Interface Stability: Deprecated

You check whether a token is valid as follows.

$ curl \
 --request POST \
 --data "tokenid=AQIC5w...*AAJTSQACMDE.*" \
 https://openam.example.com:8443/openam/identity/isTokenValid
boolean=true
   

An invalid token returns boolean=false.

$ curl \
 --request POST \
 --data "tokenid=INVALID" \
 https://openam.example.com:8443/openam/identity/isTokenValid
boolean=false
   

With a valid token, you can retrieve attributes about the subject. OpenAM returns a series of name, value pairs.

The newer API for retrieving user information is demonstrated in Section 3.12.2, “Reading Identities”. What follows describes the legacy API.

$ curl \
 --request POST \
 --data "subjectid=AQIC5w...*AAJTSQACMDE.*" \
 https://openam.example.com:8443/openam/identity/attributes
userdetails.token.id=
 AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*
userdetails.attribute.name=uid
userdetails.attribute.value=bjensen
userdetails.attribute.name=mail
userdetails.attribute.value=bjensen@example.com
userdetails.attribute.name=sn
userdetails.attribute.value=Jensen
userdetails.attribute.name=userpassword
userdetails.attribute.value={SSHA}rhusOfYpkapDWEHcfT2Y7y83LMuC++F4Abqvig==
userdetails.attribute.name=cn
userdetails.attribute.value=Babs Jensen
userdetails.attribute.value=Barbara Jensen
userdetails.attribute.name=givenname
userdetails.attribute.value=Barbara
userdetails.attribute.name=dn
userdetails.attribute.value=uid=bjensen,ou=people,dc=example,dc=com
userdetails.attribute.name=telephonenumber
userdetails.attribute.value=+1 408 555 1862
userdetails.attribute.name=objectclass
userdetails.attribute.value=organizationalPerson
userdetails.attribute.value=person
userdetails.attribute.value=posixAccount
userdetails.attribute.value=inetOrgPerson
userdetails.attribute.value=krbprincipalaux
userdetails.attribute.value=krbTicketPolicyAux
userdetails.attribute.value=top
   

You can specify attributes to limit what you retrieve.

$ curl "https://openam.example.com:8443/openam/identity/attributes?\
subjectid=AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*\
&attributenames=mail\
&attributenames=uid"
userdetails.token.id=
 AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*
userdetails.attribute.name=uid
userdetails.attribute.value=bjensen
userdetails.attribute.name=mail
userdetails.attribute.value=bjensen@example.com
   

When retrieving attributes, you can refresh the session thus setting the idle time to 0, by adding the boolean parameter refresh=true to the query string.

$ curl "https://openam.example.com:8443/openam/identity/attributes?\
subjectid=AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*\
&attributenames=cn\
&refresh=true"
userdetails.token.id=
 AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*
userdetails.attribute.name=cn
userdetails.attribute.value=Babs Jensen
userdetails.attribute.value=Barbara Jensen
   

You can specify the following attributes to retrieve information about the user's session time limits and current session: maxsessiontime (maximum length of a session), maxidletime (maximum idle time allowed during a session), idletime (actual idle time during the current session), timeleft (actual time left in session). The unit for maximum times is minutes. The unit for actual times is seconds.

Also use the parameter refresh=false to avoid changing the idletime with your request.

$ curl \
--data "subjectid=AQIC5w....*AAJTSQACMDE.*\
 &attributenames=idletime\
 &attributenames=maxidletime\
 &attributenames=timeleft\
 &attributenames=maxsessiontime\
 &refresh=false" \
 https://openam.example.com:8443/openam/identity/attributes

userdetails.token.id=AQIC5w....*AAJTSQACMDE.*
userdetails.attribute.name=maxsessiontime
userdetails.attribute.value=120
userdetails.attribute.name=maxidletime
userdetails.attribute.value=30
userdetails.attribute.name=idletime
userdetails.attribute.value=664
userdetails.attribute.name=timeleft
userdetails.attribute.value=6319
  

3.6. Authorization & Policy Management

OpenAM provides REST APIs both for requesting policy decisions, and also for administering policy definitions.

  • Under /json[/realm]/policies, you find the newer JSON-based APIs.

    Under /json[/realm]/applications and /json/applicationtypes you find JSON-based APIs for administering applications and reading application types.

    Under /json/conditiontypes you find a JSON-based API for viewing what types of conditions you can use when defining policies.

    Under /json/subjecttypes you find a JSON-based API for viewing what types of subjects you can use when defining policies.

    Under /json/decisioncombiners you find a JSON-based API for viewing implementations you can use when defining policies to specify how to combine results when multiple policies apply.

    See Section 3.6.1, “Authorization” below.

  • Under /identity/authorize and /ws/1/entitlement/, you find the backwards-compatible, legacy APIs.

    See Section 3.6.2, “Authorization (Legacy API)” below.

3.6.1. Authorization

3.6.1.1. Requesting Policy Decisions

You can request policy decisions from OpenAM by using the REST APIs described in this section. OpenAM evaluates the request based on the context and the policies configured, and returns decision that indicate what actions are allowed or denied, as well as any attributes or advice for the resources specified.

To request a decision for specific resources, see Section 3.6.1.1.1, “Requesting Policy Decisions For Specific Resources”.

To request decisions for a resource and all resources beneath it, see Section 3.6.1.1.2, “Requesting Policy Decisions For a Tree of Resources”.

3.6.1.1.1. Requesting Policy Decisions For Specific Resources

This section shows how you can request a policy decision over REST for specific resources.

To request policy decisions for specific resources, perform an HTTP POST using the evaluation action to the appropriate path under the URI where OpenAM is deployed, /json[/realm]/policies?_action=evaluate, where realm optionally specifies the realm. The payload for the HTTP POST is a JSON object that specifies at least the resources, and takes the following form.

{
    "resources": [
        "resource1",
        "resource2",
        ...,
        "resourceN"
    ],
    "application": "optional, defaults to iPlanetAMWebAgentService",
    "subject": "optional subject SSOToken",
    "environment": {
        "optional key1": [
            "value",
            "another value",
            ...
        ],
        "optional key2": [
            "value",
            "another value",
            ...
        ],
        ...
    }
}
    

The values for the fields shown above are explained below.

"resources"

This required field specifies the list of resources for which to return decisions.

For example, when using the default application, "iPlanetAMWebAgentService", you can request decisions for resource URLs.

{
    "resources": [
        "http://www.example.com/index.html",
        "http://www.example.com/do?action=run"
    ]
}
       
"application"

This optional field holds the name of the application, and defaults to "iPlanetAMWebAgentService" if not specified.

For more on available applications, see Section 3.6.1.3, “Defining Applications”.

"subject"

This optional field holds the token ID of the subject, returned for example on successful authentication. See Section 3.3, “Authentication & Logout”.

If you do not specify the token ID, OpenAM uses the token ID of the subject making the request.

"environment"

This optional field holds a map of keys to lists of values.

If you do not specify the environment, the default is an empty map.

The example below requests policy decisions for two URL resources. The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request POST \
 --header "iPlanetDirectoryPro: AQIC5..." \
 --header "Content-Type: application/json" \
 --data '{
    "resources": [
        "http://www.example.com/index.html",
        "http://www.example.com/do?action=run"
    ],
    "application": "iPlanetAMWebAgentService"
 }' \
 https://openam.example.com:8443/openam/json/realm/policies?_action=evaluate
[ {
  "resource" : "http://www.example.com:80/do?action=run",
  "actions" : {
  },
  "attributes" : {
  },
  "advices" : {
    "AuthLevelConditionAdvice" : [ "/realm:3" ]
  }
}, {
  "resource" : "http://www.example.com:80/index.html",
  "actions" : {
    "POST" : false,
    "GET" : true
  },
  "attributes" : {
    "cn" : [ "demo" ]
  },
  "advices" : {
  }
} ]
    

In the JSON list of decisions returned for each resource, OpenAM includes a these fields.

"resource"

A resource specified in the request

Notice that the resources are normalized. In the example, the request does not explicitly specify port 80, but the response does show the port number. Notice also that the decisions returned are not guaranteed to be in the same order as the resources were requested.

"actions"

A map of action name keys to Boolean values that indicate whether the action is allowed (true) or denied (false) for the specified resource

In the example, for resource http://www.example.com:80/index.html HTTP GET is allowed, whereas HTTP POST is denied.

"attributes"

A map of attribute names to their values, if any resource attributes are returned according to applicable policies

In the example, the policy that applies to http://www.example.com:80/index.html causes that the value of the subject's "cn" profile attribute to be returned.

"advices"

A map of advice names to their values, if any advice is returned according to applicable policies

The "advices" field can provide hints regarding what OpenAM needs to take the authorization decision.

In the example, the policy that applies to http://www.example.com:80/do?action=run requests that the subject be authenticated in realm /realm at an authentication level of at least 3.

{
    "advices": {
        "AuthLevelConditionAdvice": [
            "/realm:3"
        ]
    }
}
       

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.1.2. Requesting Policy Decisions For a Tree of Resources

This section shows how you can request policy decisions over REST for a resource and all other resources in the subtree beneath it.

To request policy decisions for a tree of resources, perform an HTTP POST using the evaluation action to the appropriate path under the URI where OpenAM is deployed, /json[/realm]/policies?_action=evaluateTree, where realm optionally specifies the realm. The payload for the HTTP POST is a JSON object that specifies at least the root resource, and takes the following form.

{
    "resource": "resource string",
    "application": "optional, defaults to iPlanetAMWebAgentService",
    "subject": "optional subject SSOToken",
    "environment": {
        "optional key1": [
            "value",
            "another value",
            ...
        ],
        "optional key2": [
            "value",
            "another value",
            ...
        ],
        ...
    }
}
    

The values for the fields shown above are explained below.

"resource"

This required field specifies the root resource for the decisions to return.

For example, when using the default application, "iPlanetAMWebAgentService", you can request decisions for resource URLs.

{
    "resource": "http://www.example.com/"
}
       
"application"

This optional field holds the name of the application, and defaults to "iPlanetAMWebAgentService" if not specified.

For more on available applications, see Section 3.6.1.3, “Defining Applications”.

"subject"

This optional field holds the token ID of the subject, returned for example on successful authentication. See Section 3.3, “Authentication & Logout”.

If you do not specify the token ID, OpenAM uses the token ID of the subject making the request.

"environment"

This optional field holds a map of keys to lists of values.

If you do not specify the environment, the default is an empty map.

The example below requests policy decisions for http://www.example.com/. The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation, and the subject takes the SSO token of the user who wants to access a resource.

$ curl \
 --request POST \
 --header "iPlanetDirectoryPro: AQIC5...NDU1*" \
 --header "Content-Type: application/json" \
 --data '{
    "resource": "http://www.example.com/",
    "subject": "AQIC5...zE4*"
 }' \
 https://openam.example.com:8443/openam/json/realm/policies?_action=evaluateTree
[ {
  "resource" : "http://www.example.com:80/",
  "actions" : {
    "GET" : true,
    "OPTIONS" : true,
    "HEAD" : true
  },
  "attributes" : {
  },
  "advices" : {
  }
}, {
  "resource" : "http://www.example.com:80/*",
  "actions" : {
    "POST" : false,
    "PATCH" : false,
    "GET" : true,
    "DELETE" : true,
    "OPTIONS" : true,
    "HEAD" : true,
    "PUT" : true
  },
  "attributes" : {
    "myStaticAttr" : [ "myStaticValue" ]
  },
  "advices" : {
  }
}, {
  "resource" : "http://www.example.com:80/*?*",
  "actions" : {
    "POST" : false,
    "PATCH" : false,
    "GET" : false,
    "DELETE" : false,
    "OPTIONS" : true,
    "HEAD" : false,
    "PUT" : false
  },
  "attributes" : {
  },
  "advices" : {
    "AuthLevelConditionAdvice" : [ "/:3" ]
  }
} ]
    

Notice that OpenAM returns decisions not only for the specified resource, but also for matching resource names in the tree whose root is the specified resource.

In the JSON list of decisions returned for each resource, OpenAM includes a these fields.

"resource"

A resource name whose root is the resource specified in the request

Notice that the resources are normalized. In the example, the request does not explicitly specify port 80, but the response does show the port number.

"actions"

A map of action name keys to Boolean values that indicate whether the action is allowed (true) or denied (false) for the specified resource

In the example, for matching resources with a query string only HTTP OPTIONS is allowed according to the policies configured.

"attributes"

A map of attribute names to their values, if any resource attributes are returned according to applicable policies

In the example, the policy that applies to http://www.example.com:80/* causes a static attribute to be returned.

"advices"

A map of advice names to their values, if any advice is returned according to applicable policies

The "advices" field can provide hints regarding what OpenAM needs to take the authorization decision.

In the example, the policy that applies to resources with a query string requests that the subject be authenticated at an authentication level of at least 3.

{
    "advices": {
        "AuthLevelConditionAdvice": [ "/:3" ]
    }
}
       

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.2. Managing Policies

Policy resources are represented in JSON and take the following form. Policy resources are built from standard JSON objects and values (strings, numbers, objects, arrays, true, false, and null).

{
   "name": "test",
   "active": true,
   "description": "A test policy",
   "resources": {
       "included": [
           "http://www.example.com:80/*"
       ],
       "excluded": [
           "http://www.example.com:80/images/*"
       ]
   },
   "applicationName": "application name",
   "actionValues": {
       "read": true,
       "write": false
   },
   "subject": {
       "a subject or": "a composite of subjects"
   },
   "condition": {
       "a condition or": "a composite of conditions"
   },
   "resourceAttributes": [
       {
           "type": "Static",
           "propertyName": "name",
           "propertyValues": [
               "value"
           ]
       },
       {
           "type": "User",
           "propertyName": "profile attribute",
           "propertyValues": [
               "profile attribute", ...
           ]
       },
   ]
}
   

The values for the fields shown in the example are explained below.

"name"

String matching the name in the URL used when creating the policy by HTTP PUT or in the body when creating the policy by HTTP POST

"active"

Boolean indicating whether OpenAM considers the policy active for evaluation purposes, defaults to false

"description"

String describing the policy

"resources"

List of the resource name pattern strings to which the policy applies ("included") and does not apply ("excluded")

"applicationName"

String application name, such as "iPlanetAMWebAgentService", "crestPolicyService", or some other application name

"actionValues"

Set of string action names, each set to a boolean indicating whether the action is allowed

Action values can also be expressed as numeric values. When using numeric values, use the value 0 for false and use any non-zero numeric value for true.

"subject"

Specifies the subjects to which the policy applies, where subjects can be combined by using the built-in types "AND", "OR", and "NOT", and where subject implementations are pluggable

Subjects are shown as JSON objects with "type" set to the name of the implementation (using a short name for all registered subject implementations), and also other fields depending on the implementation. The subject types registered by default include the following.

  • "AnyUser", meaning any authenticated user

  • "Attribute" to specify attributes of the subject's profile as in the following example.

    {
       "subject": {
           "type": "Attribute",
           "name": "ou",
           "value": "Product Testing"
       }
    }
            
  • "Group" to specify a particular group as in the following example.

    {
       "subject": {
           "type": "Group",
           "id": "id=HR Managers,ou=group,dc=openam,dc=forgerock,dc=org"
       }
    }
            
  • "NONE", meaning no subject

  • "Role" to specify a particular OpenAM role as in the following example.

    {
       "subject": {
           "type": "Role",
           "id": "id=admins,ou=role,dc=openam,dc=forgerock,dc=org"
       }
    }
            
  • "User" to specify a particular user as in the following example.

    {
       "subject": {
           "type": "User",
           "id": "id=bob,ou=user,dc=openam,dc=forgerock,dc=org"
       }
    }
            

"Policy" subject types can be used to correspond to the subject configured for policies as in the following example.

{
   "type": "Policy",
   "name": "All authenticated users",
   "className": "com.sun.identity.policy.plugins.AuthenticatedUsers",
   "values": []
}
      

The following example defines the subject either as Bob Dobbs or as a member of the HR Managers group.

{
   "subject": {
       "type": "OR",
       "subjects": [
           {
               "subject": {
                   "type": "User",
                   "id": "id=bob,ou=user,dc=openam,dc=forgerock,dc=org"
               }
           },
           {
               "subject": {
                   "type": "Group",
                   "id": "id=HR Managers,ou=group,dc=openam,dc=forgerock,dc=org"
               }
           }
       ]
   }
}
      

To read a subject type description, or to list available subject types, see Section 3.6.1.6, “Viewing Subject Types”.

"condition"

Specifies additional conditions, where conditions can be combined by using the built-in types "AND", "OR", and "NOT", and where condition implementations are pluggable

Conditions are shown as JSON objects with "type" set to the name of the implementation (using a short name for all registered condition implementations), and also other fields depending on the implementation. The condition types registered by default include the following.

  • "AttributeLookup" to specify a value to match in the resource as in the following example.

    {
       "type": "AttributeLookup",
       "key": "postaladdress",
       "value": "33 New Montgomery St."
    }
            
  • "DNSName" to specify domain names where the request originated as in the following example.

    {
       "type": "DNSName",
       "domainNameMask": "*.example.com"
    }
            
  • "IP" to specify an IP address range as in the following example.

    {
       "type": "IP",
       "startIp": "127.0.0.1",
       "endIp": "127.0.0.255"
    }
            
  • "NumericAttribute" to specify a value or range for a numeric attribute from the subject's user profile as in the following example.

    {
       "type": "NumericAttribute",
       "attributeName": "gidNumber",
       "caseSensitive": "<=",
       "value": "1000"
    }
            

    "caseSensitive" is optional, but if used then it should be set to a comparison operator, one of: < <= = > >=. If not specified, then OpenAM checks for equality.

  • "StringAttribute" to specify a value for a string-valued attribute from the subject's user profile as in the following example.

    {
        "type": "StringAttribute",
        "attributeName": "location",
        "caseSensitive": false,
        "value": "Bristol"
    }
             
  • "Time" to specify a time range, where type is the only required field in the following example.

    {
        "type": "Time",
        "startTime": "08:30",
        "endTime": "17:30",
        "startDay": "MONDAY",
        "endDay": "FRIDAY",
        "startDate": "01/01/2014",
        "endDate": "12/31/2014",
        "enforcementTimeZone": "GMT-8"
    }
             

"Policy" condition types can be used to correspond to the conditions configured for policies as in the following example.

{
    "type": "Policy",
    "className": "org.forgerock.openam.policy.plugins.OAuth2ScopeCondition",
    "name": "oauth2scope",
    "properties": {
        "OAuth2Scope": [
            "openid profile"
        ]
    }
}
       

The following example defines the condition as neither Saturday or Sunday, nor certain client IP addresses.

{
    "type": "NOT",
    "condition": {
        "type": "OR",
        "conditions": [
            {
                "type": "Time",
                "startDay": "SATURDAY",
                "endDay": "SUNDAY",
                "enforcementTimeZone": "GMT"
            },
            {
                "type": "IP",
                "startIp": "192.168.0.1",
                "endIp": "192.168.0.255"
            }
        ]
    }
}
       

To read a condition type description, or to list available condition types, see Section 3.6.1.5, “Viewing Condition Types”.

"resourceAttributes"

List of resource attributes to return with decisions, where resource attribute implementations are pluggable

The default implementations provide for statically defined attributes and for attributes retrieved from user profiles.

Attributes are shown as JSON objects with "type" set to the name of the implementation (by default either "Static" for statically defined attributes or "User" for attributes from the user profile), "propertyName" set to the attribute names. In the current implementation, "propertyValues" also holds attribute names rather than attribute values.

The examples above do not show the fields added to a policy by OpenAM to indicate when the policy was created and last updated, and by whom. Those field are "createdBy" and "lastModifiedBy", which take strings holding universal identifier DNs as their values, and "creationDate" and "lastModified", which take strings holding ISO-8601 timestamps.

3.6.1.2.1. Creating Policies

To create a policy, either perform an HTTP PUT indicating the full path to the resource and the name in the resource matching the name in the path, or perform an HTTP POST with the name to use specified in the resource.

The HTTP PUT form includes the policy definition as the JSON resource data, with the header Content-Type: application/json and uses the If-None-Match: * header.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request PUT \
 --header "iPlanetDirectoryPro: AQIC5w..." \
 --header "If-None-Match: *" \
 --header "Content-Type: application/json" \
 --data '{
    "name": "example",
    "active": true,
    "description": "Example Policy",
    "resources": {
        "included": [
            "http://www.example.com:80/*",
            "http://www.example.com:80/*?*"
        ],
        "excluded": []
    },
    "actionValues": {
        "POST": false,
        "GET": true
    },
    "subject": {
        "type": "User",
        "subjectName": "Bob Dobbs"
    }
}' \
 https://openam.example.com:8443/openam/json/realm/policies/example

{
  "name" : "example",
  "active" : true,
  "description" : "Example Policy",
  "resources" : {
    "included" : [ "http://www.example.com:80/*",
                   "http://www.example.com:80/*?*" ],
    "excluded" : [ ]
  },
  "applicationName" : "iPlanetAMWebAgentService",
  "actionValues" : {
    "POST" : false,
    "GET" : true
  },
  "subject" : {
    "type" : "User",
    "subjectName" : "Bob Dobbs"
  },
  "lastModifiedBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "lastModified" : "2014-04-24T16:23:34Z",
  "createdBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "creationDate" : "2014-04-24T16:23:34Z"
}
     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

The HTTP POST form includes the policy definition as the JSON resource data, with the header Content-Type: application/json and uses the _action=create operation.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request POST \
 --header "iPlanetDirectoryPro: AQIC5..." \
 --header "Content-Type: application/json" \
 --data '{
    "name": "example",
    "active": true,
    "description": "Example Policy",
    "resources": {
        "included": [
            "http://www.example.com:80/*",
            "http://www.example.com:80/*?*"
        ],
        "excluded": []
    },
    "actionValues": {
        "POST": false,
        "GET": true
    },
    "subject": {
        "type": "User",
        "subjectName": "Bob Dobbs"
    }
}' \
 https://openam.example.com:8443/openam/json/realm/policies?_action=create
{
  "name" : "example",
  "active" : true,
  "description" : "Example Policy",
  "resources" : {
    "included" : [ "http://www.example.com:80/*",
                   "http://www.example.com:80/*?*" ],
    "excluded" : [ ]
  },
  "applicationName" : "iPlanetAMWebAgentService",
  "actionValues" : {
    "POST" : false,
    "GET" : true
  },
  "subject" : {
    "type" : "User",
    "subjectName" : "Bob Dobbs"
  },
  "lastModifiedBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "lastModified" : "2014-04-29T07:33:54Z",
  "createdBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "creationDate" : "2014-04-29T07:33:54Z"
}
     
3.6.1.2.2. Reading Policies

To read a policy definition, perform an HTTP GET specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/policies/example

{
  "name" : "example",
  "active" : true,
  "description" : "Example Policy",
  "resources" : {
    "included" : [ "http://www.example.com:80/*",
                   "http://www.example.com:80/*?*" ],
    "excluded" : [ ]
  },
  "applicationName" : "iPlanetAMWebAgentService",
  "actionValues" : {
    "POST" : false,
    "GET" : true
  },
  "subject" : {
    "type" : "User",
    "subjectName" : "Bob Dobbs"
  },
  "lastModifiedBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "lastModified" : "2014-04-24T16:23:34Z",
  "createdBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "creationDate" : "2014-04-24T16:23:34Z"
}
     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.2.3. Updating Policies

To update a policy definition, perform an HTTP PUT specifying the resource name with the policy definition as the JSON resource data, and with the header Content-Type: application/json. This is essentially the same as creating a policy, but without the If-None-Match: * header.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request PUT \
 --header "iPlanetDirectoryPro: AQIC5w..." \
 --header "Content-Type: application/json" \
 --data '{
    "name": "example",
    "active": true,
    "description": "Updated example policy",
    "resources": {
        "included": [
            "http://www.example.com:80/*",
            "http://www.example.com:80/*?*"
        ],
        "excluded": []
    },
    "actionValues": {
        "POST": true,
        "GET": true
    },
    "subject": {
        "type": "User",
        "subjectName": "Bob Dobbs"
    }
}' \
 https://openam.example.com:8443/openam/json/realm/policies/example

{
  "name" : "example",
  "active" : true,
  "description" : "Updated example policy",
  "resources" : {
    "included" : [ "http://www.example.com:80/*",
                   "http://www.example.com:80/*?*" ],
    "excluded" : [ ]
  },
  "applicationName" : "iPlanetAMWebAgentService",
  "actionValues" : {
    "POST" : true,
    "GET" : true
  },
  "subject" : {
    "type" : "User",
    "subjectName" : "Bob Dobbs"
  },
  "lastModifiedBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "lastModified" : "2014-04-24T16:44:01Z",
  "createdBy" :
   "id=demo,ou=user,o=realm,ou=services,dc=openam,dc=forgerock,dc=org",
  "creationDate" : "2014-04-24T16:23:34Z"
}
     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.2.4. Deleting Policies

To delete a policy definition, perform an HTTP DELETE specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w..." \
 --request DELETE \
 https://openam.example.com:8443/openam/json/realm/policies/example
{}
     
3.6.1.2.5. Listing Policies

To list policy definitions, perform an HTTP GET on the endpoint, setting at least the _queryFilter query string parameter.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w..." \
 https://openam.example.com:8443/openam/json/realm/policies?_queryFilter=true
{
  "result" : [ ...policies... ],
  "resultCount" : 0,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
     

The _queryFilter parameter can take true to match every policy, false to match no policies, or a filter of the following form to match field values: field operator value where field represents the field name, operator is the operator code, value is the value to match, and the entire filter is URL encoded. Supported operators are as follows.

  • eq: equals

  • ge: greater than or equal to

  • gt: greater than

  • le: less than or equal to

  • lt: less than

The field value can take the following values.

  • "name" (string equality only)

  • "description" (string equality only)

  • "applicationName" (string equality only)

  • "createdBy" (string equality only)

  • "lastModifiedBy" (string equality only)

  • "creationDate" (all comparisons are supported; the date is either an ISO-8601 string, or a integer number of seconds from the UNIX epoch)

  • "lastModified" (all comparisons are supported; the date is either an ISO-8601 string, or a integer number of seconds from the UNIX epoch)

Filters can be composed of multiple expressions by a using boolean operator AND, and by using parentheses, (expression), to group expressions. You must URL encode the filter expression in _queryFilter=filter.

You can use the query string parameters _prettyPrint=true to make the output easier to read, _fields=field-name[,field-name...] to limit the fields returned in the output.

You can use _pageSize=integer to limit the number of results returned, as shown in the following example that returns only the first of three policies.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w..." \
 https://openam.example.com:8443/openam/json/policies?_queryFilter=true\&_fields=name\&_pageSize=1
{
  "result" : [ {
    "name" : "My Other Policy"
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : 2
}
     

You can use _sortKeys=[+-]field[,field...] to sort the results returned, where field represents a field in the JSON policy objects returned. Optionally use the + prefix to sort in ascending order (the default), or - to sort in descending order. The following example sorts the policy objects by their names.

  $ curl \
 --header "iPlanetDirectoryPro: AQIC5w..." \
 https://openam.example.com:8443/openam/json/policies?_queryFilter=true\&_sortKeys=name
  {
  "result" : [ {
    "name" : "Another Example Policy",
    ...
  }, {
    "name" : "My Other Policy",
    ...
  }, {
    "name" : "Sample Policy",
    ...
  } ],
  "resultCount" : 3,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : 0
}
     

3.6.1.3. Defining Applications

Application definitions set constraints for the policies that can be defined for a particular application.

Application resources are represented in JSON and take the following form. Application resources are built from standard JSON objects and values (strings, numbers, objects, arrays, true, false, and null).

{
  "name": "application name string",
  "resources": [
     "resource name pattern",
     ...
  ],
  "actions": {
     "action name string": true,
     "other action name string": false,
     ...
  },
  "conditions": [
     "condition type",
     ...
  ],
  "realm": "/realm",
  "applicationType": "application type name string",
  "description": "string describing application",
  "resourceComparator": "resource comparator class name",
  "subjects": [
     "subject type",
     ...
  ],
  "entitlementCombiner": "decision combiner",
  "saveIndex": "save index class name",
  "searchIndex": "search index class name",
  "attributeNames": [
     "attribute implementation class name",
     ...
  ]
}
    

The values for the fields shown in the description are explained below.

"name"

String matching the name in the URL used when creating the application by HTTP PUT or in the body when creating the application by HTTP POST

"resources"

Strings specifying resource name patterns as in the following example

{
    "resources": [
        "http://www.example.com:8080/*",
        "http://www.example.com:8080/*?*"
    ]
}
       
"actions"

Set of string action names, each set to a boolean indicating whether the action is allowed in the context of this application as in the following example

{
    "actions": {
        "UPDATE": true,
        "PATCH": true,
        "QUERY": true,
        "CREATE": true,
        "DELETE": true,
        "READ": true,
        "ACTION": true
    }
}
       
"conditions"

Condition types allowed in the context of this application

The following condition types are available.

"AND"
"AttributeLookup"
"DNSName"
"IP"
"NOT"
"NumericAttribute"
"OR"
"Policy"
"StringAttribute"
"Time"

For more on condition types, see Section 3.6.1.5, “Viewing Condition Types”.

"realm"

Name of the realm where this application is defined

"applicationType"

Name of the application type used as a template for this application

"description"

String describing the application

"resourceComparator"

Class name of the resource comparator implementation used in the context of this application

The following implementations are available.

"com.sun.identity.entitlement.ExactMatchResourceName"
"com.sun.identity.entitlement.PrefixResourceName"
"com.sun.identity.entitlement.RegExResourceName"
"com.sun.identity.entitlement.URLResourceName"
"subjects"

Subject types allowed in the context of this application

The following subject types are available.

"AND"
"AnyUser"
"Attribute"
"Group"
"NONE"
"NOT"
"OR"
"Policy"
"Role"
"User"

For more on subject types, see Section 3.6.1.6, “Viewing Subject Types”.

"entitlementCombiner"

Name of the decision combiner, such as "DenyOverride".

For more on decision combiners, see Section 3.6.1.7, “Viewing Decision Combiners”.

"saveIndex"

Class name of the implementation for creating indexes for resource names, such as "com.sun.identity.entitlement.util.ResourceNameIndexGenerator" for URL resource names

"searchIndex"

Class name of the implementation for searching indexes for resource names, such as "com.sun.identity.entitlement.util.ResourceNameSplitter" for URL resource names

"attributeNames"

Class names of implementations for getting attributes such as "com.sun.identity.entitlement.StaticAttributes", and "com.sun.identity.entitlement.UserAttributes"

The examples above do not show the fields added by OpenAM to indicate when the application was created and last updated, and by whom. Those field are "createdBy" and "lastModifiedBy", which take strings holding universal identifier DNs as their values, and "creationDate" and "lastModifiedDate", which an integer number of seconds since the Unix epoch.

3.6.1.3.1. Creating Applications

To create an application definition, either perform an HTTP PUT indicating the full path to the resource and the name in the resource matching the name in the path, or perform an HTTP POST with the name to use specified in the resource.

The HTTP PUT form includes the application definition as the JSON resource data, with the header Content-Type: application/json and uses the If-None-Match: * header.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request PUT \
 --header "If-None-Match: *" \
 --header "iPlanetDirectoryPro: AQIC5..." \
 --header "Content-Type: application/json" \
 --data '{
    "name": "crest",
    "resources": [
        "http://www.example.com:8080/*",
        "http://www.example.com:8080/*?*"
    ],
    "actions": {
        "UPDATE": true,
        "PATCH": true,
        "QUERY": true,
        "CREATE": true,
        "DELETE": true,
        "READ": true,
        "ACTION": true
    },
    "conditions": [
        "not",
        "dateRange",
        "timezone",
        "timeRange",
        "or",
        "dnsName",
        "ipRange",
        "daysOfWeek",
        "and"
    ],
    "realm": "/realm",
    "applicationType": "crestPolicyService",
    "description": "An example application for Common REST",
    "resourceComparator": "com.sun.identity.entitlement.URLResourceName",
    "subjects": [
        "com.sun.identity.admin.model.IdRepoUserViewSubject",
        "com.sun.identity.admin.model.NotViewSubject",
        "com.sun.identity.admin.model.IdRepoRoleViewSubject",
        "com.sun.identity.admin.model.AndViewSubject",
        "com.sun.identity.admin.model.VirtualViewSubject",
        "com.sun.identity.admin.model.OrViewSubject",
        "com.sun.identity.admin.model.IdRepoGroupViewSubject",
        "com.sun.identity.admin.model.AttributeViewSubject"
    ],
    "entitlementCombiner": "com.sun.identity.entitlement.DenyOverride",
    "saveIndex": null,
    "searchIndex": null,
    "attributeNames": []
}' \
 https://openam.example.com:8443/openam/json/applications/crest
{
  "name" : "crest",
  "resources" : [
   "http://www.example.com:8080/*",
   "http://www.example.com:8080/*?*"
  ],
  "actions" : {
    "UPDATE" : true,
    "PATCH" : true,
    "QUERY" : true,
    "CREATE" : true,
    "DELETE" : true,
    "READ" : true,
    "ACTION" : true
  },
  "conditions" : [
   "not",
   "dateRange",
   "timezone",
   "timeRange",
   "or",
   "dnsName",
   "ipRange",
   "daysOfWeek",
   "and"
  ],
  "realm" : "/",
  "creationDate" : 1398761708295,
  "lastModifiedDate" : 1398761708295,
  "createdBy" : "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
  "lastModifiedBy" : "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
  "applicationType" : "crestPolicyService",
  "description" : "An example application for Common REST",
  "resourceComparator" : "com.sun.identity.entitlement.URLResourceName",
  "subjects" : [
   "com.sun.identity.admin.model.IdRepoUserViewSubject",
   "com.sun.identity.admin.model.NotViewSubject",
   "com.sun.identity.admin.model.AndViewSubject",
   "com.sun.identity.admin.model.IdRepoRoleViewSubject",
   "com.sun.identity.admin.model.OrViewSubject",
   "com.sun.identity.admin.model.VirtualViewSubject",
   "com.sun.identity.admin.model.IdRepoGroupViewSubject",
   "com.sun.identity.admin.model.AttributeViewSubject"
  ],
  "entitlementCombiner" : "com.sun.identity.entitlement.DenyOverride",
  "saveIndex" : null,
  "searchIndex" : null,
  "attributeNames" : [ ]
}
     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

The HTTP POST form includes the application definition as the JSON resource data, with the header Content-Type: application/json and uses the _action=create operation.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request POST \
 --header "iPlanetDirectoryPro: AQIC5..." \
 --header "Content-Type: application/json" \
 --data '{
    "name": "crest",
    "resources": [
        "http://www.example.com:8080/*",
        "http://www.example.com:8080/*?*"
    ],
    "actions": {
        "UPDATE": true,
        "PATCH": true,
        "QUERY": true,
        "CREATE": true,
        "DELETE": true,
        "READ": true,
        "ACTION": true
    },
    "conditions": [
        "not",
        "dateRange",
        "timezone",
        "timeRange",
        "or",
        "dnsName",
        "ipRange",
        "daysOfWeek",
        "and"
    ],
    "realm": "/realm",
    "applicationType": "crestPolicyService",
    "description": "An example application for Common REST",
    "resourceComparator": "com.sun.identity.entitlement.URLResourceName",
    "subjects": [
        "com.sun.identity.admin.model.IdRepoUserViewSubject",
        "com.sun.identity.admin.model.NotViewSubject",
        "com.sun.identity.admin.model.IdRepoRoleViewSubject",
        "com.sun.identity.admin.model.AndViewSubject",
        "com.sun.identity.admin.model.VirtualViewSubject",
        "com.sun.identity.admin.model.OrViewSubject",
        "com.sun.identity.admin.model.IdRepoGroupViewSubject",
        "com.sun.identity.admin.model.AttributeViewSubject"
    ],
    "entitlementCombiner": "com.sun.identity.entitlement.DenyOverride",
    "saveIndex": null,
    "searchIndex": null,
    "attributeNames": []
}' \
 https://openam.example.com:8443/openam/json/applications/?_action=create
{
  "name" : "crest",
  "resources" : [
   "http://www.example.com:8080/*",
   "http://www.example.com:8080/*?*"
  ],
  "actions" : {
    "UPDATE" : true,
    "PATCH" : true,
    "QUERY" : true,
    "CREATE" : true,
    "DELETE" : true,
    "READ" : true,
    "ACTION" : true
  },
  "conditions" : [
   "not",
   "dateRange",
   "timezone",
   "timeRange",
   "or",
   "dnsName",
   "ipRange",
   "daysOfWeek",
   "and"
  ],
  "realm" : "/",
  "creationDate" : 1398762452667,
  "lastModifiedDate" : 1398762452667,
  "createdBy" : "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
  "lastModifiedBy" : "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
  "applicationType" : "crestPolicyService",
  "description" : "An example application for Common REST",
  "resourceComparator" : "com.sun.identity.entitlement.URLResourceName",
  "subjects" : [
   "com.sun.identity.admin.model.IdRepoUserViewSubject",
   "com.sun.identity.admin.model.NotViewSubject",
   "com.sun.identity.admin.model.AndViewSubject",
   "com.sun.identity.admin.model.IdRepoRoleViewSubject",
   "com.sun.identity.admin.model.OrViewSubject",
   "com.sun.identity.admin.model.VirtualViewSubject",
   "com.sun.identity.admin.model.IdRepoGroupViewSubject",
   "com.sun.identity.admin.model.AttributeViewSubject"
  ],
  "entitlementCombiner" : "com.sun.identity.entitlement.DenyOverride",
  "saveIndex" : null,
  "searchIndex" : null,
  "attributeNames" : [ ]
}
     
3.6.1.3.2. Reading Applications

To read an application definition, perform an HTTP GET specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/applications/iPlanetAMWebAgentService
{
  "name" : "iPlanetAMWebAgentService",
  "resources" : [ "http://*:*/*", "http://*:*/*?*" ],
  "actions" : {
    "POST" : true,
    "PATCH" : true,
    "GET" : true,
    "DELETE" : true,
    "OPTIONS" : true,
    "PUT" : true,
    "HEAD" : true
  },
  "conditions" : [
   "not",
   "dateRange",
   "timezone",
   "timeRange",
   "or",
   "dnsName",
   "ipRange",
   "daysOfWeek",
   "and"
  ],
  "realm" : "/realm",
  "creationDate" : 1398760362341,
  "lastModifiedDate" : 1398760362341,
  "createdBy" : "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
  "lastModifiedBy" : "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
  "applicationType" : "iPlanetAMWebAgentService",
  "description" : null,
  "resourceComparator" : "com.sun.identity.entitlement.URLResourceName",
  "subjects" : [
   "com.sun.identity.admin.model.IdRepoUserViewSubject",
   "com.sun.identity.admin.model.NotViewSubject",
   "com.sun.identity.admin.model.AndViewSubject",
   "com.sun.identity.admin.model.IdRepoRoleViewSubject",
   "com.sun.identity.admin.model.OrViewSubject",
   "com.sun.identity.admin.model.VirtualViewSubject",
   "com.sun.identity.admin.model.IdRepoGroupViewSubject",
   "com.sun.identity.admin.model.AttributeViewSubject"
  ],
  "entitlementCombiner" : "com.sun.identity.entitlement.DenyOverride",
  "saveIndex" : null,
  "searchIndex" : null,
  "attributeNames" : [ ]
}
     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.3.3. Updating Applications

To update an application definition, perform an HTTP PUT specifying the resource name with the application definition as the JSON resource data, and with the header Content-Type: application/json. This is essentially the same as creating an application definition, but without the If-None-Match: * header.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request PUT \
 --header "iPlanetDirectoryPro: AQIC5..." \
 --header "Content-Type: application/json" \
 --data '{
    "name": "crest",
    "resources": [
        "http://www.example.com:8080/*",
        "http://www.example.com:8080/*?*"
    ],
    "actions": {
        "UPDATE": false,
        "PATCH": false,
        "QUERY": true,
        "CREATE": false,
        "DELETE": false,
        "READ": true,
        "ACTION": false
    },
    "conditions": [
        "not",
        "dateRange",
        "timezone",
        "timeRange",
        "or",
        "dnsName",
        "ipRange",
        "daysOfWeek",
        "and"
    ],
    "realm": "/realm",
    "applicationType": "crestPolicyService",
    "description": "An read-only example application for Common REST",
    "resourceComparator": "com.sun.identity.entitlement.URLResourceName",
    "subjects": [
        "com.sun.identity.admin.model.IdRepoUserViewSubject",
        "com.sun.identity.admin.model.NotViewSubject",
        "com.sun.identity.admin.model.IdRepoRoleViewSubject",
        "com.sun.identity.admin.model.AndViewSubject",
        "com.sun.identity.admin.model.VirtualViewSubject",
        "com.sun.identity.admin.model.OrViewSubject",
        "com.sun.identity.admin.model.IdRepoGroupViewSubject",
        "com.sun.identity.admin.model.AttributeViewSubject"
    ],
    "entitlementCombiner": "com.sun.identity.entitlement.DenyOverride",
    "saveIndex": null,
    "searchIndex": null,
    "attributeNames": []
}' \
 https://openam.example.com:8443/openam/json/applications/crest
{
  "name" : "crest",
  "resources" : [
   "http://www.example.com:8080/*",
   "http://www.example.com:8080/*?*"
  ],
  "actions" : {
    "UPDATE" : false,
    "PATCH" : false,
    "QUERY" : true,
    "CREATE" : false,
    "DELETE" : false,
    "READ" : true,
    "ACTION" : false
  },
  "conditions" : [
   "not",
   "dateRange",
   "timezone",
   "timeRange",
   "or",
   "dnsName",
   "ipRange",
   "daysOfWeek",
   "and"
  ],
  "realm" : "/",
  "creationDate" : 1398762194628,
  "lastModifiedDate" : 1398762194628,
  "createdBy" : "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
  "lastModifiedBy" : "id=amadmin,ou=user,dc=openam,dc=forgerock,dc=org",
  "applicationType" : "crestPolicyService",
  "description" : "An read-only example application for Common REST",
  "resourceComparator" : "com.sun.identity.entitlement.URLResourceName",
  "subjects" : [
   "com.sun.identity.admin.model.IdRepoUserViewSubject",
   "com.sun.identity.admin.model.NotViewSubject",
   "com.sun.identity.admin.model.AndViewSubject",
   "com.sun.identity.admin.model.IdRepoRoleViewSubject",
   "com.sun.identity.admin.model.OrViewSubject",
   "com.sun.identity.admin.model.VirtualViewSubject",
   "com.sun.identity.admin.model.IdRepoGroupViewSubject",
   "com.sun.identity.admin.model.AttributeViewSubject"
  ],
  "entitlementCombiner" : "com.sun.identity.entitlement.DenyOverride",
  "saveIndex" : null,
  "searchIndex" : null,
  "attributeNames" : [ ]
}
     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.3.4. Deleting Applications

To delete an application definition, perform an HTTP DELETE specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --request DELETE \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/applications/crest
{}
     
3.6.1.3.5. Listing Applications

To list application definitions, perform an HTTP GET on the endpoint, setting at least the _queryFilter query string parameter.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/applications?_queryFilter=true
{
  "result" : [ {
    "name" : "iPlanetAMWebAgentService",
    "resources" : [ "http://*:*/*", "http://*:*/*?*" ],
    "actions" : {
      "POST" : true,
      "PATCH" : true,
      "GET" : true,
      "DELETE" : true,
      "OPTIONS" : true,
      "PUT" : true,
      "HEAD" : true
    },
    "conditions" : [
     "not",
     "dateRange",
     "timezone",
     "timeRange",
     "or",
     "dnsName",
     "ipRange",
     "daysOfWeek",
     "and"
    ],
    "realm" : "/realm",
    "creationDate" : 1398760362341,
    "lastModifiedDate" : 1398760362341,
    "createdBy" : "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
    "lastModifiedBy" : "id=dsameuser,ou=user,dc=openam,dc=forgerock,dc=org",
    "applicationType" : "iPlanetAMWebAgentService",
    "description" : null,
    "resourceComparator" : "com.sun.identity.entitlement.URLResourceName",
    "subjects" : [
     "com.sun.identity.admin.model.IdRepoUserViewSubject",
     "com.sun.identity.admin.model.NotViewSubject",
     "com.sun.identity.admin.model.AndViewSubject",
     "com.sun.identity.admin.model.IdRepoRoleViewSubject",
     "com.sun.identity.admin.model.OrViewSubject",
     "com.sun.identity.admin.model.VirtualViewSubject",
     "com.sun.identity.admin.model.IdRepoGroupViewSubject",
     "com.sun.identity.admin.model.AttributeViewSubject"
    ],
    "entitlementCombiner" : "com.sun.identity.entitlement.DenyOverride",
    "saveIndex" : null,
    "searchIndex" : null,
    "attributeNames" : [ ]
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
     

The _queryFilter parameter can take true to match every policy, false to match no policies, or a filter of the following form to match field values: field operator value where field represents the field name, operator is the operator code, value is the value to match, and the entire filter is URL encoded. Supported operators are as follows.

  • eq: equals (for matching strings)

  • ge: greater than or equal to (for matching integers)

  • gt: greater than (for matching integers)

  • le: less than or equal to (for matching integers)

  • lt: less than (for matching integers)

The field value can take the following values.

  • "name"

  • "description"

  • "applicationName"

  • "createdBy"

  • "lastModifiedBy"

  • "creationDate"

  • "lastModified"

Filters can be composed of multiple expressions by a using boolean operator AND, and by using parentheses, (expression), to group expressions. You must URL encode the filter expression in _queryFilter=filter.

You can use the query string parameters _prettyPrint=true to make the output easier to read, _fields=field-name[,field-name...] to limit the fields returned in the output.

You can use _pageSize=integer to limit the number of results returned.

3.6.1.4. Viewing Application Types

Application types act as templates for creating applications.

Applications types are server-wide, and do not differ by realm. Hence the URI for the application types API does not contain a realm component, but is /json/applicationtypes.

Application type resources are represented in JSON and take the following form. Application type resources are built from standard JSON objects and values (strings, numbers, objects, arrays, true, false, and null).

{
  "name": "application type name string",
  "actions": {
     "action name string": true,
     "other action name string": false,
     ...
  },
  "resourceComparator": "resource comparator class name",
  "saveIndex": "save index class name",
  "searchIndex": "search index class name",
  "applicationClassName": "com.sun.identity.entitlement.Application"
}
    

The values for the fields shown in the description are explained below.

"name"

String matching the name in the URL used when creating the application type by HTTP PUT or in the body when creating the application type by HTTP POST

"actions"

Set of string action names, each set to a boolean indicating whether the action is allowed as in the following example

{
    "actions": {
        "UPDATE": true,
        "PATCH": true,
        "QUERY": true,
        "CREATE": true,
        "DELETE": true,
        "READ": true,
        "ACTION": true
    }
}
       
"resourceComparator"

Class name of the resource comparator implementation used in the context of this application

The following implementations are available.

"com.sun.identity.entitlement.ExactMatchResourceName"
"com.sun.identity.entitlement.PrefixResourceName"
"com.sun.identity.entitlement.RegExResourceName"
"com.sun.identity.entitlement.URLResourceName"
"resourceComparator"

Class name of the resource comparator implementation used in the context of this application

The following implementations are available.

"com.sun.identity.entitlement.ExactMatchResourceName"
"com.sun.identity.entitlement.PrefixResourceName"
"com.sun.identity.entitlement.RegExResourceName"
"com.sun.identity.entitlement.URLResourceName"
"saveIndex"

Class name of the implementation for creating indexes for resource names, such as "com.sun.identity.entitlement.util.ResourceNameIndexGenerator" for URL resource names

"searchIndex"

Class name of the implementation for searching indexes for resource names, such as "com.sun.identity.entitlement.util.ResourceNameSplitter" for URL resource names

"applicationClassName"

Class name of the application implementation, such as "com.sun.identity.entitlement.Application"

3.6.1.4.1. Reading Application Types

To read an application type, perform an HTTP GET specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/applicationtypes/crestPolicyService
{
  "name" : "crestPolicyService",
  "actions" : {
    "UPDATE" : true,
    "PATCH" : true,
    "QUERY" : true,
    "CREATE" : true,
    "DELETE" : true,
    "READ" : true,
    "ACTION" : true
  },
  "resourceComparator" : "com.sun.identity.entitlement.URLResourceName",
  "saveIndex" : "org.forgerock.openam.entitlement.indextree.TreeSaveIndex",
  "searchIndex" : "org.forgerock.openam.entitlement.indextree.TreeSearchIndex",
  "applicationClassName" : "com.sun.identity.entitlement.Application"
}

     

You can use the query string parameters _prettyPrint=true to make the output easier to read, and _fields=field-name[,field-name...] to limit the fields returned in the output.

3.6.1.4.2. Listing Application Types

To list application types, perform an HTTP GET on the endpoint, setting at least the _queryFilter query string parameter as in the following example.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/applicationtypes?_queryFilter=true
{
  "result" : [ ... application types ... ],
  "resultCount" : 8,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
     

3.6.1.5. Viewing Condition Types

Condition types describe the JSON representation of conditions that you can use in policy definitions.

Condition types are server-wide, and do not differ by realm. Hence the URI for the condition types API does not contain a realm component, but is /json/conditiontypes.

3.6.1.5.1. Reading Condition Types

To read a condition type, perform an HTTP GET specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

You can use the query string parameter _prettyPrint=true to make the output easier to read.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/conditiontypes/IP
{
  "title" : "IP",
  "logical" : false,
  "config" : {
    "type" : "object",
    "properties" : {
      "startIp" : {
        "type" : "string"
      },
      "endIp" : {
        "type" : "string"
      }
    }
  }
}
     

Notice that the condition type has a title, a "logical" field that indicates whether the type is a logical operator or takes a predicate, and a configuration specification. The configuration specification in this case indicates that an IP condition has two properties, "startIp" and "endIp", each of which take a string value. In other words, a concrete IP condition specification is represented in a policy definition as in the following example.

{
   "type": "IP",
   "startIp": "127.0.0.1",
   "endIp": "127.0.0.255"
}
     

The configuration is what differs the most across condition types. The NOT condition, for example, takes a single condition object as the body of its configuration.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/conditiontypes/NOT
{
  "title" : "NOT",
  "logical" : true,
  "config" : {
    "type" : "object",
    "properties" : {
      "condition" : {
        "type" : "object",
        "properties" : {
        }
      }
    }
  }
}
     

The concrete NOT condition therefore takes the following form.

{
    "type": "NOT",
    "condition": {
        ...
    }
}
     

The OR condition takes an array of conditions.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/conditiontypes/OR
{
  "title" : "OR",
  "logical" : true,
  "config" : {
    "type" : "object",
    "properties" : {
      "conditions" : {
        "type" : "array",
        "items" : {
          "type" : "any"
        }
      }
    }
  }
}
     

A corresponding concrete OR condition thus takes the following form.

{
    "type": "OR",
    "conditions": [
        {
            ...
        },
        {
            ...
        },
        ...
    ]
}
     
3.6.1.5.2. Listing Condition Types

To list all condition types, perform an HTTP GET on the endpoint, setting the query string parameter, _queryFilter=true, as in the following example.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/realm/conditiontypes?_queryFilter=true
{
  "result" : [ ... condition types ... ],
  "resultCount" : 10,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
     

You can use the query string parameter _prettyPrint=true to make the output easier to read.

3.6.1.6. Viewing Subject Types

Subject types describe the JSON representation of subjects that you can use in policy definitions.

Subject types are server-wide, and do not differ by realm. Hence the URI for the subject types API does not contain a realm component, but is /json/subjecttypes.

3.6.1.6.1. Reading Subject Types

To read a subject type, perform an HTTP GET specifying the resource name.

The iPlanetDirectoryPro header sets the SSO token for a user who has access to perform the operation.

You can use the query string parameter _prettyPrint=true to make the output easier to read.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/subjecttypes/User
{
  "title" : "User",
  "logical" : false,
  "config" : {
    "type" : "object",
    "properties" : {
      "id" : {
        "type" : "string"
      }
    }
  }
}
     

Notice that the subject type has a title, a "logical" field that indicates whether the type is a logical operator or takes a predicate, and a configuration specification. The configuration specification in this case indicates that a User subject has one property, an "Id", which takes a string value. In other words, a concrete User subject specification is represented in a policy definition as in the following example.

{
   "type": "User",
   "id": "id=demo,ou=user,dc=openam,dc=forgerock,dc=org"
}
     

The configuration is what differs the most across subject types. The AND condition, for example, takes an array of subject objects as the body of its configuration.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/subjecttypes/AND
{
  "title" : "AND",
  "logical" : true,
  "config" : {
    "type" : "object",
    "properties" : {
      "subjects" : {
        "type" : "array",
        "items" : {
          "type" : "any"
        }
      }
    }
  }
}
     

The concrete AND subject therefore takes the following form.

{
    "type": "AND",
    "subject": [
      {
        ...
      },
      ...
    ]
}
     
3.6.1.6.2. Listing Subject Types

To list all subject types, perform an HTTP GET on the endpoint, setting the query string parameter, _queryFilter=true, as in the following example.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/subjecttypes/?_queryFilter=true
{
  "result" : [ ... subject types ... ],
  "resultCount" : 10,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
     

You can use the query string parameter _prettyPrint=true to make the output easier to read.

3.6.1.7. Viewing Decision Combiners

Decision combiners describe how to resolve policy decisions when multiple policies apply.

Decision combiners are server-wide, and do not differ by realm. Hence the URI for the condition types API does not contain a realm component, but is /json/decisioncombiners.

To list all decision combiners, perform an HTTP GET on the endpoint, setting the query string parameter, _queryFilter=true, as in the following example.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/decisioncombiners/?_queryFilter=true
{
  "result" : [ {
    "title" : "DenyOverride"
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
    

You can use the query string parameter _prettyPrint=true to make the output easier to read.

To view an individual decision combiner, perform an HTTP GET on its resource.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5..." \
 https://openam.example.com:8443/openam/json/decisioncombiners/DenyOverride
{
  "title" : "DenyOverride"
}
    

3.6.2. Authorization (Legacy API)

You can call on OpenAM to decide whether to authorize access to a protected resource based on a valid token. Of course, you must percent encode the resource URI.

Interface Stability: Deprecated

$ curl "https://openam.example.com:8443/openam/identity/authorize?\
uri=http%3A%2F%2Fwww.example.com%3A8080%2Fexamples%2Findex.html\
&subjectid=AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*"
boolean=true
   

To indicate access denied, OpenAM returns boolean=false.

3.6.2.1. Requesting Policy Decisions (Legacy API)

OpenAM provides additional REST APIs for requesting policy decisions.

The policy decision interfaces use the following path suffixes and query string parameters.

Path suffixes for policy decision requests include the following.

  • ws/1/entitlement/decision: request a decision pertaining to a single resource

  • ws/1/entitlement/decisions: request decisions pertaining to multiple resources

  • ws/1/entitlement/entitlement: request decisions for a specified resource URL

  • ws/1/entitlement/entitlements: request decisions for a specified resource URL and all resources underneath

Query string parameters for policy decision requests include the following.

  • subject=encoded-token, where the token is encoded using the method implemented in Encoder.java.

    In the examples for this section, the token ID obtained during authentication for amadmin is abbreviated as AQIC5...DU3* and the encoded token ID for the subject is MJ3QFTr4ZV2QrtlJvXlg0Q2dMRM=.

  • action=get, or action=post, which identifies the user agent action when requesting a decision.

  • application=iPlanetAMWebAgentService or application=crestPolicyService

  • resource=resource-url, or multiple resources=resource-url parameters for multiple decisions.

  • env=requestDnsName%3Dfqdn, env=requestIP%3Ddotted-quads, env=requestTime%3Dseconds-since-epoch, and env=requestDnsName%3Dtime-zone where time-zone is from Java TimeZone.getTimeZone().getID(). The env parameters thus express conditions.

    In order to express a condition that specifies OAuth 2.0 scopes, set the value of the parameter to scope=scopes. To set scopes to openid and profile, use env=scope%3Dopenid%20profile for example.     

Authentication for these interfaces uses cookies, so if your application is not running in a browser, first authenticate as described in Section 3.3, “Authentication & Logout”.

To request a decision for a single resource, use an HTTP GET on /ws/1/entitlement/decision as in the following example.

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 "https://openam.example.com:8443/openam/ws/1/entitlement/decision\
?subject=MJ3QFTr4ZV2QrtlJvXlg0Q2dMRM=&action=GET\
&application=iPlanetAMWebAgentService\
&resource=http%3A%2F%2Fwww.example.com%2Findex.html"
allow
    

If access is denied, the result is deny.

To request decisions for multiple resources, use an HTTP GET on /ws/1/entitlement/decisions as in the following example.

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 "https://openam.example.com:8443/openam/ws/1/entitlement/decisions\
?subject=MJ3QFTr4ZV2QrtlJvXlg0Q2dMRM=&action=GET\
&application=iPlanetAMWebAgentService\
&resources=http%3A%2F%2Fwww.example.com%2Findex.html\
&resources=http%3A%2F%2Fwww.example.com%2Ffavicon.ico"
{
    "statusCode": 200,
    "body": {
        "results": [
            {
                "actionsValues": {
                    "POST": true,
                    "GET": true
                },
                "attributes": {},
                "advices": {},
                "resourceName": "http://www.example.com:80/index.html"
            },
            {
                "actionsValues": {
                    "POST": true,
                    "GET": true
                },
                "attributes": {},
                "advices": {},
                "resourceName": "http://www.example.com:80/favicon.ico"
            }
        ]
    },
    "statusMessage": "OK"
}
    

To request decisions for a given resource, use an HTTP GET on /ws/1/entitlement/entitlement as in the following example.

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 "https://openam.example.com:8443/openam/ws/1/entitlement/entitlement\
?subject=MJ3QFTr4ZV2QrtlJvXlg0Q2dMRM=\
&application=iPlanetAMWebAgentService\
&resource=http%3A%2F%2Fwww.example.com%2F*"
{
    "statusCode": 200,
    "body": {
        "actionsValues": {
            "POST": true,
            "GET": true
        },
        "attributes": {},
        "advices": {},
        "resourceName": "http://www.example.com:80/*"
    },
    "statusMessage": "OK"
}
    

To request decisions for all resources underneath a given resource, use an HTTP GET on /ws/1/entitlement/entitlements as in the following example.

 $ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 "https://openam.example.com:8443/openam/ws/1/entitlement/entitlements\
?subject=MJ3QFTr4ZV2QrtlJvXlg0Q2dMRM=\
&application=iPlanetAMWebAgentService\
&resource=http%3A%2F%2Fwww.example.com%2F"
{
    "statusCode": 200,
    "body": {
        "results": [
            {
                "actionsValues": {},
                "resourceName": "http://www.example.com:80/"
            },
            {
                "actionsValues": {
                    "POST": true,
                    "GET": true
                },
                "advices": {},
                "resourceName": "http://www.example.com:80/*"
            },
            {
                "actionsValues": {
                    "POST": true,
                    "GET": true
                },
                "attributes": {},
                "advices": {},
                "resourceName": "http://www.example.com:80/*?*"
            }
        ]
    },
    "statusMessage": "OK"
}
    

3.6.2.2. Managing Policies (Legacy API)

OpenAM exposes a REST API through the /ws/1/entitlement/privilege endpoint under the deployment URI. The API lets you create, read, update, delete, and query policies.

Authentication for these interfaces uses cookies, so if your application is not running in a browser, first authenticate as described in Section 3.3, “Authentication & Logout”.

3.6.2.2.1. Creating Policies (Legacy API)

You create a policy by using an HTTP POST of the JSON representation to the endpoint. You must URL encode the JSON before passing it to OpenAM.

$ cat entitlement.json
{
    "name": "Example HTTP",
    "eSubject": {
        "state": {
            "className": "com.sun.identity.policy.plugins.AuthenticatedUsers",
            "exclusive": false,
            "name": "All Authenticated Users",
            "values": []
        },
        "className": "com.sun.identity.entitlement.opensso.PolicySubject"
    },
    "entitlement": {
        "actionsValues": {
            "POST": true,
            "GET": true
        },
        "applicationName": "iPlanetAMWebAgentService",
        "name": "authorize",
        "resourceNames": [
            "http://www.example.com:80/*"
        ]
    }
}

$ curl \
 --request POST \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 --data-urlencode "privilege.json@entitlement.json" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege
{"statusCode":201,"body":"Created","statusMessage":"Created"}

$ cat entitlement2.json
{
    "name": "Example HTTPS",
    "eSubject": {
        "state": {
            "className": "com.sun.identity.policy.plugins.AuthenticatedUsers",
            "exclusive": false,
            "name": "All Authenticated Users",
            "values": []
        },
        "className": "com.sun.identity.entitlement.opensso.PolicySubject"
    },
    "entitlement": {
        "actionsValues": {
            "POST": false,
            "GET": true
        },
        "applicationName": "iPlanetAMWebAgentService",
        "name": "authorize",
        "resourceNames": [
            "https://www.example.com:443/*?*"
        ]
    }
}

$ curl \
 --request POST \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 --data-urlencode "privilege.json@entitlement2.json" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege
{"statusCode":201,"body":"Created","statusMessage":"Created"}
     
3.6.2.2.2. Reading Policies (Legacy API)

To read a policy, use an HTTP GET on the endpoint followed by the URL-encoded name of the policy.

Notice that the "state" is returned as a long string, and so is not shown here in full.

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege/Example%20HTTP
{
    "statusCode": 200,
    "body": {
        "results": {
            "name": "Example HTTP",
            "eSubject": {
                "state": "{\n  \"className\": \"com.sun.identity.policy...}",
                "className": "com.sun.identity.entitlement.opensso.PolicySubject"
            },
            "entitlement": {
                "actionsValues": {
                    "POST": true,
                    "GET": true
                },
                "applicationName": "iPlanetAMWebAgentService",
                "name": "authorize",
                "resourceNames": [
                    "http://www.example.com:80/*"
                ]
            }
        }
    },
    "statusMessage": "OK"
}

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege/Example%20HTTPS
{
    "statusCode": 200,
    "body": {
        "results": {
            "name": "Example HTTPS",
            "eSubject": {
                "state": "{\n  \"className\": \"com.sun.identity.policy...}",
                "className": "com.sun.identity.entitlement.opensso.PolicySubject"
            },
            "entitlement": {
                "actionsValues": {
                    "POST": false,
                    "GET": true
                },
                "applicationName": "iPlanetAMWebAgentService",
                "name": "authorize",
                "resourceNames": [
                    "https://www.example.com:443/*?*"
                ]
            }
        }
    },
    "statusMessage": "OK"
}
     
3.6.2.2.3. Updating Policies (Legacy API)

To update a policy, use an HTTP PUT on the endpoint followed by the URL-encoded name of the policy.

$ cat update.json
{
    "name": "Example HTTP",
    "eSubject": {
        "state": {
            "className": "com.sun.identity.policy.plugins.AuthenticatedUsers",
            "exclusive": false,
            "name": "All Authenticated Users",
            "values": []
        },
        "className": "com.sun.identity.entitlement.opensso.PolicySubject"
    },
    "entitlement": {
        "actionsValues": {
            "POST": false,
            "GET": true
        },
        "applicationName": "iPlanetAMWebAgentService",
        "name": "authorize",
        "resourceNames": [
            "http://www.example.com:80/*?*"
        ]
    }
}

$ curl \
 --request PUT \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 --data-urlencode "privilege.json@update.json" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege/Example%20HTTP
{"statusCode":200,"body":"OK","statusMessage":"OK"}
     
3.6.2.2.4. Deleting Policies

To delete a policy, use an HTTP DELETE on the endpoint followed by the URL-encoded name of the policy.

$ curl \
 --request DELETE \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege/Example%20HTTPS
{"statusCode":200,"body":"OK","statusMessage":"OK"}
     
3.6.2.2.5. Querying Policies

To get the names of policies, use an HTTP GET on the endpoint.

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 https://openam.example.com:8443/openam/ws/1/entitlement/privilege
{
    "statusCode": 200,
    "body": {
        "results": [
            "Example HTTPS",
            "Example HTTP"
        ]
    },
    "statusMessage": "OK"
}
     

You can pass a filter query parameter to get only policies that match the filter. Make sure you URL encode the filter value.

$ curl \
 --request GET \
 --cookie "iPlanetDirectoryPro=AQIC5...DU3*" \
 "https://openam.example.com:8443/openam/ws/1/entitlement/privilege\
?subject=MJ3QFTr4ZV2QrtlJvXlg0Q2dMRM=&filter=name%3D*HTTP"
{
    "statusCode": 200,
    "body": {
        "results": [
            "Example HTTP"
        ]
    },
    "statusMessage": "OK"
}
     

3.7. OAuth 2.0 Authorization

OpenAM exposes the following REST endpoints for different OAuth 2.0 purposes.

When accessing the APIs, browser-based REST clients can rely on OpenAM to handle the session as usual. First authenticate with OpenAM. Then perform the operations in the browser session.

Clients not running in a browser can authenticate as described in Section 3.3, “Authentication & Logout”, whereby OpenAM returns a token.id value. Clients pass the token.id value in a header named after the authentication cookie, by default iplanetDirectoryPro.

3.7.1. OAuth 2.0 Client & Resource Server Endpoints

As described in the Administration Guide chapter on Managing OAuth 2.0 Authorization, OpenAM exposes REST endpoints for making calls to OpenAM acting as an authorization server.

In addition to the standard authorization and token endpoints described in RFC 6749, OpenAM also exposes a token information endpoint for resource servers to get information about access tokens so they can determine how to respond to requests for protected resources. OpenAM as authorization server exposes the following endpoints for clients and resource servers.

/oauth2/authorize

Authorization endpoint defined in RFC 6749, used to obtain an authorization grant from the resource owner

Example: https://openam.example.com:8443/openam/oauth2/authorize

/oauth2/access_token

Token endpoint defined in RFC 6749, used to obtain an access token from the authorization server

Example: https://openam.example.com:8443/openam/oauth2/access_token

/oauth2/tokeninfo

Endpoint not defined in RFC 6749, used to validate tokens, and to retrieve information such as scopes

Given an access token, a resource server can perform an HTTP GET on /oauth2/tokeninfo?access_token=token-id to retrieve a JSON object indicating token_type, expires_in, scope, and the access_token ID.

Example: https://openam.example.com:8443/openam/oauth2/tokeninfo

The /oauth2/authorize, and /oauth2/access_token endpoints function as described in RFC 6749.

The /oauth2/authorize endpoint is protected by the policy created during OAuth 2.0 authorization server configuration, which grants all authenticated users access.

The /oauth2/tokeninfo endpoint takes an HTTP GET on /oauth2/tokeninfo?access_token=token-id, and returns information about the token.

Resource servers — or any party having the token ID — can get token information through this endpoint without authenticating. This means any application or user can validate the token without having to be registered with OpenAM.

The following example shows OpenAM issuing an access token, and then returning token information.

$ curl \
 --request POST \
 --user "myClientID:password" \
 --data "grant_type=password&username=demo&password=changeit&scope=cn%20mail" \
 https://openam.example.com:8443/openam/oauth2/access_token
{
    "expires_in": 599,
    "token_type": "Bearer",
    "refresh_token": "f6dcf133-f00b-4943-a8d4-ee939fc1bf29",
    "access_token": "f9063e26-3a29-41ec-86de-1d0d68aa85e9"
}

$ curl https://openam.example.com:8443/openam/oauth2/tokeninfo\
?access_token=f9063e26-3a29-41ec-86de-1d0d68aa85e9
{
    "mail": "demo@example.com",
    "scope": [
        "mail",
        "cn"
    ],
    "cn": "demo",
    "realm": "/",
    "token_type": "Bearer",
    "expires_in": 577,
    "access_token": "f9063e26-3a29-41ec-86de-1d0d68aa85e9"
}
   

The resource server making decisions about whether the token is valid can thus use the /oauth2/tokeninfo endpoint to retrieve expiration information about the token. Depending on the scopes implementation, the JSON response about the token can also contain scope information. As described in the Administration Guide, the default scopes implementation in OpenAM considers scopes to be names of attributes in the resource owner's user profile. Notice that the JSON response contains the values for those attributes from the user's profile, as in the preceding example, with scopes set to mail and cn.

Both the /oauth2/authorize and /oauth2/access_token endpoints can take additional parameters. In particular you must specify the realm using the realm=realm-name parameter if the OpenAM OAuth 2.0 provider is configured for a subrealm rather than / (Top-Level Realm). For example, if the OAuth 2.0 provider is configured for the /customers realm, then use /oauth2/authorize?realm=/customers and /oauth2/access_token?realm=/customers.

The /oauth2/authorize endpoint can also take module and service parameters. Use either as described in Authenticating To OpenAM, where module specifies the authentication module instance to use or service specifies the authentication chain to use when authenticating the resource owner.

3.7.2. OAuth 2.0 Token Administration Endpoint

The OpenAM-specific OAuth 2.0 token administration endpoint lets administrators read, list, and delete OAuth 2.0 tokens. OAuth 2.0 clients can also manage their own tokens.

OpenAM exposes the token administration endpoint at /frrest/oauth2/token, such as https://openam.example.com:8443/openam/frrest/oauth2/token.

Note

This endpoint location is likely to change in the future.

To get a token, perform an HTTP GET on /frrest/oauth2/token/token-id, as in the following example.

$ curl \
 --request POST \
 --user "myClientID:password" \
 --data "grant_type=password&username=demo&password=changeit&scope=cn%20mail" \
 https://openam.example.com:8443/openam/oauth2/access_token
{
    "expires_in": 599,
    "token_type": "Bearer",
    "refresh_token": "f838e7d4-7e84-4743-af7c-9a9c42c2969e",
    "access_token": "9c6a48fc-44b1-4a0c-b4f0-672fba468b0f"
}

$ curl \
 --header "iplanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" \
 https://openam.example.com:8443/openam/frrest/oauth2/token/9c6a48fc...fba468b0f
{
    "scope": [
        "mail",
        "cn"
    ],
    "type": [
        "access_token"
    ],
    "username": [
        "demo"
    ],
    "realm": [
        "/"
    ],
    "id": [
        "9c6a48fc-44b1-4a0c-b4f0-672fba468b0f"
    ],
    "parent": [
        "f838e7d4-7e84-4743-af7c-9a9c42c2969e"
    ],
    "expiry_time": [
        "1355741494888"
    ],
    "client_id": [
        "myClientID"
    ]
}
   

To list tokens, perform an HTTP GET on /frrest/oauth2/token/?_query_id=conditions, where conditions is a comma-separated list of field=value conditions. The fields are taken from the fields returned in the token object through this endpoint.

"expiry_time"

Token expiration time in milliseconds since 00:00:00 UTC, January 1, 1970.

"type"

Either "access_token" or "refresh_token".

"username"

OAuth 2.0 client to whom the token was issued.

"realm"

The realm for which the token was issued.

"id"

Unique ID of the token.

The following example shows a search for current access tokens that were issued to myClientID.

$ curl \
 --header "iplanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" \
 https://openam.example.com:8443/openam/frrest/oauth2/token/?_queryID\
=username%3DmyClientID%2Ctype%3Daccess_token
{
    "result": [
        {
            "scope": [
                "mail",
                "cn"
            ],
            "id": [
                "1b836369-4fcf-4fb2-b819-ee4b1314d4f1"
            ],
            "type": [
                "access_token"
            ],
            "username": [
                "myClientID"
            ],
            "realm": [
                "/"
            ],
            "expiry_time": [
                "1355741986154"
            ]
        },
        {
            "scope": [
                "mail",
                "cn"
            ],
            "type": [
                "access_token"
            ],
            "username": [
                "myClientID"
            ],
            "realm": [
                "/"
            ],
            "id": [
                "5f1763fc-37ae-4698-9e84-d301d49e1f7e"
            ],
            "expiry_time": [
                "1355741982091"
            ]
        }
    ],
    "pagedResultsCookie": null,
    "remainingPagedResults": -1
}
   

To delete a token, perform an HTTP DELETE on /frrest/oauth2/token/token-id, as in the following example.

$ curl \
 --request POST \
 --data "grant_type=client_credentials&username=demo&password=changeit\
&client_id=myClientID&client_secret=password&scope=cn%20mail" \
 https://openam.example.com:8443/openam/oauth2/access_token
{
    "expires_in": 599,
    "token_type": "Bearer",
    "access_token": "867aaab2-61d7-4b78-9b80-4f9098034540"
}

$ curl \
 --request DELETE \
 --header "iplanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" \
 https://openam.example.com:8443/openam/frrest/oauth2/token/867aaab2..098034540
{
    "success": "true"
}
   

3.7.3. OAuth 2.0 Client Administration Endpoint

The OAuth 2.0 administration endpoint lets OpenAM administrators and agent administrators create (that is, register) and delete OAuth 2.0 clients.

OpenAM exposes this endpoint at /frrest/oauth2/client, such as https://openam.example.com:8443/openam/frrest/oauth2/client.

Note

This endpoint location is likely to change in the future.

To create an OAuth 2.0 client, perform an HTTP POST to /frrest/oauth2/client/?_action=create with a JSON object fully specifying the client, as in the following example.

$ curl \
 --request POST \
 --header "iplanetDirectoryPro: AQIC5wM...3MTYxOA..*" \
 --header "Content-Type: application/json" \
 --data \
 '{"client_id":["testClient"],
   "realm":["/"],
   "userpassword":["secret12"],
   "com.forgerock.openam.oauth2provider.clientType":["Confidential"],
   "com.forgerock.openam.oauth2provider.redirectionURIs":
     ["www.client.com","www.example.com"],
   "com.forgerock.openam.oauth2provider.scopes":["cn","sn"],
   "com.forgerock.openam.oauth2provider.defaultScopes":["cn"],
   "com.forgerock.openam.oauth2provider.name":["My Test Client"],
   "com.forgerock.openam.oauth2provider.description":["OAuth 2.0 Client"]
  }' \
 https://openam.example.com:8443/openam/frrest/oauth2/client/?_action=create
{"success":"true"}
   

When creating an OAuth 2.0 client, use the following fields in your JSON object.

"client_id"

(Required) This field takes an array containing the client identifier as defined in RFC 6749.

"realm"

(Required) This field takes an array containing the OpenAM realm in which to create the client as defined in RFC 6749.

"userpassword"

(Required) This field takes an array containing the client secret as defined in RFC 6749.

"com.forgerock.openam.oauth2provider.clientType"

(Required) This field takes an array containing the client type, either "Confidential" or "Public" as defined in RFC 6749.

"com.forgerock.openam.oauth2provider.redirectionURIs"

(Optional for confidential clients) This field takes an array of client redirection endpoints as defined in RFC 6749.

"com.forgerock.openam.oauth2provider.scopes"

(Optional) This field takes an array of scopes as defined in RFC 6749. The default scopes implementation takes scopes to be names of attributes in the resource owner profile.

Specify localized scopes in scope|locale|localized description format.

"com.forgerock.openam.oauth2provider.defaultScopes"

(Optional) This field takes an array of default scopes set automatically when tokens are issued.

"com.forgerock.openam.oauth2provider.name"

(Optional) This field takes an array containing the client name to display to the resource owner when the resource owner must authorize client access to protected resources.

Specify localized names in locale|localized name format.

"com.forgerock.openam.oauth2provider.description"

(Optional) This field takes an array containing the description to display to the resource owner when the resource owner must authorize client access to protected resources.

Specify localized descriptions in locale|localized description format.

To delete an OAuth 2.0 client, perform an HTTP DELETE on /frrest/oauth2/client/client-id, as in the following example.

$ curl \
 --request DELETE \
 --header "iplanetDirectoryPro: AQIC5wM...3MTYxOA..*" \
 https://openam.example.com:8443/openam/frrest/oauth2/client/testClient
{"success":"true"}
   

3.8. OpenID Connect 1.0

OpenID Connect 1.0 extends OAuth 2.0 so the client can verify claims about the identity of the end user, get profile information about the end user, and log the user out at the end of the OpenAM session.

OpenAM exposes the following REST endpoints for OpenID Connect 1.0 purposes.

3.8.1. Discovering OpenID Connect 1.0 Configuration

OpenAM exposes endpoints for discovering information about the provider configuration, and about the provider for a given end user.

  • /.well-known/openid-configuration allows clients to retrieve OpenID Provider configuration by HTTP GET as specified by OpenID Connect Discovery 1.0.

  • /.well-known/webfinger allows clients to retrieve the provider URL for an end user by HTTP GET as specified by OpenID Connect Discovery 1.0.

For examples, see Configuring OpenAM For OpenID Connect Discovery.

3.8.2. Registering OpenID Connect 1.0 Clients

OpenAM allows both static and dynamic registration of OpenID Connect client applications. For dynamic registration according to the OpenID Connect Dynamic Client Registration 1.0 specification, the endpoint is /oauth2/connect/register. See To Register a Client Dynamically for details.

3.8.3. Performing OpenID Connect 1.0 Client Authorization

Registered clients can request authorization through OpenAM.

OpenID Connect 1.0 supports both a Basic Client Profile using the OAuth 2.0 authorization code grant, and an Implicit Client Profile using the OAuth 2.0 implicit grant. These client profiles rely on the OAuth 2.0 endpoints for authorization. Those endpoints are described in Section 3.7.1, “OAuth 2.0 Client & Resource Server Endpoints”.

In addition, authorized clients can access end user information through the OpenID Connect 1.0 specific endpoint /oauth2/userinfo.

For examples, see Client Examples.

3.8.4. Managing OpenID Connect 1.0 Sessions

Registered clients can use OpenID Connect Session Management 1.0 to handle end user logout actions.

  • /oauth2/connect/checkSession allows clients to retrieve session status notifications.

  • /oauth2/connect/endSession allows clients to terminate end user sessions.

For an example, see Managing User Sessions.

3.9. User Self-Registration

The OpenAM REST API for users provides an action for self-registration. This is an alternative to the Membership module described in the Administration Guide section, Hints For the Membership Authentication Module.

The feature works by sending an email to the user in response to RESTful HTTP POST requesting registration with an email address. When the user clicks the link received by mail, an application intercepts the HTTP GET, transforms the query string values into an HTTP POST to confirm the operation. OpenAM responds to the application with a JSON object that the application can further use to request creation of the user account to complete the transaction.

An example follows, showing the steps in more detail.

  1. Configure the Email Service and REST Security.

    In particular, you must configure the Email Service to send mail to users who self-register, and you must enable self-registration in the REST Security service.

    You can configure these globally in OpenAM Console at Configuration > Global > Email Service for notifications and Configuration > Global > REST Security to allow self-registration.

    Alternatively, you can configure them for an individual realm under Access Control > Realm Name > Services.

    At this point users can self-register. The starting screen for self-registration is at /XUI/#register/ under the base URL where OpenAM is installed. The default confirmation URI is /XUI/confirm.html.

    The steps that follow show how to use the REST API directly.

  2. Perform an HTTP POST on /json/users?_action=register with the new user's mail.

    To use a subject and message other than those configured in the Email Service, you can optionally set the mail subject and message content by including "subject" and "message" strings in the JSON data. For example, the following POST results in a mail with subject Confirm registration with OpenAM and content Follow this link to confirm your registration in addition to the confirmation link.

    Notice that authentication is not required.

    $ curl \
     --request POST \
     --header "Content-Type: application/json" \
     --data \
     '{
       "email": "newuser@example.com",
       "subject": "Confirm registration with OpenAM",
       "message": "Follow this link to confirm your registration"
     }' \
     https://openam.example.com:8443/openam/json/users/?_action=register
    {}
        

    On success, the response is an empty JSON object {} as shown in the example.

  3. The user receives an email message that includes a URL similar to the following example, but all on one line.

    https://openam.example.com:8443/openam/json/confirmation/register?
         confirmationId=P23PK5kyAgNdqeNJpAvq1ebcpcg=
         &email=newuser@example.com
         &tokenId=+8rWf5O8KG0rfz3Pa+WwDLkH9Ac=
  4. Intercept the HTTP GET request to this URL when the user clicks the link.

    Your application must use the confirmation link to construct an HTTP POST to /json/users?_action=confirm from the query string parameters as shown in the following example.

    $ curl \
     --request POST \
     --header "Content-Type: application/json" \
     --data \
     '{
       "email":"newuser@example.com",
       "tokenId":"+8rWf5O8KG0rfz3Pa+WwDLkH9Ac=",
       "confirmationId":"P23PK5kyAgNdqeNJpAvq1ebcpcg="
     }' \
     https://openam.example.com:8443/openam/json/users?_action=confirm
    {
        "email": "newuser@example.com",
        "tokenId": "+8rWf5O8KG0rfz3Pa+WwDLkH9Ac=",
        "confirmationId": "P23PK5kyAgNdqeNJpAvq1ebcpcg="
    }
        

    The response is a further confirmation that the account can be created.

  5. Using the confirmation, your application must make an authenticated HTTP POST to /json/users?_action=anonymousCreate to create the user as shown in the following example.

    $ curl \
     --request POST \
     --header "Content-Type: application/json" \
     --data \
     '{
       "email":"newuser@example.com",
       "tokenId":"+8rWf5O8KG0rfz3Pa+WwDLkH9Ac=",
       "confirmationId":"P23PK5kyAgNdqeNJpAvq1ebcpcg=",
       "username":"newuser",
       "userpassword":"password"
     }' \
     https://openam.example.com:8443/openam/json/users?_action=anonymousCreate
    {
        "username": "newuser",
        "realm": "/",
        "uid": [
            "newuser"
        ],
        "mail": [
            "newuser@example.com"
        ],
        "sn": [
            "newuser"
        ],
        "userPassword": [
            "{SSHA}dAiONYMxqFiNilXeLXUQoDpHlePYtiJcjYw8Dw=="
        ],
        "cn": [
            "newuser"
        ],
        "inetUserStatus": [
            "Active"
        ],
        "dn": [
            "uid=newuser,ou=people,dc=openam,dc=forgerock,dc=org"
        ],
        "objectClass": [
            "devicePrintProfilesContainer",
            "person",
            "sunIdentityServerLibertyPPService",
            "inetorgperson",
            "sunFederationManagerDataStore",
            "iPlanetPreferences",
            "iplanet-am-auth-configuration-service",
            "organizationalperson",
            "sunFMSAML2NameIdentifier",
            "inetuser",
            "forgerock-am-dashboard-service",
            "iplanet-am-managed-person",
            "iplanet-am-user-service",
            "sunAMAuthAccountLockout",
            "top"
        ],
        "universalid": [
            "id=newuser,ou=user,dc=openam,dc=forgerock,dc=org"
        ]
    }
        

At this point the user is registered, active, and can authenticate with OpenAM.

3.10. Resetting Forgotten Passwords

The OpenAM REST API for users provides an action for handling forgotten passwords as long as the user has a valid email address in their profile. This is an alternative to the password reset capability described in the Administration Guide chapter, Configuring Password Reset.

If you know the current password, you can change it as described in Section 3.12.6, “Changing Passwords”.

The option is disabled by default. You can enable it in the OpenAM Console globally via Configuration > Global > REST Security.

Alternatively, you can enable it for an individual realm under Access Control > Realm Name > Services > Add > REST Security.

An example follows, showing the steps in more detail.

  1. Configure the Email Service.

    In particular, you must configure the Email Service to send mail allowing the user to reset the forgotten password.

    You can configure the service globally in the OpenAM Console via Configuration > Global > Email Service.

    Alternatively, you can configure it for an individual realm under Access Control > Realm Name > Services.

    At this point users with mail addresses can reset their forgotten passwords. The starting screen for forgotten password reset is at /XUI/#forgotPassword/ under the base URL where OpenAM is installed. The default confirmation URI is /XUI/confirm.html.

    The steps that follow show how to use the REST API directly.

  2. Perform an HTTP POST on /json/users?_action=forgotPassword with the user's ID.

    To use a subject and message other than those configured in the Email Service, you can optionally set the mail subject and message content by including "subject" and "message" strings in the JSON data. For example, the following POST results in a mail with subject Reset your forgotten password with OpenAM and content Follow this link to reset your password in addition to the confirmation link.

    Notice that authentication is not required.

    $ curl \
     --request POST \
     --header "Content-Type: application/json" \
     --data '{
       "username": "demo",
       "subject": "Reset your forgotten password with OpenAM",
       "message": "Follow this link to reset your password"
     }' \
     https://openam.example.com:8443/openam/json/users/?_action=forgotPassword
    {}
        

    On success, the response is an empty JSON object {} as shown in the example.

  3. OpenAM looks up the email address in the user profile, and sends an email message that includes a URL as in the following example, but all on one line.

    https://openam.example.com:8443/openam/json/confirmation/forgotPassword
         ?confirmationId=jrUZ3E7CK4UQJM5jnDHGNKH1UaQ=
         &tokenId=M8cVqWqbKtCtpd/UqEAr0x25fxA=
         &username=demo
  4. Intercept the HTTP GET request to this URL when the user clicks the link.

    Your application must use the confirmation link to construct an HTTP POST to /json/users?_action=forgotPasswordReset from the query string parameters as shown in the following example.

    Your POST includes the new password as the value of the "userpassword" field in the JSON payload.

    $ curl \
     --request POST \
     --header "Content-Type: application/json" \
     --data '{
     "username":"demo",
     "userpassword":"password",
     "tokenId":"M8cVqWqbKtCtpd/UqEAr0x25fxA=",
     "confirmationId":"jrUZ3E7CK4UQJM5jnDHGNKH1UaQ="
     }' \
     https://openam.example.com:8443/openam/json/users?_action=forgotPasswordReset
    {
        "name": "demo",
        "realm": "/",
        "uid": [
            "demo"
        ],
        "mail": [
            "demo@example.com"
        ],
        "sn": [
            "demo"
        ],
        "userPassword": [
            "{SSHA}zgeBu4yOAy1i9QAgnldMCzW8LWX36ViVj9leig=="
        ],
        "cn": [
            "demo"
        ],
        "inetUserStatus": [
            "Active"
        ],
        "objectClass": [
            "devicePrintProfilesContainer",
            "person",
            "sunIdentityServerLibertyPPService",
            "inetorgperson",
            "sunFederationManagerDataStore",
            "iPlanetPreferences",
            "iplanet-am-auth-configuration-service",
            "organizationalperson",
            "sunFMSAML2NameIdentifier",
            "inetuser",
            "forgerock-am-dashboard-service",
            "iplanet-am-managed-person",
            "iplanet-am-user-service",
            "sunAMAuthAccountLockout",
            "top"
        ],
        "universalid": [
            "id=demo,ou=user,dc=openam,dc=forgerock,dc=org"
        ]
    }
        

    On success, the response is the JSON representation of the user profile with the new password hashed according to the password storage scheme for the identity repository.

At this point the user can authenticate with the new password.

3.11. Logging

You can send OpenAM messages to log, specifying the message content and the log file in which to write your message.

$ curl "https://openam.example.com:8443/openam/identity/log?\
appid=AQIC5wM2LY4SfcwyCZkk-1JXzx6q1EzgagabHfBjMidb5jI.*AAJTSQACMDE.*\
&subjectid=AQIC5wM2LY4SfcxuxIP0VnP2lVjs7ypEM6VDx6srk56CN1Q.*AAJTSQACMDE.*\
&logname=rest.access\
&message=Hello%20World"
  

Logging takes a valid appid token for the subject with access to log the message, and also a subjectid token for the user whom the message concerns. If the tokens are valid and the access rights correct, your message ends up in the log specified.

$ cat openam/openam/log/rest.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   rest.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" rest.access "Not Available"
   192.168.56.2
  

3.12. Identity Management

This section shows how to create, read, update, delete, and list identities using the RESTful APIs.

Important

OpenAM is not primarily an identity data store, nor is it provisioning software. For storing identity data, consider OpenDJ. For provisioning, consider OpenIDM. Both of these products provide REST APIs as well.

OpenAM has two REST APIs for managing identities.

3.12.1. Creating Identities

OpenAM lets administrators create a user profile by making an HTTP POST of the JSON representation of the profile to /json/subrealm/users/?_action=create. To add a user to the Top Level Realm, you do not need to specify the realm.

The following example shows an administrator creating a new user. The only required fields are username and userpassword. If no other name is provided, the entry you make for username defaults to both the user id and the user's last name.

$ curl \
 --request POST \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --data \
 '{
   "username": "bjensen",
   "userpassword": "secret12",
   "mail": "bjensen@example.com"
 }' \
 https://openam.example.com:8443/openam/json/users/?_action=create
{
    "username": "bjensen",
    "realm": "/",
    "uid": [
        "bjensen"
    ],
    "mail": [
        "bjensen@example.com"
    ],
    "sn": [
        "bjensen"
    ],
    "userpassword": [
        "{SSHA}0pXpKLPRKCGY7g3YqZygJmKMW6IC2BLJimmlwg=="
    ],
    "cn": [
        "bjensen"
    ],
    "inetuserstatus": [
        "Active"
    ],
    "dn": [
        "uid=bjensen,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "objectclass": [
        "person",
        "sunIdentityServerLibertyPPService",
        "sunFederationManagerDataStore",
        "inetorgperson",
        "iPlanetPreferences",
        "iplanet-am-auth-configuration-service",
        "organizationalperson",
        "sunFMSAML2NameIdentifier",
        "inetuser",
        "iplanet-am-managed-person",
        "sunAMAuthAccountLockout",
        "iplanet-am-user-service",
        "top"
    ],
    "universalid": [
        "id=bjensen,ou=user,dc=openam,dc=forgerock,dc=org"
    ]
}
   

Alternatively, administrators can create user profiles with specific user IDs by doing an HTTP PUT of the JSON representation of the changes to /json/users/user-id, as shown in the following example.

$ curl \
 --request PUT \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --header "If-None-Match: *" \
 --data \
 '{
   "username": "janedoe",
   "userpassword": "secret12",
   "mail": "janedoe@example.com"
 }' \
 https://openam.example.com:8443/openam/json/users/janedoe
{
    "username": "janedoe",
    "realm": "/",
    "uid": [
        "janedoe"
    ],
    "mail": [
        "janedoe@example.com"
    ],
    "sn": [
        "janedoe"
    ],
    "userpassword": [
        "{SSHA}e4DJoxvYVW/nsp62XJf29ZADE16YQgrxK+XuKA=="
    ],
    "cn": [
        "janedoe"
    ],
    "inetuserstatus": [
        "Active"
    ],
    "dn": [
        "uid=janedoe,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "objectclass": [
        "devicePrintProfilesContainer",
        "person",
        "sunIdentityServerLibertyPPService",
        "inetorgperson",
        "sunFederationManagerDataStore",
        "iPlanetPreferences",
        "iplanet-am-auth-configuration-service",
        "organizationalperson",
        "sunFMSAML2NameIdentifier",
        "inetuser",
        "forgerock-am-dashboard-service",
        "iplanet-am-managed-person",
        "iplanet-am-user-service",
        "sunAMAuthAccountLockout",
        "top"
    ],
    "universalid": [
        "id=janedoe,ou=user,dc=openam,dc=forgerock,dc=org"
    ]
}
    

As shown in the examples, OpenAM returns the JSON representation of the profile on successful creation. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

The same HTTP POST and PUT mechanisms also work for other objects such as policy agent profiles and groups.

$ curl \
 --request POST \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --data \
 '{
   "name":"myWebAgent","realm":"/",
   "com.sun.identity.agents.config.fqdn.default":["www.example.com"],
   "sunidentityserverdevicekeyvalue":
     ["agentRootURL=http://www.example.com:80/"],
   "com.sun.identity.agents.config.remote.logfile":
     ["amAgent_www_example_com_80.log"],
   "com.sun.identity.agents.config.repository.location":["centralized"],
   "agenttype":["WebAgent"],
    "com.sun.identity.agents.config.cdsso.cdcservlet.url":
     ["[0]=https://openam.example.com:8443/openam/cdcservlet"],
   "com.sun.identity.client.notification.url":
     ["http://www.example.com:80/UpdateAgentCacheServlet?shortcircuit=false"],
   "com.sun.identity.agents.config.agenturi.prefix":
     ["http://www.example.com:80/amagent"],
   "userpassword":["password"],
   "com.sun.identity.agents.config.login.url":
     ["[0]=https://openam.example.com:8443/openam/UI/Login"],
   "com.sun.identity.agents.config.logout.url":
     ["[0]=https://openam.example.com:8443/openam/UI/Logout"],
   "sunidentityserverdevicestatus":["Active"]
 }' \
 https://openam.example.com:8443/openam/json/agents/?_action=create
{
    "name": "myWebAgent",
    "realm": "/",
    "com.sun.identity.agents.config.cdsso.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.cdsso.cookie.domain": [
        "[0]="
    ],
    "com.sun.identity.agents.config.get.client.host.name": [
        "false"
    ],
    "com.sun.identity.agents.config.profile.attribute.fetch.mode": [
        "NONE"
    ],
    "com.sun.identity.agents.config.notenforced.ip": [
        "[0]="
    ],
    "com.sun.identity.agents.config.fqdn.check.enable": [
        "true"
    ],
    "com.sun.identity.agents.config.cleanup.interval": [
        "30"
    ],
    "com.sun.identity.agents.config.notenforced.url.attributes.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.ignore.preferred.naming.url": [
        "true"
    ],
    "com.sun.identity.agents.config.client.ip.header": [],
    "com.sun.identity.agents.config.session.attribute.mapping": [
        "[]="
    ],
    "com.sun.identity.agents.config.audit.accesstype": [
        "LOG_NONE"
    ],
    "com.sun.identity.agents.config.proxy.override.host.port": [
        "false"
    ],
    "com.sun.identity.agents.config.load.balancer.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.encode.url.special.chars.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.convert.mbyte.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.domino.check.name.database": [
        "false"
    ],
    "com.sun.identity.agents.config.iis.owa.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.override.port": [
        "false"
    ],
    "com.sun.identity.agents.config.policy.clock.skew": [
        "0"
    ],
    "com.sun.identity.agents.config.sso.only": [
        "false"
    ],
    "com.sun.identity.agents.config.iis.owa.enable.session.timeout.url": [],
    "com.sun.identity.agents.config.domino.ltpa.config.name": [
        "LtpaToken"
    ],
    "com.sun.identity.agents.config.cookie.reset": [
        "[0]="
    ],
    "com.sun.identity.agents.config.fqdn.default": [
        "www.example.com"
    ],
    "sunIdentityServerDeviceKeyValue": [
        "agentRootURL=http://www.example.com:80/"
    ],
    "com.sun.identity.agents.config.domino.ltpa.cookie.name": [
        "LtpaToken"
    ],
    "com.sun.identity.agents.config.iis.password.header": [
        "false"
    ],
    "com.sun.identity.agents.config.response.attribute.mapping": [
        "[]="
    ],
    "com.sun.identity.agents.config.userid.param.type": [
        "session"
    ],
    "com.sun.identity.agents.config.url.comparison.case.ignore": [
        "true"
    ],
    "com.sun.identity.agents.config.profile.attribute.cookie.maxage": [
        "300"
    ],
    "com.sun.identity.agents.config.remote.logfile": [
        "amAgent_www_example_com_80.log"
    ],
    "com.sun.identity.agents.config.domino.ltpa.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.notenforced.url": [
        "[0]="
    ],
    "com.sun.identity.agents.config.notification.enable": [
        "true"
    ],
    "com.sun.identity.agents.config.profile.attribute.cookie.prefix": [
        "HTTP_"
    ],
    "com.sun.identity.agents.config.logout.cookie.reset": [
        "[0]="
    ],
    "com.sun.identity.agents.config.polling.interval": [
        "60"
    ],
    "com.sun.identity.agents.config.attribute.multi.value.separator": [
        "|"
    ],
    "com.sun.identity.agents.config.debug.file.rotate": [
        "true"
    ],
    "com.sun.identity.agents.config.debug.level": [
        "Error"
    ],
    "com.sun.identity.agents.config.local.log.rotate": [
        "false"
    ],
    "com.sun.identity.agents.config.repository.location": [
        "centralized"
    ],
    "com.sun.identity.agents.config.client.ip.validation.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.override.protocol": [
        "false"
    ],
    "AgentType": [
        "WebAgent"
    ],
    "com.sun.identity.agents.config.logout.redirect.url": [],
    "com.sun.identity.agents.config.ignore.path.info": [
        "false"
    ],
    "com.sun.identity.agents.config.override.notification.url": [
        "false"
    ],
    "com.sun.identity.agents.config.session.attribute.fetch.mode": [
        "NONE"
    ],
    "com.sun.identity.agents.config.policy.cache.polling.interval": [
        "3"
    ],
    "com.sun.identity.agents.config.cdsso.cdcservlet.url": [
        "[0]=https://openam.example.com:8443/openam/cdcservlet"
    ],
    "com.sun.identity.agents.config.cookie.name": [
        "iPlanetDirectoryPro"
    ],
    "com.sun.identity.agents.config.profile.attribute.mapping": [
        "[]="
    ],
    "com.sun.identity.agents.config.iis.filter.priority": [
        "HIGH"
    ],
    "com.sun.identity.agents.config.iis.auth.type": [],
    "com.sun.identity.client.notification.url": [
        "http://www.example.com:80/UpdateAgentCacheServlet?shortcircuit=false"
    ],
    "com.sun.identity.agents.config.cookie.secure": [
        "false"
    ],
    "com.sun.identity.agents.config.ignore.path.info.for.not.enforced.list": [
        "true"
    ],
    "com.sun.identity.agents.config.remote.log.interval": [
        "5"
    ],
    "com.sun.identity.agents.config.notenforced.url.invert": [
        "false"
    ],
    "universalid": [
        "id=myWebAgent,ou=agent,dc=openam,dc=forgerock,dc=org"
    ],
    "com.sun.identity.agents.config.replaypasswd.key": [],
    "com.sun.identity.agents.config.iis.owa.enable.change.protocol": [
        "false"
    ],
    "com.sun.identity.agents.config.userid.param": [
        "UserToken"
    ],
    "userpassword": [
        "{SHA-1}W6ph5Mm5Pz8GgiULbPgzG37mj9g="
    ],
    "com.sun.identity.agents.config.response.attribute.fetch.mode": [
        "NONE"
    ],
    "com.sun.identity.agents.config.freeformproperties": [
        "sunidentityserverdevicestatus=Active",
        "sunidentityserverdevicekeyvalue=agentRootURL=http://www.example.com:80/",
        "realm=/",
        "name=myWebAgent"
    ],
    "com.sun.identity.agents.config.postdata.preserve.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.log.disposition": [
        "REMOTE"
    ],
    "com.sun.identity.agents.config.agenturi.prefix": [
        "http://www.example.com:80/amagent"
    ],
    "com.sun.identity.agents.config.override.host": [
        "false"
    ],
    "com.sun.identity.agents.config.cookie.reset.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.local.log.size": [
        "52428800"
    ],
    "com.sun.identity.agents.config.access.denied.url": [],
    "com.sun.identity.agents.config.debug.file.size": [
        "10000000"
    ],
    "com.sun.identity.agents.config.change.notification.enable": [
        "true"
    ],
    "com.sun.identity.agents.config.anonymous.user.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.domino.ltpa.org.name": [],
    "com.sun.identity.agents.config.agent.logout.url": [
        "[0]="
    ],
    "com.sun.identity.agents.config.poll.primary.server": [
        "5"
    ],
    "com.sun.identity.agents.config.fqdn.mapping": [
        "[]="
    ],
    "com.sun.identity.agents.config.auth.connection.timeout": [
        "2"
    ],
    "com.sun.identity.agents.config.client.hostname.header": [],
    "com.sun.identity.agents.config.iis.logonuser": [
        "false"
    ],
    "com.sun.identity.agents.config.ignore.server.check": [
        "false"
    ],
    "com.sun.identity.agents.config.fetch.from.root.resource": [
        "false"
    ],
    "com.sun.identity.agents.config.login.url": [
        "[0]=https://openam.example.com:8443/openam/UI/Login"
    ],
    "com.sun.identity.agents.config.redirect.param": [
        "goto"
    ],
    "com.sun.identity.agents.config.logout.url": [
        "[0]=https://openam.example.com:8443/openam/UI/Logout"
    ],
    "sunIdentityServerDeviceStatus": [
        "Active"
    ],
    "com.sun.identity.agents.config.sso.cache.polling.interval": [
        "3"
    ],
    "com.sun.identity.agents.config.anonymous.user.id": [
        "anonymous"
    ],
    "com.sun.identity.agents.config.encode.cookie.special.chars.enable": [
        "false"
    ],
    "com.sun.identity.agents.config.locale": [
        "en_US"
    ],
    "com.sun.identity.agents.config.postcache.entry.lifetime": [
        "10"
    ]
}
   
$ curl \
 --request POST \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --data '{
   "name":"newGroup",
   "realm":"/",
   "uniquemember":["uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"]
 }' \
 https://openam.example.com:8443/openam/json/groups?_action=create
{
    "name": "newGroup",
    "realm": "/",
    "uniqueMember": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "cn": [
        "newGroup"
    ],
    "objectclass": [
        "groupofuniquenames",
        "top"
    ],
    "universalid": [
        "id=newGroup,ou=group,dc=openam,dc=forgerock,dc=org"
    ]
}

$ curl \
 --request PUT \
 --header "If-None-Match: *" \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --data '{
   "name":"anotherGroup",
   "realm":"/",
   "uniquemember":["uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"]
 }' \
 https://openam.example.com:8443/openam/json/groups/anotherGroup
{
    "name": "anotherGroup",
    "realm": "/",
    "uniqueMember": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "cn": [
        "anotherGroup"
    ],
    "objectclass": [
        "groupofuniquenames",
        "top"
    ],
    "universalid": [
        "id=anotherGroup,ou=group,dc=openam,dc=forgerock,dc=org"
    ]
}
   

3.12.2. Reading Identities

OpenAM lets users and administrators read profiles by requesting an HTTP GET on /json/subrealm/users/user-id. This allows users and administrators to verify user data, status, and directory. If users or administrators see missing or incorrect information, they can write down the correct information and add it using Section 3.12.3, “Updating Identities”. To read a profile on the Top Level Realm, you do not need to specify the realm.

Users can review the data associated with their accounts and administrators can read other user's profiles. The following example shows an administrator accessing user data. Users can view their information by changing username=amadmin to user-id.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/users/demo
{
    "username": "demo",
    "realm": "dc=openam,dc=forgerock,dc=org",
    "uid": [
        "demo"
    ],
    "userpassword": [
        "{SSHA}BKPAKRS3QKkvQRw25MfXbVC4VEuVNUf+yCaejg=="
    ],
    "sn": [
        "demo"
    ],
    "cn": [
        "demo"
    ],
    "inetuserstatus": [
        "Active"
    ],
    "dn": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "objectclass": [
        "devicePrintProfilesContainer",
        "person",
        "sunIdentityServerLibertyPPService",
        "inetorgperson",
        "sunFederationManagerDataStore",
        "iPlanetPreferences",
        "iplanet-am-auth-configuration-service",
        "organizationalperson",
        "sunFMSAML2NameIdentifier",
        "inetuser",
        "forgerock-am-dashboard-service",
        "iplanet-am-managed-person",
        "iplanet-am-user-service",
        "sunAMAuthAccountLockout",
        "top"
    ],
    "universalid": [
        "id=demo,ou=user,dc=openam,dc=forgerock,dc=org"
    ]
}
    

Use the _fields query string parameter to restrict the list of attributes returned. This parameter takes a comma-separated list of JSON object fields to include in the result.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/users/demo?_fields=username,uid
{"username":"demo","uid":["demo"]}
   

As shown in the examples, OpenAM returns the JSON representation of the profile on success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

Using HTTP GET to read also works for other objects such as agent profiles and groups.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/agents/myClientID
{
    "username": "myClientID",
    "realm": "dc=openam,dc=forgerock,dc=org",
    "com.forgerock.openam.oauth2provider.accesstoken": [],
    "com.forgerock.openam.oauth2provider.clientsessionuri": [],
    "com.forgerock.openam.oauth2provider.defaultscopes": [
        "[0]="
    ],
    "com.forgerock.openam.oauth2provider.clientname": [],
    "com.forgerock.openam.oauth2provider.clienttype": [
        "Confidential"
    ],
    "universalid": [
        "id=myClientID,ou=agent,dc=openam,dc=forgerock,dc=org"
    ],
    "com.forgerock.openam.oauth2provider.responsetypes": [
        "[6]=code token id_token",
        "[0]=code",
        "[2]=id_token",
        "[4]=token id_token",
        "[3]=code token",
        "[1]=token",
        "[5]=code id_token"
    ],
    "userpassword": [
        "{SHA-1}W6ph5Mm5Pz8GgiULbPgzG37mj9g="
    ],
    "com.forgerock.openam.oauth2provider.name": [
        "[0]="
    ],
    "com.forgerock.openam.oauth2provider.redirectionuris": [
        "[0]="
    ],
    "com.forgerock.openam.oauth2provider.idtokensignedresponsealg": [
        "HS256"
    ],
    "com.forgerock.openam.oauth2provider.scopes": [
        "[0]="
    ],
    "com.forgerock.openam.oauth2provider.postlogoutredirecturi": [],
    "sunidentityserverdevicestatus": [
        "Active"
    ],
    "agenttype": [
        "OAuth2Client"
    ],
    "com.forgerock.openam.oauth2provider.description": [
        "[0]="
    ]
}
   

The _prettyPrint query string parameter can make the resulting JSON easier to read when you are viewing the resulting JSON directly.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/groups/myGroup?_prettyPrint=true
{
    "username": "myGroup",
    "realm": "dc=openam,dc=forgerock,dc=org",
    "uniquemember": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "cn": [
        "myGroup"
    ],
    "dn": [
        "cn=myGroup,ou=groups,dc=openam,dc=forgerock,dc=org"
    ],
    "objectclass": [
        "groupofuniquenames",
        "top"
    ],
    "universalid": [
        "id=myGroup,ou=group,dc=openam,dc=forgerock,dc=org"
    ]
}
   

3.12.3. Updating Identities

OpenAM lets users update their own profiles, and lets administrators update other users' profiles. To update an identity do an HTTP PUT of the JSON representation of the changes to /json/subrealm/users/user-id. To update a profile on the Top Level Realm, you do not need to specify the realm.

The following example shows how users can update their own profiles.

$ curl \
 --request PUT \
 --header "iplanetDirectoryPro: AQIC5...Y3MTAx*" \
 --header "Content-Type: application/json" \
 --data '{ "mail": "demo@example.com" }' \
 https://openam.example.com:8443/openam/json/users/demo
{
    "username": "demo",
    "realm": "/",
    "uid": [
        "demo"
    ],
    "mail": [
        "demo@example.com"
    ],
    "sn": [
        "demo"
    ],
    "userpassword": [
        "{SSHA}S14oR2gusLWtiDkAS4twj63slXNNaMKpwrOWdw=="
    ],
    "cn": [
        "demo"
    ],
    "inetuserstatus": [
        "Active"
    ],
    "dn": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "objectclass": [
        "person",
        "sunIdentityServerLibertyPPService",
        "sunFederationManagerDataStore",
        "inetorgperson",
        "iPlanetPreferences",
        "iplanet-am-auth-configuration-service",
        "organizationalperson",
        "sunFMSAML2NameIdentifier",
        "inetuser",
        "iplanet-am-managed-person",
        "sunAMAuthAccountLockout",
        "iplanet-am-user-service",
        "top"
    ],
    "universalid": [
        "id=demo,ou=user,dc=openam,dc=forgerock,dc=org"
    ]
}
    

As shown in the example, OpenAM returns the JSON representation of the profile on success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

You can use HTTP PUT to update other objects as well, such as policy agent profiles and groups.

The following example creates a web policy agent profile.

$ curl \
 --request PUT \
 --header "iPlanetDirectoryPro: AQIC5...Y3MTAx*" \
 --header "Content-Type: application/json" \
 --header "If-None-Match: *" \
 --data '{
  "username" : "myWebAgent",
  "realm" : "/",
  "com.sun.identity.agents.config.fqdn.default" : [ "www.example.com" ],
  "sunIdentityServerDeviceKeyValue" :
   [ "agentRootURL=http://www.example.com:80/" ],
  "com.sun.identity.agents.config.remote.logfile" :
   [ "amAgent_www_example_com_80.log" ],
  "com.sun.identity.agents.config.repository.location" : [ "centralized" ],
  "AgentType" : [ "WebAgent" ],
  "com.sun.identity.agents.config.cdsso.cdcservlet.url" :
   [ "[0]=https://openam.example.com:8443/openam/cdcservlet" ],
  "com.sun.identity.client.notification.url" :
   [ "http://www.example.com:80/UpdateAgentCacheServlet?shortcircuit=false" ],
  "universalid" : [ "id=myWebAgent,ou=agent,dc=openam,dc=forgerock,dc=org" ],
  "userpassword" : [ "changeit" ],
  "com.sun.identity.agents.config.agenturi.prefix" :
   [ "http://www.example.com:80/amagent" ],
  "com.sun.identity.agents.config.login.url" :
   [ "[0]=https://openam.example.com:8443/openam/UI/Login" ],
  "com.sun.identity.agents.config.logout.url" :
   [ "[0]=https://openam.example.com:8443/openam/UI/Logout" ],
  "sunIdentityServerDeviceStatus" : [ "Active" ]
 }' \
 https://openam.example.com:8443/openam/json/agents/myWebAgent?_prettyPrint=true
   

When you create a policy agent profile, OpenAM returns the full profile in JSON format.

Notice in the following example that updates myGroup the object class value is not included in the JSON sent to OpenAM.

$ curl \
 --request PUT \
 --header "iPlanetDirectoryPro: AQIC5...Y3MTAx*" \
 --header "Content-Type: application/json" \
 --data '{
   "name":"myGroup",
   "realm":"/",
   "uniquemember":["uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"],
   "cn":["myGroup"],
   "description":["Updated the group"]
 }' \
 https://openam.example.com:8443/openam/json/groups/myGroup
{
    "name": "myGroup",
    "realm": "/",
    "uniqueMember": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "cn": [
        "myGroup"
    ],
    "dn": [
        "cn=myGroup,ou=groups,dc=openam,dc=forgerock,dc=org"
    ],
    "objectclass": [
        "groupofuniquenames",
        "top"
    ],
    "universalid": [
        "id=myGroup,ou=group,dc=openam,dc=forgerock,dc=org"
    ]
}
   

3.12.4. Deleting Identities

OpenAM lets administrators delete a user profile by making an HTTP DELETE call to /json/subrealm/users/user-id. To delete a user from the Top Level Realm, you do not need to specify the realm.

The following example removes a user from the top level realm. Only administrators should delete users. The user id is the only field required to delete a user.

$ curl \
 --request DELETE \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/users/bjensen
{"success":"true"}
   

On success, OpenAM returns a JSON object indicating success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

You can use this same logic for other resources such as performing an HTTP DELETE of an agent profile or of a group.

$ curl \
 --request DELETE \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/agents/myOAuth2ClientAgent
{"success":"true"}
   
$ curl \
 --request DELETE \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/groups/myGroup
{"success":"true"}
   

Note

Deleting a user does not automatically remove any of the user's sessions. After deleting a user, check for any sessions for the user and remove them under the Console's Sessions tab.

3.12.5. Listing Identities

OpenAM lets administrators list identities by making an HTTP GET call to /json/subrealm/users/?_queryId=*. To query the Top Level Realm, you do not need to specify the realm.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 "https://openam.example.com:8443/openam/json/users?_queryID=*"
{
  "result" : [ "amAdmin", "demo", "anonymous" ],
  "resultCount" : 3,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
   

This also works for other types of objects, such as agent profiles and groups.

$ curl \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 "https://openam.example.com:8443/openam/json/agents?_queryID=*"
{
  "result" : [ "wsp", "wsc", "agentAuth", "SecurityTokenService" ],
  "resultCount" : 4,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
   
$ curl \
 --header "iPlanetDirectoryPro: AQIC5w...2NzEz*" \
 "https://openam.example.com:8443/openam/json/groups?_queryID=*"
{
  "result" : [ "myOtherGroup", "myGroup" ],
  "resultCount" : 2,
  "pagedResultsCookie" : null,
  "remainingPagedResults" : -1
}
   

As the result lists include all objects, this capability to list identity names is mainly useful in testing.

As shown in the examples, OpenAM returns the JSON representation of the resource list if successful. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

3.12.6. Changing Passwords

OpenAM administrator, by default amadmin, can reset a user's password or a user can change their own password with an HTTP PUT to /json/subrealm/users/username including the new password as the value of "userpassword" in the request data. OpenAM administrator can reset the password without the old password. A user must provide the current password, which is set in the request as the value of the olduserpassword header. For the case where the user has forgotten their password, see Section 3.10, “Resetting Forgotten Passwords” instead.

The following example shows a successful request to change the demo user's password to password.

$ curl \
 --request PUT \
 --header "iPlanetDirectoryPro: AQIC5w...NTcy*" \
 --header "Content-Type: application/json" \
 --header "olduserpassword: changeit" \
 --data '{"userpassword":"newpassword"}' \
 https://openam.example.com:8443/openam/json/users/demo
{
    "username": "demo",
    "realm": "/",
    "uid": [
        "demo"
    ],
    "mail": [
        "demo@example.com"
    ],
    "sn": [
        "demo"
    ],
    "userPassword": [
        "{SSHA}OrBR9VdMLs95iMq/VKYLwJkr4fTOfGS91+9grg=="
    ],
    "cn": [
        "demo"
    ],
    "inetUserStatus": [
        "Active"
    ],
    "dn": [
        "uid=demo,ou=people,dc=openam,dc=forgerock,dc=org"
    ],
    "objectClass": [
        "devicePrintProfilesContainer",
        "person",
        "sunIdentityServerLibertyPPService",
        "inetorgperson",
        "sunFederationManagerDataStore",
        "iPlanetPreferences",
        "iplanet-am-auth-configuration-service",
        "organizationalperson",
        "sunFMSAML2NameIdentifier",
        "inetuser",
        "forgerock-am-dashboard-service",
        "iplanet-am-managed-person",
        "iplanet-am-user-service",
        "sunAMAuthAccountLockout",
        "top"
    ],
    "universalid": [
        "id=demo,ou=user,dc=openam,dc=forgerock,dc=org"
    ]
}
   

As shown in the examples, OpenAM returns the JSON representation of the resource list if successful. On failure, OpenAM returns a JSON representation of the error including the HTTP status code. See also Section 3.15, “REST Status Codes” for more information.

3.12.7. Creating Identities (Legacy API)

Interface Stability: Deprecated

OpenAM lets you create user profiles, and also create web and J2EE policy agent profiles. When you create an entry, you must provide the following parameters.

admin

Valid token for the user with permissions to add the identity

identity_name

A unique name for the identity to create

identity_attribute_names

LDAP attribute names for attributes to create

identity_attribute_values_name

LDAP attribute values for the identity to create. For example, identity_attribute_names=sn&identity_attribute_values_sn=Jensen.

identity_realm

The realm in which to create the identity

identity_type

Either user or AgentOnly

$ curl "https://openam.example.com:8443/openam/identity/create?\
admin=AQIC5wM2LY4SfcxSYA8eG-vrNHb_W7nG8XkfAGyRyuaebDY.*AAJTSQACMDE.*\
&identity_name=testuser\
&identity_attribute_names=cn\
&identity_attribute_values_cn=Test%20User\
&identity_attribute_names=sn\
&identity_attribute_values_sn=User\
&identity_attribute_names=userpassword\
&identity_attribute_values_userpassword=secret12\
&identity_realm=%2F\
&identity_type=user"
    

3.12.8. Reading & Searching for Identities (Legacy API)

Interface Stability: Deprecated

Reading is similar to attribute retrieval, as described in Section 3.5, “Token Validation”, but obtained using the token of a user with permissions to perform the search, as shown in the following example.

$ curl "https://openam.example.com:8443/openam/identity/read?\
admin=AQIC5wM2LY4SfcxSYA8eG-vrNHb_W7nG8XkfAGyRyuaebDY.*AAJTSQACMDE.*\
&name=testuser\
&attributes_names=realm\
&attributes_values_realm=%2F"
identitydetails.name=testuser
identitydetails.type=user
identitydetails.realm=o=openam
identitydetails.attribute=
identitydetails.attribute.name=uid
identitydetails.attribute.value=testuser
identitydetails.attribute=
identitydetails.attribute.name=sn
identitydetails.attribute.value=User
identitydetails.attribute=
identitydetails.attribute.name=userpassword
identitydetails.attribute.value={SSHA}AzpT+N1sjrQhL1wfX2ETWh/Aqbd+lH9LOlhDqg==
identitydetails.attribute=
identitydetails.attribute.name=cn
identitydetails.attribute.value=Test User
identitydetails.attribute=
identitydetails.attribute.name=inetuserstatus
identitydetails.attribute.value=Active
identitydetails.attribute=
identitydetails.attribute.name=dn
identitydetails.attribute.value=uid=testuser,ou=people,dc=example,dc=com
identitydetails.attribute=
identitydetails.attribute.name=objectclass
identitydetails.attribute.value=person
identitydetails.attribute.value=sunIdentityServerLibertyPPService
identitydetails.attribute.value=inetorgperson
identitydetails.attribute.value=sunFederationManagerDataStore
identitydetails.attribute.value=iPlanetPreferences
identitydetails.attribute.value=iplanet-am-auth-configuration-service
identitydetails.attribute.value=organizationalperson
identitydetails.attribute.value=sunFMSAML2NameIdentifier
identitydetails.attribute.value=inetuser
identitydetails.attribute.value=iplanet-am-managed-person
identitydetails.attribute.value=iplanet-am-user-service
identitydetails.attribute.value=sunAMAuthAccountLockout
identitydetails.attribute.value=top
identitydetails.attribute=
identitydetails.attribute.name=universalid
identitydetails.attribute.value=id=testuser,ou=user,o=openam
   

You can search for user IDs by providing the following parameters.

admin

Valid token for the user with access to perform the search

attributes_names

LDAP attribute names for attributes to search

attributes_values_name

LDAP attribute values for the identity to search. For example, attribute_names=sn&attribute_values_sn=Jensen.

filter

Additional LDAP filter component to limit the search results returned

$ curl "https://openam.example.com:8443/openam/identity/search?\
admin=AQIC5wM2LY4SfcxSYA8eG-vrNHb_W7nG8XkfAGyRyuaebDY.*AAJTSQACMDE.*\
&attributes_names=sn\
&attributes_values_sn=Jensen\
&attributes_names=mail\
&attributes_values_mail=bjensen*\
&attributes_names=realm\
&attributes_values_realm=%2F"
string=bjensen
   

3.12.9. Updating Identities (Legacy API)

Interface Stability: Deprecated

You can update an identity with the same parameters used to create identities, provided the token corresponds to a user with access to update the identity.

$ curl "https://openam.example.com:8443/openam/identity/update?\
admin=AQIC5wM2LY4SfcxSYA8eG-vrNHb_W7nG8XkfAGyRyuaebDY.*AAJTSQACMDE.*\
&identity_name=testuser\
&identity_attribute_names=mail\
&identity_attribute_values_mail=testuser%40example.com\
&identity_realm=%2F\
&identity_type=user"
   

3.12.10. Deleting Identities (Legacy API)

Interface Stability: Deprecated

You can also delete an identity.

$ curl "https://openam.example.com:8443/openam/identity/delete?\
admin=AQIC5wM2LY4SfcxSYA8eG-vrNHb_W7nG8XkfAGyRyuaebDY.*AAJTSQACMDE.*\
&identity_name=testuser\
&identity_realm=%2F\
&identity_type=user"
   

3.13. Realm Management

This section shows how to create, read, update, and delete realms using the RESTful APIs.

3.13.1. Default Parameters for Realms

Realms have a number of fields entered with the default loading. The following table provides information on what the default realm settings are, and these settings can be updated, added, or deleted when updating a realm.

Table 3.1. Realm Parameters for JSON-based API
Realm ParameterDefaultPurpose
realmNone - the only required field to add a realm

The name of the realm

Example: testRealm

sunOrganizationStatusNone

The status of the realm

Active or Inactive

sunOrganizationAliasesNone

Any applicable aliases associated with the realm. Be aware that an alias can only be used once. Entering an alias used by another realm will remove the alias from that realm and you will lose configuration.

Example: opensso.example.com

serviceNamessunAMAuthHOTPService iPlanetAMAuthConfiguration sunAMAuthFederationService sunIdentityRepositoryService iPlanetAMPolicyConfigService iPlanetAMAuthService iPlanetAMAuthLDAPService sunAMAuthDataStoreService sunAMAuthSAEService sunAMDelegationService sunAMAuthWSSAuthModuleService iPlanetAMAuthOATHService Services needed for the realm, including authentication modules

3.13.2. Creating Realms

OpenAM lets administrators create a realm by making an HTTP POST of the JSON representation of the profile to /json/realms/?_action=create.

You can create realms using an HTTP POST of the JSON representation of the profile to /json/realms/?_action=create, as shown in the following example. The only required field is realm, but the realm will not be active if the status is not set.

$ curl \
 --request POST \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --data '{ "realm": "testRealm" }' \
 https://openam.example.com:8443/openam/json/realms/?_action=create
{"realmCreated":"/testRealm"}
     

You can also set the sunOrganizationAliases parameter, but it can only be assigned to one realm (usually the top level realm). Before setting this parameter, make sure it is not already assigned elsewhere. If you replace remove it from another realm, you will lose your configuration.

Alternatively, administrators can create realms by the specific realm name using the HTTP PUT of the JSON representation of the changes to /json/realms/realm-id, as shown in the following example.

$ curl \
 --request PUT \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 --header "Content-Type: application/json" \
 --data '{ "sunOrganizationStatus": "Active" }' \
 https://openam.example.com:8443/openam/json/realms/testRealm
     

OpenAM returns the JSON representation of the profile on success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

3.13.3. Reading Realms

OpenAM lets administrators read realms by requesting an HTTP GET on /json/realms/realm-id. This allows administrators to review all active realm services for the realm, like policy configuration and modules. If users or administrators see missing information (such as Active status) or incorrect information, they can write down the correct information and add it using Section 3.13.4, “Updating Realms”

The following example shows an administrator receiving information about the testRealm.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/realms/testRealm
{
    "serviceNames":[
                  "sunAMAuthHOTPService",
                  "iPlanetAMAuthConfiguration",
                  "sunAMAuthFederationService",
                  "sunIdentityRepositoryService",
                  "iPlanetAMPolicyConfigService",
                  "iPlanetAMAuthService",
                  "iPlanetAMAuthLDAPService",
                  "sunAMAuthDataStoreService",
                  "sunAMAuthSAEService",
                  "sunAMDelegationService",
                  "sunAMAuthWSSAuthModuleService",
                  "iPlanetAMAuthOATHService"
    ]
}
    

As shown in the example, OpenAM returns the JSON representation of the profile on success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

3.13.4. Updating Realms

OpenAM lets administrators update realms. To update a realm, do an HTTP PUT of the JSON representation of the changes to /json/realms/realm-id.

The following example shows how to update a realm.

$ curl \
 --request PUT \
 --header "iplanetDirectoryPro: AQIC5...Y3MTAx*" \
 --header "Content-Type: application/json" \
 --data '{ "sunOrganizationStatus": "Active" }' \
 https://openam.example.com:8443/openam/json/realms/testRealm
     

OpenAM returns the JSON representation of the profile on success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

3.13.5. Deleting Realms

OpenAM lets administrators delete a realm by making an HTTP DELETE call to /json/realms/realm-id.

The following example deletes a realm. The top level realm cannot be deleted. Only administrators should delete realms. The name of the realm is the only field required to delete the realm.

Make sure that you do not have any information you need within a realm before deleting it. Once a realm is deleted, the only way to restore it is to return to a backed up deployment of OpenAM.

$ curl \
 --request DELETE \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/realms/testRealm
{"success":"true"}
    

On success, OpenAM returns a JSON object indicating success. On failure, OpenAM returns a JSON representation of the error including the HTTP status code.

3.14. Displaying Dashboard Applications

OpenAm lets administrators configure online applications to display applications on user Dashboards. You can used exposed REST API to display information about the online applications.

/dashboard/assigned

This endpoint retrieves the list of applications assigned to the authenticated user.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/dashboard/assigned
{
  "google": {
      "dashboardIcon": [
          "Google.gif"
      ],
      "dashboardName": [
          "Google"
      ],
      "dashboardLogin": [
          "http://www.google.com"
      ],
      "ICFIdentifier": [
          ""
      ],
      "dashboardDisplayName": [
          "Google"
      ],
      "dashboardClassName": [
          "SAML2ApplicationClass"
      ]
   }
}
      
/dashboard/available

This endpoint retrieves the list of applications available in the authenticated user's realm. The example is based on two of the default Dashboard applications: Google and Salesforce.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/dashboard/available
{
  "google": {
      "dashboardIcon": [
          "Google.gif"
      ],
      "dashboardName": [
          "Google"
      ],
      "dashboardLogin": [
          "http://www.google.com"
      ],
      "ICFIdentifier": [
          ""
      ],
      "dashboardDisplayName": [
          "Google"
      ],
      "dashboardClassName": [
          "SAML2ApplicationClass"
      ]
  }
  "salesforce": {
      "dashboardIcon": [
          "salesforce.gif"
      ],
      "dashboardName": [
          "Salesforce"
      ],
      "dashboardLogin": [
          "http://salesforce.com"
      ],
      "ICFIdentifier": [
          ""
      ],
      "dashboardDisplayName": [
          "Salesforce"
      ],
      "dashboardClassName": [
          "SAML2ApplicationClass"
      ]
  }
}
      
/dashboard/defined

This endpoint retrieves the list of all applications available defined for the OpenAM Dashboard service. The example is based on the three default Dashboard applications: Google, Salesforce, and Zendesk.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...2NzEz*" \
 https://openam.example.com:8443/openam/json/dashboard/defined
{
    "google": {
        "dashboardIcon": [
            "Google.gif"
        ],
        "dashboardName": [
            "Google"
        ],
        "dashboardLogin": [
            "http://www.google.com"
        ],
        "ICFIdentifier": [
            "idm magic 34"
        ],
        "dashboardDisplayName": [
            "Google"
        ],
        "dashboardClassName": [
            "SAML2ApplicationClass"
        ]
    },
    "salesforce": {
        "dashboardIcon": [
            "salesforce.gif"
        ],
        "dashboardName": [
            "SalesForce"
        ],
        "dashboardLogin": [
            "http://www.salesforce.com"
        ],
        "ICFIdentifier": [
            "idm magic 12"
        ],
        "dashboardDisplayName": [
            "Salesforce"
        ],
        "dashboardClassName": [
            "SAML2ApplicationClass"
        ]
    },
    "zendesk": {
        "dashboardIcon": [
            "ZenDesk.gif"
        ],
        "dashboardName": [
            "ZenDesk"
        ],
        "dashboardLogin": [
            "http://www.ZenDesk.com"
        ],
        "ICFIdentifier": [
            "idm magic 56"
        ],
        "dashboardDisplayName": [
            "ZenDesk"
        ],
        "dashboardClassName": [
            "SAML2ApplicationClass"
        ]
    }
}
      

If your application runs in a user-agent such as a browser, you can rely on OpenAM to handle authentication.

3.15. REST Status Codes

OpenAM REST APIs respond to successful requests with HTTP status codes in the 2xx range. OpenAM REST APIs respond to error conditions with HTTP status codes in the 4xx and 5xx range. Status codes used are described in the following list.

200 OK

The request was successful and a resource returned, depending on the request. For example, a successful HTTP GET on /users/myUser returns a user profile and status code 200, whereas a successful HTTP DELETE returns {"success","true"} and status code 200.

201 Created

The request succeeded and the resource was created.

400 Bad Request

The request was malformed as in the following example, which is sending bad data in the payload for the action.

$ curl \
 --request POST \
 --header "Content-Type: application/json" \
 --data '{"bad":"data"}' \
 https://openam.example.com:8443/openam/json/users?_action=forgotPassword

{"code":400,"reason":"Bad Request","message":"Username not provided"}
      
401 Unauthorized

The request requires user authentication as in the following example, which is missing an SSO Token value.

$ curl \
 --request POST \
 https://openam.example.com:8443/openam/json/sessions?_action=logout

{ "code": 401, "reason": "Unauthorized", "message": "Access denied" }
      
403 Forbidden

Access was forbidden during an operation on a resource as in the following example, which has a regular user trying to read the OpenAM administrator profile.

$ curl \
 --request POST \
 --header "X-OpenAM-Username: demo" \
 --header "X-OpenAM-Password: changeit" \
 https://openam.example.com:8443/openam/json/authenticate

{ "tokenId": "AQIC5w...YyMA..*" }

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...YyMA..*" \
 https://openam.example.com:8443/openam/json/users/amadmin
{
    "code": 403,
    "reason": "Forbidden",
    "message": "Permission to perform the read operation denied to
                id=demo,ou=user,dc=openam,dc=forgerock,dc=org"
}
      
404 Not Found

The specified resource could not be found as in the following example, which is attempting to read a nonexistent user's profile.

$ curl \
 --header "iplanetDirectoryPro: AQIC5w...NTcy*" \
 https://openam.example.com:8443/openam/json/users/missing

{"code":404,"reason":"Not Found","message":"Resource cannot be found."}
      
405 Method Not Allowed

The HTTP method is not allowed for the requested resource.

409 Conflict

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

415 Unsupported Media Type

The request is in a format not supported by the requested resource for the requested method as in the following example, which is attempting to pass basic authentication credentials as form-encoded data rather than query string parameters.

$ curl \
 --request POST \
 --data "username=demo&password=changeit" \
 https://openam.example.com:8443/openam/json/authenticate
...
HTTP Status 415
...
The server refused this request because the request entity is in a
 format not supported by the requested resource for the requested method
...
      
500 Internal Server Error

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

501 Not Implemented

The resource does not support the functionality required to fulfill the request as in the following example, which is attempting to delete an entry as a delete action instead of using an HTTP DELETE request.

$ curl \
 --request POST \
 --header "iplanetDirectoryPro: AQIC5w...NTcy*" \
 https://openam.example.com:8443/openam/json/users/demo?_action=delete

{
    "code": 501,
    "reason": "Not Implemented",
    "message": "Actions are not supported for resource instances"
}
      
503 Service Unavailable

The requested resource was temporarily unavailable.