---
title: Filters
description: Filter objects intercept requests and responses during processing, and change them as follows:
component: pinggateway
version: 7.2
page_id: pinggateway:reference:Filters
canonical_url: https://docs.pingidentity.com/pinggateway/2026/reference/Filters.html
llms_txt: https://docs.pingidentity.com/pinggateway/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: 2022-06-13T17:41:33Z
superseded_by: https://docs.pingidentity.com/pinggateway/2026/reference/Filters.html
section_ids:
  AllowOnlyFilter: AllowOnlyFilter
  AllowOnlyFilter-usage: Usage
  AllowOnlyFilter-properties: Properties
  AllowOnlyFilter-example: Examples
  AllowOnlyFilter-moreinfo: More information
  AmSessionIdleTimeoutFilter: AmSessionIdleTimeoutFilter
  AmSessionIdleTimeoutFilter-usage: Usage
  AmSessionIdleTimeoutFilter-properties: Properties
  AmSessionIdleTimeoutFilter-example: Example
  AmSessionIdleTimeoutFilter-moreinfo: More information
  AssignmentFilter: AssignmentFilter
  AssignmentFilter-usage: Usage
  AssignmentFilter-properties: Properties
  AssignmentFilter-example: Examples
  AssignmentFilter-moreinfo: More information
  AuthorizationCodeOAuth2ClientFilter: AuthorizationCodeOAuth2ClientFilter
  AuthorizationCodeOAuth2ClientFilter-serviceuri: Service URIs
  AuthorizationCodeOAuth2ClientFilter-usage: Usage
  AuthorizationCodeOAuth2ClientFilter-properties: Properties
  AuthorizationCodeOAuth2ClientFilter-example: Examples
  AuthorizationCodeOAuth2ClientFilter-moreinfo: More information
  CapturedUserPasswordFilter: CapturedUserPasswordFilter
  CapturedUserPasswordFilter-usage: Usage
  CapturedUserPasswordFilter-properties: Properties
  CapturedUserPasswordFilter-examples: Examples
  CapturedUserPasswordFilter-moreinfo: More information
  CertificateThumbprintFilter: CertificateThumbprintFilter
  CertificateThumbprintFilter-usage: Usage
  CertificateThumbprintFilter-properties: Properties
  CertificateThumbprintFilter-examples: Examples
  CertificateThumbprintFilter-moreinfo: More information
  CircuitBreakerFilter: CircuitBreakerFilter
  CircuitBreakerFilter-usage: Usage
  CircuitBreakerFilter-properties: Properties
  CircuitBreakerFilter-example: Example
  CircuitBreakerFilter-moreinfo: More information
  ClientCredentialsOAuth2ClientFilter: ClientCredentialsOAuth2ClientFilter
  ClientCredentialClientCredentialsOAuth2ClientFilter-usage: Usage
  ClientCredentialsOAuth2ClientFilter-properties: Properties
  ClientCredentialsOAuth2ClientFilter-example: Examples
  ClientCredentialsOAuth2ClientFilter-moreinfo: More information
  ClientSecretBasicAuthenticationFilter: ClientSecretBasicAuthenticationFilter
  ClientSecretBasicAuthenticationFilter-usage: Usage
  ClientSecretBasicAuthenticationFilter-conf: Configuration
  ClientSecretBasicAuthenticationFilter-example: Example
  ClientSecretPostAuthenticationFilter: ClientSecretPostAuthenticationFilter
  ClientSecretPostAuthenticationFilter-usage: Usage
  ClientSecretPostAuthenticationFilter-conf: Configuration
  ConditionalFilter: ConditionalFilter
  ConditionalFilter-usage: Usage
  ConditionalFilter-properties: Properties
  ConditionalFilter-example: Example
  ConditionalFilter-moreinfo: More information
  ConditionEnforcementFilter: ConditionEnforcementFilter
  ConditionEnforcementFilter-usage: Usage
  ConditionEnforcementFilter-properties: Properties
  ConditionEnforcementFilter-example: Example
  ConditionEnforcementFilter-moreinfo: More information
  ChainOfFilters: ChainOfFilters
  ChainOfFilters-usage: Usage
  ChainOfFilters-properties: Properties
  ChainOfFilters-example: Example
  ChainOfFilters-moreinfo: More information
  CookieFilter: CookieFilter
  CookieFilter-usage: Usage
  CookieFilter-properties: Properties
  CookieFilter-moreinfo: More information
  CorsFilter: CorsFilter
  CorsFilter-usage: Usage
  CorsFilter-properties: Properties
  CorsFilter-moreinfo: More information
  CrossDomainSingleSignOnFilter: CrossDomainSingleSignOnFilter
  websocket_notifications_for_sessions: WebSocket notifications for sessions
  CrossDomainSingleSignOnFilter-desc-usage: Usage
  CrossDomainSingleSignOnFilter-properties: Properties
  CrossDomainSingleSignOnFilter-example: Example
  CrossDomainSingleSignOnFilter-moreinfo: More information
  CryptoHeaderFilter: CryptoHeaderFilter (deprecated)
  CryptoHeaderFilter-usage: Usage
  CryptoHeaderFilter-properties: Properties
  CryptoHeaderFilter-example: Example
  CryptoHeaderFilter-moreinfo: More information
  CsrfFilter: CsrfFilter
  CsrfFilter-usage: Usage
  CsrfFilter-properties: Properties
  CsrfFilter-example: Example
  CsrfFilter-moreinfo: More information
  DateHeaderFilter: DateHeaderFilter
  DateHeaderFilter-usage: Usage
  DateHeaderFilter-properties: Properties
  DateHeaderFilter-example: Example
  DateHeaderFilter-moreinfo: More information
  EncryptedPrivateKeyJwtClientAuthenticationFilter: EncryptedPrivateKeyJwtClientAuthenticationFilter
  EncryptedPrivateKeyJwtClientAuthenticationFilter-usage: Usage
  EncryptedPrivateKeyJwtClientAuthenticationFilter-conf: Configuration
  EntityExtractFilter: EntityExtractFilter
  EntityExtractFilter-usage: Usage
  EntityExtractFilter-properties: Properties
  EntityExtractFilter-examples: Examples
  EntityExtractFilter-moreinfo: More information
  FapiInteractionIdFilter: FapiInteractionIdFilter
  FapiInteractionIdFilter-usage: Usage
  FapiInteractionIdFilter-properties: Properties
  FapiInteractionIdFilter-example: Example
  FapiInteractionIdFilter-more: More information
  FragmentFilter: FragmentFilter
  FragmentFilter-usage: Usage
  FragmentFilter-example: Example
  FragmentFilter-moreinfo: More information
  FileAttributesFilter: FileAttributesFilter
  FileAttributesFilter-usage: Usage
  FileAttributesFilter-properties: Properties
  FileAttributesFilter-moreinfo: More information
  ForwardedRequestFilter: ForwardedRequestFilter
  ForwardedRequestFilter-usage: Usage
  ForwardedRequestFilter-properties: Properties
  ForwardedRequestFilter-example: Example
  ForwardedRequestFilter-moreinfo: More information
  HeaderFilter: HeaderFilter
  HeaderFilter-usage: Usage
  HeaderFilter-properties: Properties
  HeaderFilter-example: Examples
  HeaderFilter-example-replacing: Replace host header on an incoming request
  HeaderFilter-example-cookie: Add a header to a response
  HeaderFilter-example-adding: Add headers to a request
  HeaderFilter-example-token: Add a token value to a response
  HeaderFilter-example-logging: Add headers and logging results
  HeaderFilter-moreinfo: More information
  HttpBasicAuthenticationClientFilter: HttpBasicAuthenticationClientFilter
  HttpBasicAuthenticationClientFilter-usage: Usage
  HttpBasicAuthenticationClientFilter-properties: Properties
  HttpBasicAuthenticationClientFilter-example: Example
  HttpBasicAuthFilter: HttpBasicAuthFilter
  HttpBasicAuthFilter-usage: Usage
  HttpBasicAuthFilter-properties: Properties
  HttpBasicAuthFilter-example: Example
  HttpBasicAuthFilter-moreinfo: More information
  IdTokenValidationFilter: IdTokenValidationFilter
  IdTokenValidationFilter-usage: Usage
  IdTokenValidationFilter-properties: Properties
  IdTokenValidationFilter-example: Example
  IdTokenValidationFilter-moreinfo: More information
  JwtBuilderFilter: JwtBuilderFilter
  JwtBuilderFilter-usage: Usage
  JwtBuilderFilter-properties: Properties
  JwtBuilderFilter-example: Examples
  JwtBuilderFilter-moreinfo: More information
  JwtValidationFilter: JwtValidationFilter
  JwtValidationFilter-usage: Usage
  JwtValidationFilter-properties: Properties
  JwtValidationFilter-example: Example
  JwtValidationFilter-moreinfo: More information
  LocationHeaderFilter: LocationHeaderFilter
  LocationHeaderFilter-usage: Usage
  LocationHeaderFilter-properties: Properties
  LocationHeaderFilter-example: Example
  LocationHeaderFilter-moreinfo: More information
  OAuth2ClientFilter: OAuth2ClientFilter
  OAuth2ResourceServerFilter: OAuth2ResourceServerFilter
  OAuth2ResourceServerFilter-usage: Usage
  OAuth2ResourceServerFilter-properties: Properties
  OAuth2ResourceServerFilter-example: Examples
  OAuth2ResourceServerFilter-moreinfo: More information
  OAuth2TokenExchangeFilter: OAuth2TokenExchangeFilter
  OAuth2TokenExchangeFilter-usage: Usage
  OAuth2TokenExchangeFilter-conf: Configuration
  OAuth2TokenExchangeFilter-example: Example
  OAuth2TokenExchangeFilter-moreinfo: More information
  PasswordReplayFilter: PasswordReplayFilter
  PasswordReplayFilter-usage: Usage
  PasswordReplayFilter-properties: Properties
  PasswordReplayFilter-example: Example
  PasswordReplayFilter-moreinfo: More information
  PolicyEnforcementFilter: PolicyEnforcementFilter
  PolicyEnforcementFilter-process-decision: Processing requests after a policy decision
  pef-advices: Using advices from policy decisions
  PolicyEnforcementFilter-conf-am: Notes on configuring policies in AM
  pef-eviction: WebSocket notifications for policy changes
  PolicyEnforcementFilter-usage: Usage
  PolicyEnforcementFilter-properties: Properties
  PEF-example: Example policy enforcement using claimsSubject
  PolicyEnforcementFilter-moreinfo: More information
  PrivateKeyJwtClientAuthenticationFilter: PrivateKeyJwtClientAuthenticationFilter
  PrivateKeyJwtClientAuthenticationFilter-usage: Usage
  PrivateKeyJwtClientAuthenticationFilter-conf: Configuration
  ResourceOwnerOAuth2ClientFilter: ResourceOwnerOAuth2ClientFilter
  ClientCredentialResourceOwnerOAuth2ClientFilter-usage: Usage
  ResourceOwnerOAuth2ClientFilter-properties: Properties
  ResourceOwnerOAuth2ClientFilter-example: Examples
  ResourceOwnerOAuth2ClientFilter-moreinfo: More information
  ScriptableFilter: ScriptableFilter
  ScriptableFilter-usage: Usage
  ScriptableFilter-properties: Properties
  ScriptableFilter-examples: Examples
  ScriptableFilter-moreinfo: More information
  SessionInfoFilter: SessionInfoFilter
  websocket_notifications_for_sessions_2: WebSocket notifications for sessions
  SessionInfoFilter-usage: Usage
  SessionInfoFilter-properties: Properties
  SessionInfoFilter-example: Examples
  SessionInfoFilter-moreinfo: More information
  SetCookieUpdateFilter: SetCookieUpdateFilter
  SetCookieUpdateFilter-usage: Usage
  SetCookieUpdateFilter-properties: Properties
  examples: Examples
  SetCookieUpdateFilter-moreinfo: More information
  SingleSignOnFilter: SingleSignOnFilter
  websocket_notifications_for_sessions_3: WebSocket notifications for sessions
  SingleSignOnFilter-usage: Usage
  SingleSignOnFilter-properties: Properties
  SingleSignOnFilter-moreinfo: More information
  SqlAttributesFilter: SqlAttributesFilter
  SqlAttributesFilter-usage: Usage
  SqlAttributesFilter-properties: Properties
  SqlAttributesFilter-example: Example
  StaticRequestFilter: StaticRequestFilter
  StaticRequestFilter-usage: Usage
  StaticRequestFilter-properties: Properties
  StaticRequestFilter-example: Example
  StaticRequestFilter-moreinfo: More information
  SwitchFilter: SwitchFilter
  SwitchFilter-usage: Usage
  SwitchFilter-properties: Properties
  SwitchFilter-example: Example
  SwitchFilter-moreinfo: More information
  ThrottlingFilter: ThrottlingFilter
  ThrottlingFilter-usage: Usage
  ThrottlingFilter-properties: Properties
  ThrottlingFilter-examples: Examples
  ThrottlingFilter-moreinfo: More information
  TokenTransformationFilter: TokenTransformationFilter
  TokenTransformationFilter-usage: Usage
  TokenTransformationFilter-properties: Properties
  TokenTransformationFilter-example: Example
  TokenTransformationFilter-moreinfo: More information
  TransactionIdOutboundFilter: TransactionIdOutboundFilter
  TransactionIdOutboundFilter-moreinfo: More information
  UmaFilter: UmaFilter
  UmaFilter-usage: Usage
  UmaFilter-properties: Properties
  UmaFilter-moreinfo: More information
  UriPathRewriteFilter: UriPathRewriteFilter
  UriPathRewriteFilter-usage: Usage
  UriPathRewriteFilter-properties: Properties
  UriPathRewriteFilter-example: Examples
  valid_and_invalid_mapping_examples: Valid and invalid mapping examples
  example_request_scenarios: Example request scenarios
  example_route: Example route
  UriPathRewriteFilter-moreinfo: More information
  UserProfileFilter: UserProfileFilter
  UserProfileFilter-usage: Usage
  UserProfileFilter-properties: Properties
  UserProfileFilter-example: Example
  UserProfileFilter-moreinfo: More information
---

# Filters

Filter objects intercept requests and responses during processing, and change them as follows:

* Leave the request, response, and contexts unchanged. For example, the filter can simply can log the context as it passes through the filter.

* In the request flow, change any aspect of the request (such as the URL, headers, or entity), or replace the request with a new Request object.

* In the response flow, change any aspect of the response (such as the status, headers, or entity), or return a new Response instance

## AllowOnlyFilter

Authorizes a request to continue processing if it satisfies at least one of the configured rules. Otherwise, passes the request to the FailureHandler or returns an HTTP 401 Unauthorized, with an empty response body.

This filter manages requests from the *last request sender*, otherwise called the *request from the last hop*, or the *request from a direct client*.

For debugging, configure the AllowOnlyFilter `name`, and add the following logger to `logback.xml`, replacing filter_name with the name:

```
org.forgerock.openig.filter.allow.AllowOnlyFilter.filter_name
```

For more information, see [Managing logs](../maintenance-guide/logging.html).

### Usage

```json
{
  "name": string,
  "type": "AllowOnlyFilter",
  "config": {
    "rules": [ object, ... ],
    "failureHandler": Handler reference
  }
}
```

### Properties

* `"rules"`: *array of [objects](preface.html#definition-object), required*

  An array of one or more `rules` configuration objects to specify criteria for the request.

  When more than one `rules` configuration object is included in the array, the request must match at least one of the configuration objects.

  When more than one property is specified in the `rules` configuration (for example, `from` and `destination`) the request must match criteria for each property.

  ```json
  {
    "rules": [
      {
        "name": configuration expression<string>,
        "from": [ object, ... ],
        "destination": [ object, ... ],
        "when": configuration expression<boolean>
      },
      ...
    ]
  }
  ```

  * `"name"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    A name for the `rules` configuration. When logging is configured for the AllowOnlyFilter, the rule name appears in the logs.

  * `"from"`: *array of [objects](preface.html#definition-object), required*

    An array of one or more `from` configuration objects to specify criteria about the last request sender (the direct client).

    When more than one `from` configuration object is included in the array, the last request sender must match at least one of the configuration objects.

    When both `ip` and `certificate` properties are included in the configuration, the last request sender must match criteria for both properties.

    ```json
    "from": [
      {
        "ip": {
          "list": [configuration expression<string>, ...],
          "resolver": runtime expression<string>
        },
        "certificate" : {
          "subjectDNs" : Pattern[]
        }
      },
      ...
    ]
    ```

    * `"ip"`: *[object](preface.html#definition-object), optional*

      Criteria about the IP address of the last request sender.

      * `"list"`: *array of configuration expression<[strings](preface.html#definition-string)>, required*:

        An array of IP addresses or IP address ranges, using IPv4 or IPv6, and CIDR notation. The following example includes different formats:

        ```json
        "list": ["127.0.0.1", "::1", "192.168.0.0/16", "1234::/16"]
        ```

        The IP address of the last request sender must match at least one of the specified IP addresses or IP address ranges.

        * `"resolver"`: *runtime expression<[string](preface.html#definition-string)>, optional*:

          An expression that returns an IP address as a string. The following example returns an IP address from the first item in `X-Forwarded-For`:

          ```json
          "resolver": "${request.headers['X-Forwarded-For'][0]}"
          ```

          Default: Resolve the IP address from the following items, in the following order:

          1. If there is a `Forwarded` header, use the IP address of the last hop.

          2. Otherwise, if there is an `X-Forwarded-For` header, use the IP address of the last hop.

          3. Otherwise, use the IP address of the connection.

    * `"certificate"`: *array of [objects](preface.html#definition-object), optional*

      An array of `certificate` configuration objects that specify criteria about the certificate of the last request sender.

      * `"subjectDNs"`: *array of [patterns](preface.html#definition-pattern), required*:

        An array of patterns to represent the expected distinguished name of the certificate subject, the `subjectDN`. The `subjectDN` of the last request sender must match at least one of the patterns.

  * `"destination"`: *array of [objects](preface.html#definition-object), optional*

    An array of `destination` configuration objects to specify criteria about the request destination.

    When more than one `destination` configuration object is included in the array, the request destination must match at least one of the configuration objects.

    When more than one property is specified in the `destination` configuration, for example `hosts` and `ports`, the request destination must match criteria for each property.

    ```json
    "destination": [
      {
        "hosts": [pattern, ... ],
        "ports": [configuration expression<string>, ... ],
        "methods": [configuration expression<string>, ... ],
        "paths": [pattern, ... ]
      },
      ...
    ]
    ```

    * `"hosts"`: *array of [patterns](preface.html#definition-pattern), optional*

      An array of *case-insensitive* patterns to match the `request.host` attribute. Patterns are matched with the Java [Pattern](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html) class.

      When this property is configured, the request destination must match at least one host pattern in the array.

      Default: Any host is allowed.

    * `"ports"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

      An array of strings to match the `request.port` attribute. Specify values in the array as follows:

      * Array of single ports, for example `["80", "90"]`.

      * Array of port ranges, for example `["100:200"]`.

      * Array of single ports and port ranges, for example `["80", "90", "100:200"]`.

      When this property is configured, the destination port must match at least one entry in the array.

      Default: Any port is allowed.

    * `"methods"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

      An array of HTTP methods to match the `request.method` attribute.

      When this property is configured, the request method must match at least one method in the array.

      Default: Any method is allowed.

    * `"paths"`: *array of [patterns](preface.html#definition-pattern), optional*

      An array of *case-sensitive* patterns to match the `request.url_path` attribute. Patterns are matched with the Java [Pattern](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html) class.

      When this property is configured, the destination path must match at least one path in the array.

      Default: Any path is allowed.

  * `"when"`: *runtime expression<[boolean](preface.html#definition-boolean)>, optional*

    A flag to indicate that the request meets a condition. When `true`, the request is allowed.

    The following condition is met when the first value of `h1` is `1`:

    ```json
    "when": "${request.headers['h1'][0] == '1'}"
    ```

    Default: `${true}`

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request if none of the declared rules are satisfied.

  Provide either the name of a Handler object defined in the heap, or an inline Handler configuration object.

  Default: HTTP 401 Unauthorized, with an empty response body.

  See also [Handlers](Handlers.html).

### Examples

In the following example, a request is authorized if the last request sender satisfies *either* of the following conditions:

* Certificate subjectDN matches `.*CN=test$` *or* `CN=me`, *and* the IP address is in the range 1.2.3.0/24.

* IP address is 123.43.56.8.

```json
"from": [
   {
     "certificate": {
          "subjectDNs": [".*CN=test$", "CN=me"]
     },
     "ip": {
       "list": ["1.2.3.0/24"]
     }
   },
   {
     "ip": {
       "list": ["123.43.56.8"]
     }
   },
]
```

In the following example, a request is authorized if the request destination satisfies *all* of the following conditions:

* The host is `myhost1.com` *or* `www.myhost1.com`

* The port is `80`.

* The method is `POST` *or* `GET`

* The path matches `/user/*`.

```json
"destination": [
  {
    "hosts": ["myhost1.com", "www.myhost1.com"],
    "ports": ["80"],
    "methods": ["POST", "GET"],
    "paths": ["/user/*"]
  }
]
```

The following example authorizes a request to continue processing if the requests meets the conditions set by *either* `rule1` or `rule2`:

```json
{
  "type": "AllowOnlyFilter",
  "config": {
    "rules": [
      {
        "name": "rule1",
        "from": [
          {
            "certificate": {
              "subjectDNs": [".*CN=test$", "CN=me"]
            },
            "ip": {
              "list": ["1.2.3.0/24"]
            }
          }
        ],
        "destination": [
          {
            "hosts": ["myhost1.com", "www.myhost1.com"],
            "ports": ["80"],
            "methods": ["POST", "GET"],
            "paths": ["/user/*"]
          }
        ],
        "when": "${request.headers['h1'][0] == '1'}"
      },
      {
        "name":"rule2",
        "when": "${request.headers['h1'][0] == '2'}"
      }
    ]
  }
}
```

### More information

[org.forgerock.openig.filter.allow.AllowOnlyFilter](../_attachments/apidocs/org/forgerock/openig/filter/allow/AllowOnlyFilter.html)

## AmSessionIdleTimeoutFilter

Forces the revocation of AM sessions that have been idle for a specified duration. The AmSessionIdleTimeoutFilter issues an authenticated and encrypted JWT to track activity on the AM session, and conveys it within a persistent cookie. The tracking token contains the following parts:

* The time when the user was last seen active

* A hash of the AM session cookie, to bind the tracking token to the AM session cookie

* The idle timeout

Multiple filter instances can share the same tracking token, for example, in a clustered IG configuration, or when a federation of applications protected by authentication filters need to have a flexible idle timeout strategy.

AmSessionIdleTimeoutFilter requires the following configuration:

* In AM, client-side sessions must be enabled for the realm in which the tracking token operates. See [Configure client-side sessions](https://docs.pingidentity.com/pingam/7.2/sessions-guide/impl-client-based-sessions.html#proc-configure-client-based-sessions) in AM's *Sessions Guide*.

* In AM, client-side session denylisting must be enabled. See [Configure client-side session denylisting](https://docs.pingidentity.com/pingam/7.2/sessions-guide/session-state-session-termination.html#session-state-configure-denylist) in AM's *Sessions Guide*.

* The AmSessionIdleTimeoutFilter must be placed in a route before a filter that uses the AM session token, such as a SingleSignOnFilter or PolicyEnforcementFilter.

* In production environments, and when multiple AmSessionIdleTimeoutFilters use the same tracking token, the encryption must not rely on the default configuration. It must be configured identically on each filter that uses the tracking token.

The following image shows the flow of information when an AmSessionIdleTimeoutFilter sits in front of a CrossDomainSingleSignOnFilter, to manage AM session timeout.

![Flow of information when an AmSessionIdleTimeoutFilter sits in front of a CrossDomainSingleSignOnFilter.](_images/idletime.svg)

\[1-5] When the AmSessionIdleTimeoutFilter receives an unauthenticated request, it passes the request along the chain, and the CrossDomainSingleSignOnFilter manages authentication.

\[6-8] When the AmSessionIdleTimeoutFilter receives an authenticated request, it checks that the AM session token is valid, and then passes the request along the chain.

\[9-10] If the AM session was valid, the AmSessionIdleTimeoutFilter issues a tracking token on the response flow, containing the following information:

* Hash of the AM session token

* Current timestamp

* Idle timeout of the current filter

If the AM session was not valid, the AmSessionIdleTimeoutFilter does nothing on the response flow.

\[11-12] The AmSessionIdleTimeoutFilter places the tracking token in persistent tracking cookie, and sends it with the response, to be used in the next request.

\[13-15] When the same or another AmSessionIdleTimeoutFilter receives an authenticated request with a tracking token, it checks that the AM session token is valid, and checks that tracking token hash is bound to the AM session.

\[16] Depending on the strategy set by `idleTimeoutUpdate`, the AmSessionIdleTimeoutFilter selects the value for `idleTimeout` from the tracking token (set by the AmSessionIdleTimeoutFilter in a previous request) or from its own value of `idleTimeout` (if this is a different instance of AmSessionIdleTimeoutFilter).

The AmSessionIdleTimeoutFilter checks for AM session timeout. If the last activity time plus the idle timeout is before the current time, the session has timed out. For example, a session with the following values has timed out:

* last activity time: 15h30 today

* idle timeout: 5 mins

* current time: 15h40

\[17-21] The AM session has timed out, so the AmSessionIdleTimeoutFilter does the following:

* Forces AM to revoke the session.

* Passes the request along the chain.

* Expires the tracking cookie on the response flow, and sends it with the response.

\[22-26] The session has not timed out, so the AmSessionIdleTimeoutFilter does the following:

* Passes the request along the chain.

* Updates the tracking token on the response flow, with the current timestamp and the value for `idleTimeOut`, using the same value for that was selected in step 16.

* Places the tracking token in a persistent tracking cookie, and sends it with the response, to be used in the next request.

### Usage

```json
{
  "name": string,
   "type": "AmSessionIdleTimeoutFilter",
   "config": {
     "amService": AmService reference,
     "idleTimeout": configuration expression<duration>,
     "sessionToken": runtime expression<string>,
     "idleTimeoutUpdate": configuration expression<enumeration>,
     "secretsProvider": SecretsProvider reference,
     "encryptionSecretId": configuration expression<secret-id>,
     "encryptionMethod": configuration expression<string>,
     "cookie": object
   }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  The AmService that refers to the AM instance that issue tracked session token.

* `"idleTimeout"`: *configuration expression<[duration](preface.html#definition-duration)>, required*

  The time a session can be inactive before it is considered as idle.

  When an AmSessionIdleTimeoutFilter creates the tracking token, the token's value for `idleTimeout` is set by this property. When a different AmSessionIdleTimeoutFilter accesses the same tracking token, depending on the strategy set by `idleTimeoutUpdate`, the token's value for `idleTimeout` can be updated by the second AmSessionIdleTimeoutFilter.

* `"sessionToken"`: *runtime expression<[string](preface.html#definition-string)>, optional*

  The location of the AM session token in the request. The following example accesses the first value of the request cookie `iPlanetDirectoryPro`:

  ```none
  "sessionToken": "${request.cookies['iPlanetDirectoryPro'][0].value}"
  ```

  For information about the AM session cookie, see [Find the name of your AM session cookie](../gateway-guide/preface.html#am-session-cookie).

  Default: `${request.cookies['<cookie name defined in the referenced AmService>'][0].value}`

* `idleTimeoutUpdate`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

  When multiple AmSessionIdleTimeoutFilters use the same tracking token, this property selects whether to use the `idleTimeout` from this filter or from the tracking token.

  Use one of the following values:

  * `NEVER`: Use the idle timeout from the tracking token, and ignore the idle timeout from this filter.

  * `ALWAYS`: Use the idle timeout from this filter, and ignore the idle timeout from the tracking token.

  * `INCREASE_ONLY`: Compare the idle timeout from this filter and the tracking token, and use the longest value.

  * `DECREASE_ONLY`: Compare the idle timeout from this filter and the tracking token, and use the shortest value.

  Default: `ALWAYS`

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), optional*

  The [SecretsProvider](secrets.html#SecretsProvider) to query for secrets to encrypt the tracking token.

* `"encryptionSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, optional*

  The secret ID of the encryption key used to encrypt the tracking cookie.

  In production environments, and when multiple AmSessionIdleTimeoutFilters use the same tracking cookie, the encryption must not rely on the default configuration. It must be configured identically on each filter that uses the cookie.

  Authenticated encryption is achieved with a symmetric encryption key. Therefore, the secret must refer to a symmetric key.

  For more information, see [RFC 5116](https://datatracker.ietf.org/doc/html/rfc5116).

  Default: When no `secretsProvider` is provides, IG generates a random symmetric key for authenticated encryption.

- `"encryptionMethod"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The algorithm to use for authenticated encryption. For information about allowed encryption algorithms, see [RFC 7518: "enc" (Encryption Algorithm) Header Parameter Values for JWE](https://www.rfc-editor.org/rfc/rfc7518#section-5.1).

  Default: A256GCM

- `"cookie"`: *[object](preface.html#definition-object), optional*

  Configuration of the activity tracking cookie.

  ```json
  {
    "name": configuration expression<string>,
    "domain": configuration expression<string>,
    "httpOnly": configuration expression<boolean>,
    "path": configuration expression<string>,
    "sameSite": configuration expression<enumeration>,
    "secure": configuration expression<boolean>
  }
  ```

  * `"name"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    The cookie name.

    Default: `x-ig-activity-tracker`

  - `"domain"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Domain to which the cookie applies.

    Default: The fully qualified hostname of the IG host.

  - `"httpOnly"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Flag to mitigate the risk of client-side scripts accessing protected cookies.

    Default: `true`

  - `"path"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Path to apply to the cookie.

    Default: `/`

  - `"sameSite"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

    Options to manage the circumstances in which a cookie is sent to the server. Use one of the following values to reduce the risk of CSRF attacks:

    * `STRICT`: Send the cookie only if the request was initiated from the cookie domain. Not case-sensitive. Use this value to reduce the risk of cross-site request forgery (CSRF) attacks.

    * `LAX`: Send the cookie only with GET requests in a first-party context, where the URL in the address bar matches the cookie domain. Not case-sensitive. Use this value to reduce the risk of cross-site request forgery (CSRF) attacks.

    * `NONE`: Send the cookie whenever a request is made to the cookie domain. With this setting, consider setting `secure` to `true` to prevent browsers from rejecting the cookie. For more information, see [SameSite cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite).

    Default: Null

  - `"secure"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Flag to limit the scope of the cookie to secure channels.

    Default: `false`

### Example

```json
{
  "type": "AmSessionIdleTimeoutFilter",
  "config": {
    "sessionToken": "${request.cookies['iPlanetDirectoryPro'][0].value}",
    "amService": "AmService",
    "idleTimeout": "1 minute",
    "idleTimeoutUpdate": "ALWAYS",
    "cookie": {
      "name": "x-ig-activity-tracker",
      "domain": null,
      "path": "/",
      "secure": false,
      "httpOnly": true,
      "sameSite": null
    },
   "secretsProvider": "secrets-provider-ref",
   "encryptionMethod": "A256GCM",
   "encryptionSecretId": "crypto.key.secret.id"
  }
}
```

### More information

[org.forgerock.openig.openam.session.AmSessionIdleTimeoutFilter](../_attachments/apidocs/org/forgerock/openig/openam/session/AmSessionIdleTimeoutFilter.html)

## AssignmentFilter

Verifies that a specified condition is met. If the condition is met or if no condition is specified, the value is assigned to the target. Values can be assigned before the request is handled and after the response is handled.

### Usage

```json
{
  "name": string,
  "type": "AssignmentFilter",
  "config": {
    "onRequest": [
      {
        "condition": runtime expression<boolean>,
        "target": lvalue-expression,
        "value": runtime expression
      }, ...
    ],
    "onResponse": [
      {
        "condition": runtime expression<boolean>,
        "target": lvalue-expression,
        "value": runtime expression
      }, ...
    ]
  }
}
```

### Properties

* `"onRequest"`: *array of [objects](preface.html#definition-object), optional*

  Defines a list of assignment bindings to evaluate before the request is handled.

* `"onResponse"`: *array of [objects](preface.html#definition-object), optional*

  Defines a list of assignment bindings to evaluate after the response is handled.

* `"condition"`: *runtime expression<[boolean](preface.html#definition-boolean)>, optional*

  If the expression evaluates `true`, the value is assigned to the target.

  Default: `${true}`

* `"target"`: *<[lvalue-expression](preface.html#definition-lvalue-expression)>, required*

  Expression that yields the target object whose value is to be set.

* `"value"`: *runtime expression<[object](preface.html#definition-object)> , optional*

  The value to be set in the target. The value can be a string, information from the context, or even a whole map of information.

### Examples

Add info to a session

The following example assigns a value to a session. Add the filter to a route to prevent IG from clearing up empty JWTSession cookies:

```json
{
  "type": "AssignmentFilter",
  "config": {
    "onRequest": [{
      "target": "${session.authUsername}",
      "value": "I am root"
    }]
  }
}
```

Capture and store login credentials

The following example captures credentials and stores them in the IG session during a login request. Notice that the credentials are captured on the request but are not marked as valid until the response returns a positive 302. The credentials could then be used to log a user in to a different application:

```json
{
  "name": "PortalLoginCaptureFilter",
  "type": "AssignmentFilter",
  "config": {
    "onRequest": [
      {
        "target": "${session.authUsername}",
        "value": "${request.queryParams['username'][0]}"
      },
      {
        "target": "${session.authPassword}",
        "value": "${request.queryParams['password'][0]}"
      },
      {
        "comment": "Authentication has not yet been confirmed.",
        "target": "${session.authConfirmed}",
        "value": "${false}"
      }
    ],
    "onResponse": [
      {
        "condition": "${response.status.code == 302}",
        "target": "${session.authConfirmed}",
        "value": "${true}"
      }
    ]
  }
}
```

### More information

[org.forgerock.openig.filter.AssignmentFilter](../_attachments/apidocs/org/forgerock/openig/filter/AssignmentFilter.html)

## AuthorizationCodeOAuth2ClientFilter

The AuthorizationCodeOAuth2ClientFilter uses OAuth 2.0 delegated authorization to authenticate end users. The filter can act as an OpenID Connect relying party or as an OAuth 2.0 client.

AuthorizationCodeOAuth2ClientFilter performs the following tasks:

* Allows the user to select an authorization server from one or more static client registrations, or by discovery and dynamic registration.

  In static client registration, authorization servers are provided by [Issuer](MiscellaneousConfigurationObjects.html#Issuer), and registrations are provided by [ClientRegistration](MiscellaneousConfigurationObjects.html#ClientRegistration).

* Redirects the user through the authentication and authorization steps of an OAuth 2.0 authorization code grant, which results in the authorization server returning an access token to the filter.

* When an authorization grant succeeds, injects the access token data into a configurable target in the context so that subsequent filters and handlers can access the access token. Subsequent requests can use the access token without authenticating again.

* When an authorization grant fails, invokes a failureHandler.

### Service URIs

Service URIs are constructed from the `clientEndpoint`, as follows:

* `clientEndpoint/login/?discovery=user-input&goto=url`

  Discover and register dynamically with the end user's OpenID Provider or with the client registration endpoint as described in RFC 7591, using the value of user-input.

  After successful registration, redirect the end user to the provider for authentication and authorization consent. Then redirect the user-agent back to the callback client endpoint, and then the goto URI.

  The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.

  To redirect a request to a site that does not meet the goto URL criteria, change the original URI by using a ForwardedRequestFilter.

* `clientEndpoint/login?registration=clientId&issuer=issuerName&goto=url`

  Redirect the end user for authorization with the specified registration, defined by the ClientRegistration's `clientId` and `issuerName`. For information, see [ClientRegistration](MiscellaneousConfigurationObjects.html#ClientRegistration).

  The provider corresponding to the registration then authenticates the end user and obtains authorization consent before redirecting the user-agent back to the callback client endpoint.

  If successful, the filter saves the authorization state in the session and redirects the user-agent to the goto URL.

  The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.

  To redirect a request to a site that does not meet the goto URL criteria, change the original URI by using a ForwardedRequestFilter.

* `clientEndpoint/logout?goto=url`

  Remove the authorization state for the end user, and redirect the request to the goto URL.

  The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.

  To redirect a request to a site that does not meet the goto URL criteria, change the original URI by using a ForwardedRequestFilter.

  If no goto URL is specified in the request, use `defaultLogoutGoto`.

* `clientEndpoint/callback`

  Handle the callback from the OAuth 2.0 authorization server, that occurs as part of the authorization process.

  If the callback is handled successfully, the filter saves the authorization state in the context at the specified target location and redirects to the URL provided to the login endpoint during login.

* Other request URIs

  Restore the authorization state in the specified target location, and call the next filter or handler in the chain.

### Usage

```json
{
  "name": string,
  "type": "AuthorizationCodeOAuth2ClientFilter",
  "config": {
    "clientEndpoint": runtime expression<uri string>,
    "failureHandler": Handler reference,
    "loginHandler": Handler reference,
    "registrations": [ ClientRegistration reference, ... ],
    "metadata": object,
    "cacheExpiration": configuration expression<duration>,
    "executor": ScheduledExecutorService reference,
    "target": lvalue-expression,
    "defaultLoginGoto": runtime expression<url>,
    "defaultLogoutGoto": runtime expression<url>,
    "requireHttps": configuration expression<boolean>,
    "requireLogin": configuration expression<boolean>,
    "issuerRepository": Issuer repository reference,
    "discoveryHandler": Handler reference,
    "discoverySecretId": configuration expression<secret-id>,
    "tokenEndpointAuthMethod": configuration expression<enumeration>,
    "tokenEndpointAuthSigningAlg": configuration expression<string>,
    "oAuth2SessionKey": configuration expression<string>,
    "secretsProvider": SecretsProvider reference
  }
}
```

### Properties

* `"clientEndpoint"`: *runtime expression<[url](preface.html#definition-url)>, required*

  The URI to the client endpoint.

  So that routes can accept redirects from the authorization server to the callback endpoint, the `clientEndpoint` must be the same as the route condition or a sub path of the route condition. For example:

  * The same as the route condition:

    ```json
    "condition": "${find(request.uri.path, '^/discovery')}"
    ```

    ```json
    "clientEndpoint": "/discovery"
    ```

  * As a sub path of the route condition:

    ```json
    "condition": "${find(request.uri.path, '^/home/id_token')}"
    ```

    ```json
    "clientEndpoint": "/home/id_token/sub-path"
    ```

    Service URIs are constructed from the `clientEndpoint`. For example, when `clientEndpoint` is `openid`, the service URIs are `/openid/login`, `/openid/logout`, and `/openid/callback`. These endpoints are implicitly reserved, and attempts to access them directly can cause undefined errors.

    The result of the expression must be a string that represents a valid URI, but is not a real `java.net.URI` object. For example, it would be incorrect to use `${request.uri}`, which is not a String but a MutableUri.

    See also [Expressions](Expressions.html#Expressions).

- `"failureHandler"`: *Handler [reference](preface.html#definition-reference), required*

  An inline handler configuration object, or the name of a handler object that is defined in the heap.

  When the OAuth 2.0 Resource Server denies access to a resource, the failure handler can be invoked only if the error response contains a WWW-Authenticate header (meaning that there was a problem with the OAuth 2.0 exchange). All other responses are forwarded to the user-agent without invoking the failure handler.

  If the value of the WWW-Authenticate header is `invalid_token`, the AuthorizationCodeOAuth2ClientFilter tries to refresh the access token:

  * If the token is refreshed, the AuthorizationCodeOAuth2ClientFilter tries again to access the protected resource.

  * If the token is not refreshed, or if the second attempt to access the protected resource fails, the AuthorizationCodeOAuth2ClientFilter invokes the failure handler.

    When the failure handler is invoked, the target in the context can be populated with information such as the exception, client registration, and error. The failure object in the target is a simple map, similar to the following example:

    ```json
    {
        "client_registration": "ClientRegistration name string",
        "error": {
            "realm": "optional string",
            "scope": [ "string (required by the client)", ... ],
            "error": "optional string",
            "error_description": "optional string",
            "error_uri": "optional string"
        },
        "access_token": "string",
        "id_token": "string",
        "token_type": "Bearer",
        "expires_in": "number",
        "scope": [ "optional scope string", ... ],
        "client_endpoint": "URL string",
        "exception": exception
    }
    ```

    In the failure object, the following fields are not always present. Their presence depends on when the failure occurs:

    * "access_token"

    * "id_token"

    * "token_type"

    * "expires_in"

    * "scope"

    * "client_endpoint"

      See also [Handlers](Handlers.html).

- `"loginHandler"`: *Handler [reference](preface.html#definition-reference), required if there are zero or multiple client registrations, optional if there is one client registration*

  Use this Handler when the user must choose an authorization server. When `registrations` contains only one client registration, this Handler is optional but is displayed if specified.

  Provide either the name of a Handler object defined in the heap, or an inline Handler configuration object.

  See also [Handlers](Handlers.html).

- `"registrations"`: *array of ClientRegistration [references](preface.html#definition-reference) optional*

  List of client registrations that authenticate IG to the authorization server. The list must contain all client registrations that are to be used by the client filter.

  The value represents a static client registration with an authorization server, as described in [ClientRegistration](MiscellaneousConfigurationObjects.html#ClientRegistration).

- `"metadata"`: *<[object](preface.html#definition-object)>, required for dynamic client registration and ignored otherwise*

  The values of the object are evaluated as configuration expression<[strings](preface.html#definition-string)>.

  This object holds client metadata as described in [OpenID Connect Dynamic Client Registration 1.0](https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata), and optionally a list of scopes. See that document for additional details and a full list of fields.

  This object can also hold client metadata as described in RFC 7591, [OAuth 2.0 Dynamic Client Registration Protocol](https://www.rfc-editor.org/rfc/rfc7591). See that RFC for additional details.

  The following partial list of metadata fields is not exhaustive, but includes metadata that is useful with AM as OpenID Provider:

  * `"redirect_uris"`: *array of configuration expression<[url](preface.html#definition-url)>, required*

    The array of redirection URIs to use when dynamically registering this client.

    One of the registered values **must** match the `clientEndpoint`.

  * `"client_name"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Name of the client to present to the end user.

  * `"scope"`: *\_configuration expression<[string](preface.html#definition-string)>, optional*

    Space-separated string of scopes to request of the OpenID Provider, for example:

    ```json
    "scope": "openid profile"
    ```

    This property is available for dynamic client registration with AM, or with authorization servers that support RFC 7591, *OAuth 2.0 Dynamic Client Registration Protocol*

- `"cacheExpiration"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

  Duration for which to cache user-info resources.

  IG lazily fetches user info from the OpenID provider. In other words, IG only fetches the information when a downstream Filter or Handler uses the user info. Caching allows IG to avoid repeated calls to OpenID providers when reusing the information over a short period.

  Default: 10 minutes

  Set this to disabled or zero to disable caching. When caching is disabled, user info is still lazily fetched.

- `"executor"`: *ScheduledExecutorService [reference](preface.html#definition-reference), optional*

  A [ScheduledExecutorService](MiscellaneousConfigurationObjects.html#ScheduledExecutorService) to schedule the execution of tasks, such as the eviction of entries in the OpenID Connect user information cache.

  Default: `ScheduledExecutorService`

- `"target"`: *[lvalue-expression](preface.html#definition-lvalue-expression), optional*

  An expression that yields the target object. Downstream filters and handlers can use data in the target to enrich the existing request or create a new request.

  When the `target` is `openid`, the following information can be provided in `${attributes.openid}`:

  * `access_token`: Value of the OAuth 2.0 access token

  * `scope`: Scopes associated with the OAuth 2.0 access token

  * `token_type`: Authentication token type; for example, `Bearer`

  * `expires_in`: Number of milliseconds until the OAuth 2.0 access token expires

  * `id_token`: Value of the OpenID Connect token

  * `id_token_claims`: Claims used in the OpenID Connect token

  * `client_endpoint`: URL to the client endpoint

  * `client_registration`: Client ID of the OAuth 2.0 client that enables IG to communicate as an OAuth 2.0 client with an authorization server

  * `user_info`: Profile attributes of an authenticated user; for example, `sub`, `name`, `family_name`

  Data is provided to the target as follows:

  * If the authorization process completes successfully, the AuthorizationCodeOAuth2ClientFilter injects the authorization state data into the target. In the following example, a downstream StaticRequestFilter retrieves the username and password from the target to log the user in to the sample application.

    ```json
    {
      "type": "StaticRequestFilter",
      "config": {
        "method": "POST",
        "uri": "http://app.example.com:8081/login",
        "form": {
          "username": [
            "${attributes.openid.user_info.sub}"
          ],
           "password": [
            "${attributes.openid.user_info.family_name}"
          ]
        }
      }
    }
    ```

    For information about setting up this example, see [Authenticate Automatically to the Sample Application](../gateway-guide/oidc.html#oidc-rp-login-sampleapp).

  * If the failure handler is invoked, the target can be populated with information such as the exception, client registration, and error, as described in ["failureHandler"](#failureHandler) in this reference page.

    Default: `${attributes.openid}`

    See also [Expressions](Expressions.html#Expressions).

- `"defaultLoginGoto"`: *runtime expression<[url](preface.html#definition-url)>,optional*

  After successful authentication and authorization, if the user accesses the `clientEndpoint/login` endpoint without providing a landing page URL in the `goto` parameter, the request is redirected to this URI.

  The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.

  To redirect a request to a site that does not meet the goto URL criteria, change the original URI by using a ForwardedRequestFilter.

  The result of the expression must be a string that represents a valid URI, but is not a real `java.net.URI` object. For example, it would be incorrect to use `${request.uri}`, which is not a String but a MutableUri.

  Default: return an empty page.

- `"defaultLogoutGoto"`: *runtime expression<[url](preface.html#definition-url)>,optional*

  If the user accesses the `clientEndpoint/logout` endpoint without providing a goto URL, the request is redirected to this URI.

  The goto URL must use the same scheme, host, and port as the original URI, or be a relative URI (just the path). Otherwise, the request fails with an error.

  To redirect a request to a site that does not meet the goto URL criteria, change the original URI by using a ForwardedRequestFilter.

  The result of the expression must be a string that represents a valid URI, but is not a real `java.net.URI` object. For example, it would be incorrect to use `${request.uri}`, which is not a String but a MutableUri.

  Default: return an empty page.

* `"requireHttps"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

  Whether to require that original target URI of the request (`originalUri` in [UriRouterContext](RequestsResponsesContexts.html#UriRouterContext)) uses the HTTPS scheme.

  If the request received by the web container is not using HTTPS, the request is rejected.

  Default: true.

- `"requireLogin"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

  Whether to require authentication for all incoming requests.

  Default: true.

* `"issuerRepository"`: *Issuer repository [reference](preface.html#definition-reference), optional*

  A repository of OAuth 2.0 issuers, built from discovered issuers and the IG configuration.

  Provide the name of an IssuerRepository object defined in the heap.

  Default: Look up an issuer repository named `IssuerRepository` in the heap. If none is explicitly defined, then a default one named `IssuerRepository` is created in the current route.

  See also [IssuerRepository](MiscellaneousConfigurationObjects.html#IssuerRepository).

- `"discoveryHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Use this property for discovery and dynamic registration of OpenID Connect clients.

  Provide either the name of a Handler object defined in the heap, or an inline Handler configuration object. Usually set this to the name of a ClientHandler configured in the heap, or a chain that ends in a ClientHandler.

  Default: The default ClientHandler.

  See also [Handlers](Handlers.html), [ClientHandler](Handlers.html#ClientHandler).

- `"discoverySecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required for discovery and dynamic registration*

  Use this property for discovery and dynamic registration of OAuth 2.0 clients.

  Specifies the secret ID of the secret that is used to sign a JWT before the JWT is sent to the authorization server.

  If `discoverySecretId` is used, then the `tokenEndpointAuthMethod` is always `private_key_jwt`.

- `"tokenEndpointAuthMethod"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

  Use this property for discovery and dynamic registration of OAuth 2.0 clients.

  The authentication method with which a client authenticates to the authorization server or OpenID provider at the token endpoint. For information about client authentication methods, see [OpenID Client Authentication](http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication). The following client authentication methods are allowed:

  * `client_secret_basic`: Clients that have received a `client_secret` value from the authorization server authenticate with the authorization server by using HTTP basic access authentication, as in the following example:

    ```http
    POST /oauth2/token HTTP/1.1
    Host: as.example.com
    Authorization: Basic ....
    Content-Type: application/x-www-form-urlencoded

    grant_type=authorization_code&
    code=...
    ```

  * `client_secret_post`: Clients that have received a `client_secret` value from the authorization server authenticate with the authorization server by including the client credentials in the request body, as in the following example:

    ```http
    POST /oauth2/token HTTP/1.1
    Host: as.example.com
    Content-Type: application/x-www-form-urlencoded

    grant_type=authorization_code&;
    client_id=...&
    client_secret=...&
    code=...
    ```

  * `private_key_jwt`: Clients send a signed JSON Web Token (JWT) to the authorization server. IG builds and signs the JWT, and prepares the request as in the following example:

    ```http
    POST /token HTTP/1.1
    Host: as.example.com
    Content-Type: application/x-www-form-urlencoded

    grant_type=authorization_code&
    code=...&
    client_id=<clientregistration_id>&
    client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
    client_assertion=PHNhbWxwOl ... ZT
    ```

    If the authorization server doesn't support `private_key_jwt`, a dynamic registration falls back on the method returned by the authorization server, for example, `client_secret_basic` or `client_secret_post`.

    If `tokenEndpointAuthSigningAlg` is not configured, the `RS256` signing algorithm is used for `private_key_jwt`.

    Consider these points for identity providers:

    * Some providers accept more than one authentication method.

    * If a provider strictly enforces how the client must authenticate, align the authentication method with the provider.

    * If a provider doesn't support the authentication method, the provider sends an HTTP 400 Bad Request response with an `invalid_client` error message, according to [RFC 6749: Error Response](https://www.rfc-editor.org/rfc/rfc6749#section-5.2).

    * If the authentication method is invalid, the provider sends an `IllegalArgumentException`.

  Default: If `discoverySecretId` is used, then the `tokenEndpointAuthMethod` is always `private_key_jwt`. Otherwise, it is `client_secret_basic`.

- `"tokenEndpointAuthSigningAlg"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The JSON Web Algorithm (JWA) used to sign the JWT that is used to authenticate the client at the token endpoint. The property is used when `private_key_jwt` is used for authentication.

  If the authorization server sends a notification to use a different algorithm to sign the JWT, that algorithm is used.

  Default: If `discoverySecretId` is used, then the `tokenEndpointAuthSigningAlg` is `RS256`. Otherwise, it is not used.

* `"oAuth2SessionKey"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  A key to identify an OAuth 2.0 session. The key can be any character string.

  To share the same OAuth 2.O session when a user accesses different applications protected by IG, use the same key in each filter.

  Default: The complete client endpoint URI. AuthorizationCodeOAuth2ClientFilters do not share OAuth 2.O sessions.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

### Examples

For examples, see the following sections:

* [Use AM As a single OpenID connect provider](../gateway-guide/oidc.html#oidc-am)

* [Use multiple OpenID Connect providers](../gateway-guide/oidc.html#oidc-nascar)

* [Discover and dynamically register with OpenID connect providers](../gateway-guide/oidc.html#oidc-discovery)

### More information

[org.forgerock.openig.filter.oauth2.client.OAuth2ClientFilter](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/client/OAuth2ClientFilter.html)

[Issuer](MiscellaneousConfigurationObjects.html#Issuer)

[ClientRegistration](MiscellaneousConfigurationObjects.html#ClientRegistration)

[The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)

[The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750)

[OpenID Connect](http://openid.net/connect) site, in particular the list of standard OpenID Connect 1.0 [scope values](https://openid.net/specs/openid-connect-basic-1_0.html#Scopes).

## CapturedUserPasswordFilter

Makes an AM password available to IG in the following steps:

* Checks for the presence of the SessionInfoContext context, at `${contexts.amSession}`.

  * If the context is not present, or if `sunIdentityUserPassword` is `null`, the CapturedUserPasswordFilter collects session info and properties from AM.

  * If the context is present and `sunIdentityUserPassword` is not `null`, the CapturedUserPasswordFilter uses that value for the password.

* The CapturedUserPasswordFilter decrypts the password and stores it in the CapturedUserPasswordContext, at `${contexts.capturedPassword}`.

### Usage

```json
{
  "name": string,
   "type": "CapturedUserPasswordFilter",
   "config": {
     "amService": AmService reference,
     "keySecretId": configuration expression<secret-id>,
     "keyType": configuration expression<string>,
     "secretsProvider": SecretsProvider reference,
     "ssoToken": runtime expression<string>,
     "key": configuration expression<string> //deprecated
   }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  The AmService heap object to use for the password. See also, [AmService](MiscellaneousConfigurationObjects.html#AmService).

* `"keySecretId"`: *configuration expression<[secret-id](preface.html#definition-enumeration)>, required*

  The secret ID for the key required decrypt the AM password.

* `"keyType"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

  Algorithm to decrypt the AM password. Use one of the following values:

  * `AES` AES for JWT-based AES_128_CBC_HMAC_SHA_256 encryption. For more information, see [AES_128_CBC_HMAC_SHA_256](https://www.rfc-editor.org/rfc/rfc7518#section-5.2.3) in the IETF *JSON Web Algorithms*.

  * `DES` for DES/ECB/NoPadding

    |   |                                                                                                                                                  |
    | - | ------------------------------------------------------------------------------------------------------------------------------------------------ |
    |   | This value is deprecated, and considered unsecure. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

- `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), optional*

  The SecretsProvider object to query for the JWT session signing or encryption keys. For more information, see [SecretsProvider](secrets.html#SecretsProvider).

  Default: The route's default secret service. For more information, see [Default secrets object](secrets.html#default-secrets-object).

- `"ssoToken"`: *runtime expression<[string](preface.html#definition-string)>, required*

  Location of the AM SSO token.

  Default: `${request.cookiesAmService-ssoTokenHeader'][0].value}`, where `AmService-ssoTokenHeader` is the name of the header or cookie where the AmService expects to find SSO tokens.

- `"key"`: *configuration expression\<string>, required*

  |   |                                                                                                                                                                                    |
  | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | This property is deprecated and is not considered secure. Use `keySecretId` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  Base64 encoded key value to decrypt the AM password.

### Examples

The following example route is used to get login credentials from AM in [Get login credentials from AM](../gateway-guide/credentials-am.html).

```json
{
  "name": "04-replay",
  "condition": "${find(request.uri.path, '^/replay')}",
  "heap": [
    {
      "name": "SystemAndEnvSecretStore-1",
      "type": "SystemAndEnvSecretStore"
    },
    {
      "name": "AmService-1",
      "type": "AmService",
      "config": {
        "agent": {
          "username": "ig_agent",
          "passwordSecretId": "agent.secret.id"
        },
        "secretsProvider": "SystemAndEnvSecretStore-1",
        "url": "http://am.example.com:8088/openam/"
      }
    },
    {
      "name": "CapturedUserPasswordFilter",
      "type": "CapturedUserPasswordFilter",
      "config": {
        "ssoToken": "${contexts.ssoToken.value}",
        "keySecretId": "aes.key",
        "keyType": "AES",
        "secretsProvider": "SystemAndEnvSecretStore-1",
        "amService": "AmService-1"
      }
    }
  ],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "SingleSignOnFilter",
          "config": {
            "amService": "AmService-1"
          }
        },
        {
          "type": "PasswordReplayFilter",
          "config": {
            "loginPage": "${true}",
            "credentials": "CapturedUserPasswordFilter",
            "request": {
              "method": "POST",
              "uri": "http://app.example.com:8081/login",
              "form": {
                "username": [
                  "${contexts.ssoToken.info.uid}"
                ],
                "password": [
                  "${contexts.capturedPassword.value}"
                ]
              }
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  }
}
```

### More information

[org.forgerock.openig.openam.CapturedUserPasswordFilter](../_attachments/apidocs/org/forgerock/openig/openam/CapturedUserPasswordFilter.html)

[org.forgerock.openig.openam.CapturedUserPasswordContext](../_attachments/apidocs/org/forgerock/openig/openam/CapturedUserPasswordContext.html)

[CapturedUserPasswordContext](RequestsResponsesContexts.html#CapturedUserPasswordContext)

[SessionInfoFilter](#SessionInfoFilter)

## CertificateThumbprintFilter

Extracts a Java certificate from a trusted header or from a TLS connection, computes the SHA-256 thumbprint of that certificate, and makes the thumbprint available for the ConfirmationKeyVerifierAccessTokenResolver. Use this filter to enable verification of certificate-bound access tokens.

CertificateThumbprintFilter computes and makes available the SHA-256 thumbprint of a client certificate as follows:

* Evaluates a runtime expression and yields a `java.security.cert.Certificate`

* Hashes the certificate using SHA-256

* Base64url-encodes the result

* Stores the result in the contexts chain

The runtime expression can access or build a client certificate from any information present at runtime, such as a PEM in a header, or a pre-built certificate.

Use CertificateThumbprintFilter with ConfirmationKeyVerifierAccessTokenResolver when the IG instance is behind the TLS termination point, for example, when IG is running behind a load balancer or other ingress point.

### Usage

```json
{
  "name": string,
  "type": "CertificateThumbprintFilter",
  "config": {
    "certificate": runtime expression<certificate>,
    "failureHandler": Handler reference,
  }
}
```

### Properties

* `"certificate"`: *runtime expression<[certificate](preface.html#definition-certificate)>, required*

  An EL expression which, when evaluated, yields an instance of a `java.security.cert.Certificate`.

  Use the following [Functions](Expressions.html#Functions) in the expression to define hash, decoding, and certificate format:

  * `digestSha256`, to calculate the SHA-256 hash of the certificate.

  * `decodeBase64url`, to decode an incoming base64url-encoded string.

  * `pemCertificate`, to convert a PEM representation string into a certificate.

  See [Examples](#CertificateThumbprintFilter-examples).

- `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request on failure.

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 403 Forbidden, the request stops being executed.

### Examples

The following example use the certificate associated with the incoming HTTP connection:

```json
{
  "name": "CertificateThumbprintFilter-1",
  "type": "CertificateThumbprintFilter",
  "config": {
    "certificate": "${contexts.client.certificates[0]}"
  }
}
```

The following example is adapted for a deployment with NGINX as the TLS termination, where NGINX fronts IG. NGINX provides the client certificate associated with its own incoming connection in the `x-ssl-client-cert` header. The certificate is encoded as PEM, and then url-encoded:

```json
{
  "name": "CertificateThumbprintFilter-2",
  "type": "CertificateThumbprintFilter",
  "config": {
    "certificate": "${pemCertificate(urlDecode(request.headers['x-ssl-client-cert'][0]))}"
  }
}
```

### More information

[org.forgerock.openig.filter.oauth2.cnf.CertificateThumbprintFilter](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/cnf/CertificateThumbprintFilter.html)

## CircuitBreakerFilter

Monitors failures. When the number of failures reaches a configured failure threshold, the circuit breaker trips, and the circuit is considered *open*. Calls to downstream filters are stopped, and a runtime exception is returned.

After a configured delay, the circuit breaker is reset, and is the circuit considered *closed*. Calls to downstream filters are restored.

### Usage

```json
{
  "name": string,
  "type": "CircuitBreakerFilter",
  "config": {
    "maxFailures":  configuration expression<integer>,
    "openDuration": configuration expression<duration>,
    "openHandler": Handler reference,
    "slidingCounter": object,
    "executor":  ScheduledExecutorService reference
  }
}
```

### Properties

* `"maxFailures"`: *configuration expression<[number](preface.html#definition-number)>, required*

  The maximum number of failed requests allowed in the window given by `size`, before the circuit breaker trips. The value must be greater than zero.

* `"openDuration"`: *configuration expression<[duration](preface.html#definition-duration)>, required*

  The duration for which the circuit stays open after the circuit breaker trips. The `executor` schedules the circuit to be closed after this duration.

* `"openHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  The [Handler](Handlers.html) to call when the circuit is open.

  Default: A handler that throws a RuntimeException with a "circuit-breaker open" message.

* `"slidingCounter"`: *[object](preface.html#definition-object), optional*

  A sliding window error counter. The circuit breaker trips when the number of failed requests in the number of requests given by `size` reaches `maxFailures`.

  The following image illustrates how the sliding window counts failed requests:

  ![Example sliding window error counter.](_images/sliding-window.svg)

  ```json
  {
    "slidingCounter":  {
      "size": configuration expression<number>
    }
  }
  ```

  * `"size"`: *configuration expression<[number](preface.html#definition-number)>, required*

    The size of the sliding window in which to count errors.

    The value of `size` must be greater than zero, and greater than the value of `maxFailures`, otherwise an exception is thrown.

* `"executor"`: *ScheduledExecutorService [reference](preface.html#definition-reference), optional*

  A [ScheduledExecutorService](MiscellaneousConfigurationObjects.html#ScheduledExecutorService) to schedule closure of the circuit after the duration given by `openDuration`.

  Default: The default ScheduledExecutorService in the heap

### Example

In the following example, the circuit breaker opens after 11 failures in the previous 100 requests, throwing a runtime exception with a "circuit-breaker open" message. The default ScheduledExecutorService in the heap closes the circuit-breaker after 10 seconds.

```json
{
  "type": "CircuitBreakerFilter",
  "config": {
    "maxFailures": 10,
    "openDuration": "10 seconds",
    "openHandler": {
      "type": "StaticResponseHandler",
      "config": {
        "status": 500,
        "headers": {
          "Content-Type": [ "text/plain" ]
        },
        "entity": "Too many failures; circuit opened to protect downstream services."
      }
    },
    "slidingCounter": {
      "size": 100
    }
  }
}
```

### More information

[org.forgerock.openig.filter.circuitbreaker.CircuitBreakerFilter](../_attachments/apidocs/org/forgerock/openig/filter/circuitbreaker/CircuitBreakerFilter.html)

## ClientCredentialsOAuth2ClientFilter

Authenticates OAuth 2.0 clients by using the client's OAuth 2.0 credentials to obtain an access token from an authorization server, and injecting the access token into the inbound request as a Bearer Authorization header. The access token is valid for the configured scopes.

The ClientCredentialsOAuth2ClientFilter obtains the client's access token by using the `client_credentials` grant type. Client authentication is provided by the `endpointHandler` property, which uses a client authentication filter, such as [ClientSecretBasicAuthenticationFilter](#ClientSecretBasicAuthenticationFilter). The filter refreshes the access token as required.

Use the ClientCredentialsOAuth2ClientFilter in a service-to-service context, where services need to access resources protected by OAuth 2.0.

### Usage

```json
{
  "name": string,
  "type": "ClientCredentialsOAuth2ClientFilter",
  "config": {
    "secretsProvider": SecretsProvider reference,
    "tokenEndpoint": configuration expression<url>,
    "scopes": [ configuration expression<string>, ... ],
    "endpointHandler": Handler reference,
    "clientId": configuration expression<sting>, //deprecated
    "clientSecretId": configuration expression<secret-id>, //deprecated
    "handler": Handler reference //deprecated
  }
}
```

### Properties

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

- `"tokenEndpoint"`: *configuration expression<[url](preface.html#definition-url)>, required*

  The URL to the authorization server's OAuth 2.0 token endpoint.

- `"scopes"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  Array of scope strings to request from the authorization server.

  Default: Empty, request no scopes.

- `"endpointHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  The Handler to exchange tokens on the authorization endpoint.

  Configure this property as a [Chain](Handlers.html#Chain), using one of the following client authentication filters:

  * [ClientSecretBasicAuthenticationFilter](#ClientSecretBasicAuthenticationFilter)

  * [ClientSecretPostAuthenticationFilter](#ClientSecretPostAuthenticationFilter)

  * [PrivateKeyJwtClientAuthenticationFilter](#PrivateKeyJwtClientAuthenticationFilter)

  ```json
  {
    "name": "myHandler",
    "type": "Chain",
    "config": {
      "handler": "ForgeRockClientHandler",
      "filters": [
        {
          "type": "ClientSecretBasicAuthenticationFilter",
          "config": {
            "clientId": "myConfidentialClient",
            "clientSecretId": "my.client.secret.id",
            "secretsProvider" : "mySystemAndEnvSecretStore",
          }
        }
      ]
    }
  }
  ```

  Default: ForgeRockClientHandler

- `"clientId"`: *configuration expression\<string>, required*

  |   |                                                                                                                                                           |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | This property is deprecated. Use `endpointHandler` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The ID of the OAuth 2.0 client registered with the authorization server.

  If you use the deprecated properties, provide `clientId`, `clientSecretId` to obtain the client secret, which authenticates using the `client_secret_basic` method.

- `"clientSecretId"`: *configuration expression\<secret-id>, required*

  |   |                                                                                                                                                           |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | This property is deprecated. Use `endpointHandler` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The ID to use when querying the `secretsProvider` for the client secret.

- `"handler"`: *Handler reference or inline Handler declaration, optional*

  |   |                                                                                                                                                           |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | This property is deprecated. Use `endpointHandler` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The Handler to use to access the authorization server's OAuth 2.0 token endpoint. Provide either the name of a handler object defined in the heap, or specify a handler object inline.

  Default: ClientHandler

### Examples

For an example, refer to [Using OAuth 2.0 client credentials](../gateway-guide/oauth2-clientcredentials.html).

### More information

[org.forgerock.openig.filter.oauth2.client.ClientCredentialsOAuth2ClientFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/client/ClientCredentialsOAuth2ClientFilterHeaplet.html)

[org.forgerock.openig.filter.oauth2.OAuth2ResourceServerFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/OAuth2ResourceServerFilterHeaplet.html)

[OAuth2ResourceServerFilter](#OAuth2ResourceServerFilter)

[The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)

[The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750)

## ClientSecretBasicAuthenticationFilter

Supports client authentication with the method `client_secret_basic`. Clients that have received a `client_secret` value from the authorization server authenticate through the HTTP basic access authentication scheme, as in the following example:

```http
POST /oauth2/token HTTP/1.1
Host: as.example.com
Authorization: Basic ....
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=...
```

Use this filter with an endpoint `Handler` that requires `client_secret_basic` authentication. For example, `endpointHandler` in the [OAuth2TokenExchangeFilter](#OAuth2TokenExchangeFilter) or [ClientCredentialsOAuth2ClientFilter](#ClientCredentialsOAuth2ClientFilter).

### Usage

```json
{
  "name": string,
  "type": "ClientSecretBasicAuthenticationFilter",
  "config": {
    "clientId": configuration expression<string>,
    "clientSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference
  }
}
```

### Configuration

* `"clientId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The OAuth 2.0 client ID to use for authentication.

* `"clientSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required*

  The OAuth 2.0 client secret to use for authentication.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

### Example

```json
{
  "name": "ExchangeHandler",
  "type": "Chain",
  "config": {
    "handler": "ForgeRockClientHandler",
    "filters": [
      {
        "type": "ClientSecretBasicAuthenticationFilter",
        "config": {
          "clientId": "serviceConfidentialClient",
          "clientSecretId": "client.secret.id",
          "secretsProvider" : "SystemAndEnvSecretStore-1"
        }
      }
    ]
  }
}
```

## ClientSecretPostAuthenticationFilter

Supports client authentication with the method `client_secret_post`. Clients that have received a `client_secret` value from the authorization server authenticate by including the client credentials in the request body, as in the following example:

```http
POST /oauth2/token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&;
client_id=...&
client_secret=...&
code=...
```

Use this filter with an endpoint `Handler` that requires `client_secret_post` authentication. For example, `endpointHandler` in the [OAuth2TokenExchangeFilter](#OAuth2TokenExchangeFilter) or [ClientCredentialsOAuth2ClientFilter](#ClientCredentialsOAuth2ClientFilter).

### Usage

```json
{
  "name": string,
  "type": "ClientSecretPostAuthenticationFilter",
  "config": {
    "clientId": configuration expression<string>,
    "clientSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference
  }
}
```

### Configuration

* `"clientId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The OAuth 2.0 client ID to use for authentication.

* `"clientSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required*

  The OAuth 2.0 client secret to use for authentication.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

## ConditionalFilter

Verifies that a specified condition is met. If the condition is met, the request is dispatched to a delegate Filter. Otherwise, the delegate Filter is skipped.

Use `ConditionalFilter` to easily use or skip a Filter depending on whether a condition is met. To easily use or skip a set of Filters, use a `ChainOfFilters` as the delegate Filter and define a set of Filters. For information, see [ChainOfFilters](#ChainOfFilters).

### Usage

```json
{
    "name": string,
    "type": "ConditionalFilter",
    "config": {
        "condition": runtime expression<boolean>,
        "delegate": Filter reference
   }
}
```

### Properties

* `"condition"`: *runtime expression<[boolean](preface.html#definition-boolean)>, required*

  If the expression evaluates to `true`, the request is dispatched to the delegate Filter. Otherwise the delegate Filter is skipped.

* `"delegate"`: *Filter [reference](preface.html#definition-reference), required*

  Filter to treat the request when the condition expression evaluates as `true`.

  See also [Filters](#).

### Example

The following example tests whether a request finishes with `.js` or `.jpg`:

```json
{
  "type": "Chain",
  "config": {
    "filters": [{
      "type": "ConditionalFilter",
      "config": {
        "condition": "${not (find(request.uri.path, '.js$') or find(request.uri.path, '.jpg$'))}",
        "delegate": "mySingleSignOnFilter"
      }
    }],
    "handler": "ReverseProxyHandler"
  }
}
```

If the request is to access a .js file or .jpg file, it skips the delegate SingleSignOnFilter filter declared in the heap, and passes straight to the ReverseProxyHandler.

If the request is to access another type of resource, it must pass through the delegate SingleSignOnFilter for authentication with AM before it can pass to the ReverseProxyHandler.

### More information

[org.forgerock.openig.filter.ConditionalFilter](../_attachments/apidocs/org/forgerock/openig/filter/ConditionalFilter.html)

## ConditionEnforcementFilter

Verifies that a specified condition is met. If the condition is met, the request continues to be executed. Otherwise, the request is referred to a failure handler, or IG returns 403 Forbidden and the request is stopped.

### Usage

```json
{
    "name": string,
    "type": "ConditionEnforcementFilter",
    "config": {
        "condition": runtime expression<boolean>,
        "failureHandler": Handler reference
    }
}
```

### Properties

* `"condition"`: *runtime expression<[boolean](preface.html#definition-boolean)>, required*

  If the expression evaluates to `true`, the request continues to be executed.

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request if the condition expression evaluates as `false`.

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 403 Forbidden, the request stops being executed.

### Example

The following example tests whether a request contains a session username. If it does, the request continues to be executed. Otherwise, the request is dispatched to the `ConditionFailedHandler` failure handler.

```json
{
    "name": "UsernameEnforcementFilter",
    "type": "ConditionEnforcementFilter",
    "config": {
        "condition": "${not empty (session.username)}",
        "failureHandler": "ConditionFailedHandler"
    }
}
```

### More information

[org.forgerock.openig.filter.ConditionEnforcementFilter](../_attachments/apidocs/org/forgerock/openig/filter/ConditionEnforcementFilter.html)

## ChainOfFilters

Dispatches a request to an ordered list of filters. Use this filter to assemble a list of filters into a single filter that you can then use in different places in the configuration.

A ChainOfFilters can be placed in a configuration anywhere that a filter can be placed.

Unlike `Chain`, `ChainOfFilters` does not finish by dispatching the request to a handler. For more information, see [Chain](Handlers.html#Chain).

### Usage

```json
{
    "name": string,
    "type": "ChainOfFilters",
    "config": {
        "filters": [ Filter reference, ... ]
    }
}
```

### Properties

* `"filters"`: *array of Filter [references](preface.html#definition-reference), required*

  An array of names of filter objects defined in the heap, and inline filter configuration objects.

  The chain dispatches the request to these filters in the order they appear in the array.

  See also [Filters](#).

### Example

```json
{
    "name": "MyChainOfFilters",
    "type": "ChainOfFilters",
    "config": {
        "filters": [ "Filter1", "Filter2" ]
   }
}
```

### More information

[org.forgerock.openig.filter.ChainFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/ChainFilterHeaplet.html)

## CookieFilter

Manages, suppresses, and relays cookies as follows:

* **Manage**, to store cookies from the protected application in the IG session, and include them in later requests.

  For requests with a `Cookie` header, managed cookies are removed so that protected applications don't see them.

  For responses with a `Set-Cookie` header, managed cookies are removed and then added in a `Cookie` header to the next request that goes through that filter.

  Manage is the default action, and a common choice to manage cookies originating from the protected application.

* **Suppress**, to remove cookies from the request and response. Use this option to hide domain cookies, such as the AM session cookie, that are used by IG but are not usually used by protected applications.

* **Relay**, to transmit cookies freely from the user agent to the remote server, and vice versa.

If a cookie does not appear in one of the three action parameters, then the default action is performed, controlled by setting the `defaultAction` parameter. If unspecified, the default action is to manage all cookies. In the event a cookie appears in more than one configuration parameter, then it will be selected in the order of precedence: managed, suppressed, relayed.

### Usage

```json
{
     "name": string,
     "type": "CookieFilter",
     "config": {
         "managed": [ configuration expression<string>, ... ],
         "suppressed": [ configuration expression<string>, ... ],
         "relayed": [ configuration expression<string>, ... ],
         "defaultAction": configuration expression<enumeration>
     }
}
```

### Properties

* `"managed"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  A list of the names of cookies to be managed.

* `"suppressed"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  A list of the names of cookies to be suppressed.

* `"relayed"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  A list of the names of cookies to be relayed.

* `"defaultAction"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

  Action to perform for cookies that do not match an action set. Set to `"MANAGE"`, `"RELAY"`, or `"SUPPRESS"`. Default: `"MANAGE"`.

### More information

[org.forgerock.openig.filter.CookieFilter](../_attachments/apidocs/org/forgerock/openig/filter/CookieFilter.html)

## CorsFilter

Configures policies for cross-origin resource sharing (CORS), to allow cross-domain requests from user agents.

### Usage

```json
{
   "name": string,
   "type": "CorsFilter",
   "config": {
     "policies": [ object, ... ],
     "failureHandler": Handler reference
   }
}
```

### Properties

* `"policies"`: *array of [objects](preface.html#definition-object), required*

  One or more policies to apply to the request. A policy is selected when the origin of the request matches the accepted `origins` of the policy.

  When multiple policies are declared, they are tried in the order that they are declared, and the first matching policy is selected.

  ```json
  {
    "acceptedOrigins": [ configuration expression<url>, ... ] or "*",
    "acceptedMethods": [ configuration expression<string>, ... ] or "*",
    "acceptedHeaders": [ configuration expression<string>, ... ] or "*",
    "exposedHeaders": [ configuration expression<string>, ... ],
    "maxAge": configuration expression<duration>,
    "allowCredentials": configuration expression<boolean>,
    "origins": [ configuration expression<url>, ... ] or "*" //deprecated
  }
  ```

  * `"acceptedOrigins"`: *array of configuration expression<[urls](preface.html#definition-url)> or `"*"`, required*

    A comma-separated list of *origins*, to match the origin of the CORS request. Alternatively, use `*` to allow requests from any URL.

    If the request origin is not in the list of accepted origins, the failure handler is invoked or an HTTP 403 Forbidden is returned, and the request stops being executed.

    Origins are URLs with a scheme, hostname, and optionally a port number, for example, `http://www.example.com`. If a port number is not defined, origins with no port number or with the default port number (80 for HTTP, 443 for HTTPS) are accepted.

    Examples:

    ```json
    {
      "acceptedOrigins": [
        "http://www.example.com",
        "https://example.org:8433"
      ]
    }
    ```

    ```json
    {
      "acceptedOrigins": "*"
    }
    ```

  * `"acceptedMethods"`: *array of configuration expression<[strings](preface.html#definition-string)> or `"*"`, optional*

    A comma-separated list of case-sensitive HTTP method names that are allowed when making CORS requests. Alternatively, use `*` to allow requests with any method.

    In preflight requests, browsers use the `Access-Control-Request-Method` header to let the server know which HTTP method might be used in the actual request.

    * If all requested methods are allowed, the requested methods are returned in the preflight response, in the `Access-Control-Allow-Methods` header.

    * If any requested method is not allowed, the `Access-Control-Allow-Methods` header is omitted. The failure handler is not invoked, but the user-agent interprets the preflight response as a CORS failure.

    Examples:

    ```json
    {
      "acceptedMethods": [
        "GET",
        "POST",
        "PUT",
        "MyCustomMethod"
      ]
    }
    ```

    ```json
    {
      "acceptedMethods": "*"
    }
    ```

    Default: All methods are rejected.

  * `"acceptedHeaders"`: *array of configuration expression<[strings](preface.html#definition-string)> or `"*"`, optional*

    A comma-separated list of case-insensitive request header names that are allowed when making CORS requests. Alternatively, use `*` to allow requests with any header.

    In preflight requests, browsers use the `Access-Control-Request-Headers` header to let the server know which HTTP headers might be used in the actual request.

    * If all requested headers are allowed, the requested headers are returned in the preflight response, in the `Access-Control-Allow-Headers` header.

    * If any requested header is not allowed, the `Access-Control-Allow-Headers` header is omitted. The failure handler is not invoked, but the user-agent interprets the preflight response as a CORS failure.

    Examples:

    ```json
    {
      "acceptedHeaders": [
        "iPlanetDirectoryPro",
        "X-OpenAM-Username",
        "X-OpenAM-Password",
        "Accept-API-Version",
        "Content-Type",
        "If-Match",
        "If-None-Match"
      ]
    }
    ```

    ```json
    {
      "acceptedHeaders": "*"
    }
    ```

    Default: All requested headers are rejected.

  * `"exposedHeaders"`: *list of configuration expression<[string](preface.html#definition-string)>, optional*

    A comma-separated list of case-insensitive response header names that are returned in the `Access-Control-Expose-Headers` header.

    Only headers in this list, safe headers, and the following simple response headers are exposed to frontend JavaScript code:

    * `Cache-Control`

    * `Content-Language`

    * `Expires`

    * `Last-Modified`

    * `Pragma`

    * `Content-Type`

    Example:

    ```json
    {
      "exposedHeaders": [
        "Access-Control-Allow-Origin",
        "Access-Control-Allow-Credentials",
        "Set-Cookie"
      ]
    }
    ```

  Default: No headers are exposed.

  * `"maxAge"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

    The maximum duration for which a browser is allowed to cache a preflight response. The value is included in the `Access-Control-Max-Age` header of preflight responses.

    When this `maxAge` is greater than the browser's maximum internal value, the browser value takes precedence.

    Default: 5 seconds

  * `"allowCredentials"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    A flag to allow requests that use credentials, such as cookies, authorization headers, or TLS client certificates.

    Set to `true` to set the `Access-Control-Allow-Credentials` header to `true`, and allow browsers to expose the response to frontend JavaScript code.

    Default: False

  * `"origins"`: *list of configuration expression\<url> or "\*", required*

    |   |                                                                                                                                                           |
    | - | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
    |   | This property is deprecated; use `acceptedOrigins` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

    A comma-separated list of origins, to match the origin of the CORS request. Alternatively, use `*` to allow requests from any URL.

    Origins are URLs with a scheme, hostname, and optionally a port number, for example, `http://www.example.com`. If a port number is not defined, origins with no port number or with the default port number (80 for HTTP, 443 for HTTPS) are accepted.

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler invoked during the preflight request, when the request origin does not match any of the `acceptedOrigins` defined in `policies`.

  The failure handler is not invoked when requested headers or requested methods are not allowed.

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 403 Forbidden, the request stops being executed.

### More information

[org.forgerock.http.filter.cors.CorsFilter](../_attachments/apidocs/org/forgerock/http/filter/cors/CorsFilter.html)

<https://fetch.spec.whatwg.org/#http-cors-protocol>

## CrossDomainSingleSignOnFilter

When IG and AM are running in the same domain, the SingleSignOnFilter can be used for SSO. When IG and AM are running in different domains, AM cookies are not visible to IG because of the same-origin policy. The CrossDomainSingleSignOnFilter provides a mechanism to push tokens issued by AM to IG running in a different domain.

When this filter processes a request, it injects the CDSSO token, the session user ID, and the full claims set into the [CdSsoContext](RequestsResponsesContexts.html#CdSsoContext). Should an error occur during authentication, the error details are captured in a [CdSsoFailureContext](RequestsResponsesContexts.html#CdSsoFailureContext).

For an example of how to configure CDSSO in AM and IG, and information about the flow of data between AM, IG, and a protected application, see [Authenticate with CDSSO](../gateway-guide/sso.html#cdsso-auth).

### WebSocket notifications for sessions

When WebSocket notifications are set up for sessions, IG receives a notification from AM when a user logs out of AM, or when the AM session is modified, closed, or times out. IG then evicts entries that are related to the event from the `sessionCache`.

For information about setting up WebSocket notifications, using them to clear the session cache, and including them in the server logs, see [WebSocket notifications](../maintenance-guide/tuning.html#amservice-websocket).

### Usage

```json
{
  "name": string,
  "type": "CrossDomainSingleSignOnFilter",
  "config": {
    "amService": AmService reference,
    "redirectEndpoint": configuration expression<url>,
    "authenticationService": configuration expression<string>,
    "authCookie": object,
    "defaultLogoutLandingPage": configuration expression<url>,
    "logoutExpression": runtime expression<boolean>,
    "failureHandler": Handler reference,
    "verificationSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference
  }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  The AmService heap object to use. See [AmService](MiscellaneousConfigurationObjects.html#AmService).

* `"redirectEndpoint"`: *configuration expression<[url](preface.html#definition-url)>, required*

  The URI to which AM redirects the browser with the authentication token or an authentication error. The filter checks that the authentication was initiated by IG.

  Configure this URI to be the same as that in AM.

  To make sure that the redirect is routed back to the CrossDomainSingleSignOnFilter, include the endpoint in the route condition in one of the following ways:

  * As a sub-path of the condition path.

    For example, use the following route condition with the following endpoint:

    ```json
    "condition": "${find(request.uri.path, '^/home/cdsso')}"
    ```

    ```json
    "redirectEndpoint": "/home/cdsso/callback"
    ```

  * To match the route condition.

    For example, use the following route condition with the following endpoint:

    ```json
    "condition": "${find(request.uri.path, '^/home/cdsso')}"
    ```

    ```json
    "redirectEndpoint": "/home/cdsso"
    ```

    With this route condition, all POST requests on the condition path are treated as AM CDSSO callbacks. Any POST requests that aren't the result of an AM CDSSO callback will fail.

  * As a specific path that is not related to the condition path.

    To make sure that the redirect is routed back to this filter, include the redirectEndpoint as a path in the filter condition.

    For example, use the following route condition with the following endpoint:

    ```json
    "condition": "${find(request.uri.path, '^/home/cdsso/redirect') || find(request.uri.path, '^/ig/cdssoRedirectUri')}"
    ```

    ```json
    "redirectEndpoint": "/ig/cdssoRedirectUri"
    ```

- `"authenticationService"`: *configuration expression<[string](preface.html#definition-string)>,optional*

  The name of an AM authentication tree or authentication chain to use for authentication.

  Default: AM's default authentication service.

  For an example that uses `authenticationService`, see [Authenticate with SSO through an AM authentication tree](../gateway-guide/sso.html#proc-sso-authservice).

  For more information about authentication trees and chains, see [Authentication nodes and trees](https://docs.pingidentity.com/pingam/7.2/authentication-guide/about-authentication-trees.html) and [Authentication modules and chains](https://docs.pingidentity.com/pingam/7.2/authentication-guide/about-authentication-modules-and-chains.html) in AM's *Authentication and SSO* guide.

* `"authCookie"`: *[object](preface.html#definition-object), optional*

  The configuration of the cookie used to store the authentication.

  ```json
  {
    "name": configuration expression<string>,
    "domain": configuration expression<string>,
    "httpOnly": configuration expression<boolean>,
    "path": configuration expression<string>,
    "sameSite": configuration expression<enumeration>,
    "secure": configuration expression<boolean>
  }
  ```

  * `"name"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Name of the cookie containing the authentication token from AM.

    For security, change the default name of cookies.

    Default: `ig-token-cookie`

  * `"domain"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Domain to which the cookie applies.

    Set a domain only if the user-agent is able to re-emit cookies on that domain on its next hop. For example, to re-emit a cookie on the domain `example.com`, the user-agent must be able to access that domain on its next hop.

    Default: The fully qualified hostname of the user-agent's next hop.

  * `"httpOnly"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Flag to mitigate the risk of client-side scripts accessing protected cookies.

    Default: `true`

  * `"path"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Path protected by this authentication.

    Set a path only if the user-agent is able to re-emit cookies on the path. For example, to re-emit a cookie on the path `/home/cdsso`, the user-agent must be able to access that path on its next hop.

    Default: The path of the request that got the `Set-Cookie` in its response.

  * `"sameSite"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

    Options to manage the circumstances in which a cookie is sent to the server. Use one of the following values to reduce the risk of CSRF attacks:

    * `STRICT`: Send the cookie only if the request was initiated from the cookie domain. Not case-sensitive.

      Use this value to reduce the risk of cross-site request forgery (CSRF) attacks.

    * `LAX`: Send the cookie only with GET requests in a first-party context, where the URL in the address bar matches the cookie domain. Not case-sensitive.

      Use this value to reduce the risk of cross-site request forgery (CSRF) attacks.

    * `NONE`: Send the cookie whenever a request is made to the cookie domain. Not case-sensitive.

      With this setting, consider setting `secure` to `true` to prevent browsers from rejecting the cookie. For more information, see [SameSite cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite).

    Default: `LAX`

  |   |                                                                                                                                                                                                                                                                                                                              |
  | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | For CDSSO, set `"sameSite":"none"` and `"secure":"true"`. For security reasons, many browsers require the connection used by the browser to be secure (HTTPS) for `"sameSite":"none"`. Therefore, if the connection used by the browser is not secure (HTTP), the browser might not supply cookies with `"sameSite":"none"`. |

  * `"secure"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Flag to limit the scope of the cookie to secure channels.

    Set this flag only if the user-agent is able to re-emit cookies over HTTPS on its next hop. For example, to re-emit a cookie with the `secure` flag, the user-agent must be connected to its next hop by HTTPS.

    Default: `false`

- `"defaultLogoutLandingPage"`: *configuration expression<[url](preface.html#definition-url)>, optional*

  The URL to which a request is redirected if `logoutExpression` is evaluated as true.

  If this property is not an absolute URL, the request is redirected to the IG domain name.

  This parameter is effective only when `logoutExpression` is specified.

  Default: None, processing continues.

* `"logoutExpression"`: *runtime expression<[boolean](preface.html#definition-boolean)>, optional*

  A flag to indicate that a logout condition is met. The condition is based on the request:

  * `true`: The AM session token for the end user is revoked. If a `defaultLogoutLandingPage` is specified, the request is redirected to that page.

  * `false`: The request continues to be processed.

    The following example expressions can be used to trigger revocation of the end user token:

  * The request URI contains `/logout`:

    ```none
    ${find(request.uri, '/logout')}
    ```

  * The request path starts with `/logout`:

    ```none
    ${find(request.uri.path, '^/logout')}
    ```

  * The request query includes the `logOff=true` query parameter:

    ```none
    ${find(request.uri.query, 'logOff=true')}
    ```

  Default: `${false}`

- `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request if an error occurs during authentication.

  If an error occurs during authentication, a [CdSsoFailureContext](RequestsResponsesContexts.html#CdSsoFailureContext) is populated with details of the error and any associated `Throwable`. This is available to the failure handler so that it can respond appropriately.

  Be aware that the failure handler does not itself play a role in user authentication. It is only invoked if there is a problem that prevents user authentication from taking place.

  A number of circumstances may cause the failure handler to be invoked, including:

  * The redirect endpoint is invalid.

  * The redirect endpoint is invoked without a valid CDSSO token.

  * The redirect endpoint is invoked inappropriately.

  * An error was reported by AM during authentication.

  If no failure handler is configured, the default failure handler is used.

  See also [Handlers](Handlers.html).

  Default: HTTP 200 OK. The response entity contains details of the error.

* `"verificationSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required to verify the signature of signed tokens*

  The secret ID for the secret to verify the signature of signed tokens.

  If configured, the token must be signed. If not configured, IG does not verify the signature.

  For information about how signatures are validated, see [Validating the signature of signed tokens](../gateway-guide/about.html#secret-valid-signature). For information about how each type of secret store resolves named secrets, see [Secrets](secrets.html).

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

### Example

In the following example from [Single sign-on and cross-domain single sign-on](../gateway-guide/sso.html), IG uses authentication from AM on a different domain to process a request:

```json
{
  "name": "cdsso",
  "baseURI": "http://app.example.com:8081",
  "condition": "${find(request.uri.path, '^/home/cdsso')}",
  "heap": [
    {
      "name": "SystemAndEnvSecretStore-1",
      "type": "SystemAndEnvSecretStore"
    },
    {
      "name": "AmService-1",
      "type": "AmService",
      "config": {
        "url": "http://am.example.com:8088/openam",
        "realm": "/",
        "version": "7.2",
        "agent": {
          "username": "ig_agent_cdsso",
          "passwordSecretId": "agent.secret.id"
        },
        "secretsProvider": "SystemAndEnvSecretStore-1",
        "sessionCache": {
          "enabled": false
        }
      }
    }
  ],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "name": "CrossDomainSingleSignOnFilter-1",
          "type": "CrossDomainSingleSignOnFilter",
          "config": {
            "redirectEndpoint": "/home/cdsso/redirect",
            "authCookie": {
              "path": "/home",
              "name": "ig-token-cookie"
            },
            "amService": "AmService-1",
            "verificationSecretId": "verify",
            "secretsProvider": {
              "type": "JwkSetSecretStore",
              "config": {
                "jwkUrl": "http://am.example.com:8088/openam/oauth2/connect/jwk_uri"
              }
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  }
}
```

### More information

[org.forgerock.openig.openam.SingleSignOnFilter](../_attachments/apidocs/org/forgerock/openig/openam/SingleSignOnFilter.html)

[CdSsoContext](RequestsResponsesContexts.html#CdSsoContext)

[CdSsoFailureContext](RequestsResponsesContexts.html#CdSsoFailureContext)

[SsoTokenContext](RequestsResponsesContexts.html#SsoTokenContext)

## CryptoHeaderFilter (deprecated)

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | This object is deprecated and is not considered secure. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html).The CryptoHeaderFilter conveys encrypted data between hosts by using insecure ECB mode ciphers. Consider using a [JwtBuilderFilter](JwtBuilderFilter.html) with a [HeaderFilter](HeaderFilter.html) for a more secure way to pass identity or other runtime information to the protected application. |

Encrypts or decrypts headers in a request or response, using a symmetric or asymmetric key. CryptoHeaderFilter supports key rotation.

### Usage

```json
{
  "name": string,
  "type": "CryptoHeaderFilter",
  "config": {
    "messageType": configuration expression<enumeration>,
    "operation": configuration expression<enumeration>,
    "keySecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference,
    "algorithm": configuration expression<string>,
    "charset": configuration expression<string>,
    "headers": [ configuration expression<string>, ... ]
  }
}
```

### Properties

* `"messageType"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

  The type of message whose headers to encrypt or decrypt.

  Must be one of: `"REQUEST"`, `"RESPONSE"`.

* `"operation"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

  Indication of whether to encrypt or decrypt.

  Must be one of: `"ENCRYPT"`, `"DECRYPT"`.

* `"keySecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required*

  The secret ID of the key to encrypt or decrypt the headers.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The SecretsProvider object to query for the key to encrypt or decrypt the headers. For more information, see [SecretsProvider](secrets.html#SecretsProvider).

* `"algorithm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The algorithm name, mode, and padding used for encryption and decryption.

  **CryptoHeaderFilter does not support EC-based encryption**. Use other cipher algorithm values given in [Java Security Standard Algorithm Names](https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html).

  Default: `AES/ECB/PKCS5Padding`

* `"charset"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The name of the charset used to encrypt or decrypt values, as described in [Class Charset](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/charset/Charset.html).

  Default: `UTF-8`

* `"headers"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  The names of header fields to encrypt or decrypt.

  Default: Empty

### Example

```json
{
  "name": "DecryptReplayPasswordFilter",
  "type": "CryptoHeaderFilter",
  "config": {
    "messageType": "REQUEST",
    "operation": "DECRYPT",
    "keySecretId": "decryption.secret.id",
    "secretsProvider": "KeyStoreSecretStore-1",
    "algorithm": "AES/ECB/PKCS5Padding",
    "headers": [ "replaypassword" ]
  }
}
```

### More information

[org.forgerock.openig.filter.CryptoHeaderFilter](../_attachments/apidocs/org/forgerock/openig/filter/CryptoHeaderFilter.html)

## CsrfFilter

Prevent Cross Site Request Forgery (CSRF) attacks when using cookie-based authentication, as follows:

* When a session is created or updated for a client, generate a CSRF token as a hash of the session cookie.

* Send the token in a response header to the client, and require the client to provide that header in subsequent requests.

* In subsequent requests, compare the provided token to the generated token.

* If the token is not provided or can't be validated, reject the request and return a valid CSRF token transparently in the response header.

  Rogue websites that attempt CSRF attacks operate in a different website domain to the targeted website. Because of same-origin policy, rogue websites can't access a response from the targeted website, and cannot, therefore, access the CSRF token.

### Usage

```json
{
  "name": string,
  "type": "CsrfFilter",
  "config": {
    "cookieName": configuration expression<string>,
    "headerName": configuration expression<string>,
    "excludeSafeMethods": configuration expression<boolean>,
    "failureHandler": Handler reference
  }
}
```

### Properties

* `"cookieName"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The name of the HTTP session cookie used to store the session ID. For example, use the following cookie names for the following processes:

  * SSO with the [SingleSignOnFilter](SingleSignOnFilter.html): Use the name of the AM HTTP session cookie, (default, `iPlanetDirectoryPro`). For information about the AM session cookie, see [Find the name of your AM session cookie](../gateway-guide/preface.html#am-session-cookie).

  * CDSSO with the [CrossDomainSingleSignOnFilter](CrossDomainSingleSignOnFilter.html): Use the name configured in `authCookie.name`.

  * OpenID Connect with the [AuthorizationCodeOAuth2ClientFilter](AuthorizationCodeOAuth2ClientFilter.html): Use the name of the IG HTTP session cookie (default, `IG_SESSIONID`). For information about the IG session cookie, see [admin.json](AdminHttpApplication.html).

  * SAML: Use the name of the IG HTTP session cookie (default, `IG_SESSIONID`). For information about the IG session cookie, see [admin.json](AdminHttpApplication.html).

* `"headerName"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The name of the header that carries the CSRF token. The same header is used to create and verify the token.

  Default: `X-CSRF-Token`

* `"excludeSafeMethods"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

  Whether to exclude GET, HEAD, and OPTION methods from CSRF testing. In most cases, these methods are assumed as safe from CSRF.

  Default: `true`

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request if the CSRF the token is not provided or can't be validated. Provide an inline handler declaration, or the name of a handler object defined in the heap.

  Although IG returns the CSRF token transparently in the response header, this handler cannot access the CSRF token.

  Default: Handler that generates `HTTP 403 Forbidden`.

### Example

For an example of how to harden protection against CSRF attacks, see [Protect against CSRF attacks](../gateway-guide/csrf.html).

```json
{
  "name": "CsrfFilter-1",
  "type": "CsrfFilter",
  "config": {
    "cookieName": "openig-jwt-session",
    "headerName": "X-CSRF-Token",
    "excludeSafeMethods": true
  }
}
```

### More information

[org.forgerock.openig.filter.CsrfFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/CsrfFilterHeaplet.html)

## DateHeaderFilter

Inserts the server date in an HTTP `Date` header on the response, if the `Date` header is not present.

### Usage

```json
{
  "type": "DateHeaderFilter"
}
```

### Properties

There are no configuration properties for this filter.

### Example

The following example includes a DateHeaderFilter in a chain:

```json
{
  "condition": "...",
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [{
          ...
        },
        {
          "type": "DateHeaderFilter"
        }
      ],
      "handler": {
        "name": "StaticResponseHandler-1",
        ...
      }
    }
  }
}
```

### More information

For information about Date format, see [RFC 7231 - Date](https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.2).

This filter is also available to support Financial-Grade API, for information, see [Financial-grade API Security Profile 1.0 - Part 1: Baseline](https://openid.net/specs/openid-financial-api-part-1-1_0.html)

[org.forgerock.openig.filter.DateHeaderFilter](../_attachments/apidocs/org/forgerock/openig/filter/DateHeaderFilter.html)

## EncryptedPrivateKeyJwtClientAuthenticationFilter

Supports client authentication with the `private_key_jwt` client-assertion, using a signed and encrypted JWT.

Clients send a signed and encrypted JWT to the authorization server. IG builds, signs and encrypts the JWT, and prepares the request as in the following example:

```http
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=...&
client_id=<clientregistration_id>&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
client_assertion=PHNhbWxwOl ... ZT
```

Use this filter with an endpoint `Handler` that requires authentication with the `private_key_jwt` client-assertion, using an encrypted JWT. For example, the `endpointHandler` handler in the [OAuth2TokenExchangeFilter](#OAuth2TokenExchangeFilter).

### Usage

```json
{
  "name": string,
  "type": "EncryptedPrivateKeyJwtClientAuthenticationFilter",
  "config": {
    "encryptionAlgorithm": configuration expression<enumeration>,
    "encryptionMethod": configuration expression<string>,
    "encryptionSecretId": configuration expression<secret-id>,
    "clientId": configuration expression<string>,
    "tokenEndpoint": configuration expression<url>,
    "secretsProvider": SecretsProvider reference,
    "signingSecretId": configuration expression<string>,
    "signingAlgorithm": configuration expression<string>,
    "jwtExpirationTimeout": configuration expression<duration>,
    "claims": map
  }
}
```

### Configuration

* `"encryptionAlgorithm"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The algorithm name used for encryption and decryption. Use algorithm names from [Java Security Standard Algorithm Names](https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#algorithmparameters-algorithms).

* `"encryptionMethod"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The algorithm method to use for encryption. Use algorithms from [RFC 7518, section-5.1](https://www.rfc-editor.org/rfc/rfc7518#section-5.1).

* `"encryptionSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required*

  The secret-id of the keys used to encrypt the JWT.

- `"clientId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The `client_id` obtained when registering with the authorization server.

- `"tokenEndpoint"`: *configuration expression<[url](preface.html#definition-url)>, required*

  The URL to the authorization server's OAuth 2.0 token endpoint.

- `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The SecretsProvider to resolve queried secrets, such as passwords and cryptographic keys. For allowed formats, see [SecretsProvider](secrets.html#SecretsProvider).

- `"signingSecretId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  Reference to the keys used to sign the JWT.

- `"signingAlgorithm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The JSON Web Algorithm (JWA) used to sign the JWT, such as:

  * `RS256`: RSA using SHA-256

  * `ES256`: ECDSA with SHA-256 and NIST standard P-256 elliptic curve

  * `ES384`: ECDSA with SHA-384 and NIST standard P-384 elliptic curve

  * `ES512`: ECDSA with SHA-512 and NIST standard P-521 elliptic curve

  Default: `RS256`

- `"jwtExpirationTimeout"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

  The duration for which the JWT is valid.

  Default: 1 minute

- `"claims"`: *[map](preface.html#definition-map), optional*

  The claims used in the authentication.

  The map can be structured as follows:

  * As a configuration expression of a map, where the evaluation is an object of type `Map<String, Object>`.

  * As a map whose key is a string, and whose values are configuration expressions.

  Default: Empty

## EntityExtractFilter

Extracts regular expression patterns from a message entity, and stores their values in a `target` object. Use this object in password replay, to find a login path or extract a nonce.

If the message `type` is `REQUEST`, the pattern is extracted before the request is handled. If the message `type` is `RESPONSE`, the pattern is extracted out of the response body.

Each pattern can have an associated template, which is applied to its match result.

For information, see [Patterns](Patterns.html).

### Usage

```json
{
    "name": string,
    "type": "EntityExtractFilter",
    "config": {
        "messageType": configuration expression<enumeration>,
        "charset": configuration expression<string>,
        "target": lvalue-expression,
        "bindings": [
            {
                "key": configuration expression<string>,
                "pattern": pattern,
                "template": pattern
            }, ...
        ]
    }
}
```

### Properties

* `"messageType"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

  The message type to extract patterns from.

  Must be `REQUEST` or `RESPONSE`.

* `"charset"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  Overrides the character set encoding specified in message.

  Default: The message encoding is used.

* `"target"`: *<[lvalue-expression](preface.html#definition-lvalue-expression)>, required*

  Expression that yields the target object that contains the extraction results.

  The bindings determine what type of object is stored in the target location.

  The object stored in the target location is a Map\<String, String>. You can then access its content with `${target.key}` or `${target['key']}`.

  See also [Expressions](Expressions.html#Expressions).

* `"key"`: *configuration expression<[string](preface.html#definition-string)>, required*

  Name of the element in the target object to contain an extraction result.

* `"pattern"`: *[pattern](preface.html#definition-pattern), required*

  The regular expression pattern to find in the entity.

  See also [Patterns](Patterns.html).

* `"template"`: *[pattern-template](preface.html#definition-pattern-template), optional*

  The template to apply to the pattern, and store in the named target element.

  Default: store the match result itself.

  See also [Patterns](Patterns.html).

### Examples

Extracts a nonce from the response, which is typically a login page, and sets its value in the attributes context to be used by the downstream filter posting the login form. The nonce value would be accessed using the following expression: `${attributes.extract.wpLoginToken}`.

The pattern finds all matches in the HTTP body of the form `wpLogintokenvalue="abc"`. Setting the template to `$1` assigns the value `abc` to `attributes.extract.wpLoginToken`:

```json
{
    "name": "WikiNoncePageExtract",
    "type": "EntityExtractFilter",
    "config": {
        "messageType": "response",
        "target": "${attributes.extract}",
        "bindings": [
            {
                "key": "wpLoginToken",
                "pattern": "wpLoginToken\"\\s.*value=\"(.*)\"",
                "template": "$1"
            }
        ]
    }
}
```

The following example reads the response looking for the AM login page. When found, it sets `isLoginPage = true` to be used in a SwitchFilter to post the login credentials:

```json
{
    "name": "FindLoginPage",
    "type": "EntityExtractFilter",
    "config": {
        "messageType": "response",
        "target": "${attributes.extract}",
        "bindings": [
            {
                "key": "isLoginPage",
                "pattern": "OpenAM\s\(Login\)",
                "template": "true"
            }
        ]
    }
}
```

### More information

[org.forgerock.openig.filter.EntityExtractFilter](../_attachments/apidocs/org/forgerock/openig/filter/EntityExtractFilter.html)

## FapiInteractionIdFilter

Tracks the interaction ID of requests, according to the [Financial-grade API (FAPI) WG](https://openid.net/wg/fapi/), as follows:

* If a FAPI header is provided in a client request, includes the interaction ID in the `x-fapi-interaction-id` property of the response header.

* If a FAPI header is not provided in the request, includes a new Universally Unique Identifier (UUID) in the `x-fapi-interaction-id` property of the response header.

* Adds the value of `x-fapi-interaction-id` to the log.

### Usage

```json
{
  "name": string,
  "type": "FapiInteractionIdFilter"
}
```

### Properties

There are no configuration properties for this filter.

### Example

The following example, based on [Validate Certificate-Bound Access Tokens](../gateway-guide/oauth2-rs.html#oauth2-rs-introspect-mtls), adds a FapiInteractionIdFilter to the end of the chain:

```json
{
  "name": "mtls",
  "condition": "${find(request.uri.path, '/mtls')}",
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [ {
          "name": "OAuth2ResourceServerFilter-1",
           ...
        },
        {
          "type": "FapiInteractionIdFilter"
        }
      ],
      "handler": {
          "name": "StaticResponseHandler-1",
          ...
      }
    }
  }
}
```

### More information

[org.forgerock.openig.filter.finance.FapiInteractionIdFilter](../_attachments/apidocs/org/forgerock/openig/filter/finance/FapiInteractionIdFilter.html)

[Financial-grade API - Part 1: Read-Only API Security Profile](https://openid.net/specs/openid-financial-api-part-1.html#protected-resources-provisions)

## FragmentFilter

Tracks the fragment part of a URI when a request triggers a login redirect.

* Before authentication, the filter captures the URI fragment information and stores it in a cookie.

* After authentication, when the request is issued again to the original URI, the filter redirects the browser to the original URI, including any URI fragment.

Use this filter with SingleSignOnFilter, CrossDomainSingleSignOnFilter, AuthorizationCodeOAuth2ClientFilter, and PolicyEnforcementFilter. This filter is not required for SAML because the final redirect is done with a DispatchHandler and a StaticResponseFilter.

### Usage

```json
{
  "name": string,
  "type": "FragmentFilter",
  "config": {
    "fragmentCaptureEndpoint": configuration expression<string>,
    "noJavaScriptMessage": configuration expression<string>,
    "cookie": object
  }
}
```

* `"fragmentCaptureEndpoint"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The IG endpoint used to capture the fragment form data.

  Configure the endpoint to match the condition of the route in which the filter is used.

* `"noJavaScriptMessage"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  A message to display on the fragment form when JavaScript is not enabled.

  Default: No message

* `"cookie"`: *[object](preface.html#definition-object), optional*

  The configuration of the cookie used to store the fragment information.

  ```json
  {
    "name": configuration expression<string>,
    "domain": configuration expression<string>,
    "httpOnly": configuration expression<boolean>,
    "path": configuration expression<string>,
    "sameSite": configuration expression<enumeration>,
    "secure": configuration expression<boolean>,
    "maxAge": configuration expression<duration>
  }
  ```

  * `"name"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Cookie name.

    Default: `ig-fragment-cookie`

  - `"domain"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Domain to which the cookie applies.

    Default: The fully qualified hostname of the IG host.

  - `"httpOnly"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Flag to mitigate the risk of client-side scripts accessing protected cookies.

    Default: `true`

  - `"path"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Path to apply to the cookie.

    Default: `/`

  - `"sameSite"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

    Options to manage the circumstances in which a cookie is sent to the server. Use one of the following values to reduce the risk of CSRF attacks:

    * `STRICT`: Send the cookie only if the request was initiated from the cookie domain. Not case-sensitive.

      Use this value to reduce the risk of cross-site request forgery (CSRF) attacks.

    * `LAX`: Send the cookie only with GET requests in a first-party context, where the URL in the address bar matches the cookie domain. Not case-sensitive.

      Use this value to reduce the risk of cross-site request forgery (CSRF) attacks.

    * `NONE`: Send the cookie whenever a request is made to the cookie domain. Not case-sensitive.

      With this setting, consider setting `secure` to `true` to prevent browsers from rejecting the cookie. For more information, see [SameSite cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite).

    Default: `LAX`

  - `"secure"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Flag to limit the scope of the cookie to secure channels.

    Default: `false`

  - `"maxAge"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

    The maximum duration for which the FragmentFilter cookie can be valid.

    When this `maxAge` is greater than the browser's maximum internal value, the browser value takes precedence.

    Default: 1 hour

### Example

For an example of how the FragmentFilter is used in an SSO flow, see [Persist URI fragments in login redirects](../gateway-guide/fragment.html).

### More information

[AuthRedirectContext](RequestsResponsesContexts.html#AuthRedirectContext)

[org.forgerock.openig.filter.FragmentFilter](../_attachments/apidocs/org/forgerock/openig/filter/FragmentFilter.html)

[URI Fragment](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment)

[RFC 3986: Fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5)

## FileAttributesFilter

Retrieves and exposes a record from a delimiter-separated file. Lookup of the record is performed using a specified `key`, whose `value` is derived from an expression. The resulting record is exposed in an object whose location is specified by the `target` expression. If a matching record cannot be found, then the resulting object is empty.

The retrieval of the record is performed lazily; it does not occur until the first attempt to access a value in the `target`. This defers the overhead of file operations and text processing until a value is first required. This also means that the value expression is not evaluated until the object is first accessed.

### Usage

```json
{
     "name": string,
     "type": "FileAttributesFilter",
     "config": {
         "file": configuration expression<string>,
         "charset": configuration expression<string>,
         "separator": configuration expression<enumeration>,
         "header": configuration expression<boolean>,
         "fields": [ configuration expression<string>, ... ],
         "target": lvalue-expression,
         "key": configuration expression<string>,
         "value": runtime expression<string>
     }
}
```

For an example see [Log in with credentials from a file](../gateway-guide/credentials-datasource.html#tutorial-credentials-from-file).

### Properties

* `"file"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The file containing the record to be read.

* `"charset"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The character set in which the file is encoded.

  Default: `"UTF-8"`.

* `"separator"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

  The separator character, which is one of the following:

  * `COLON`

    Unix-style colon-separated values, with backslash as the escape character.

  * `COMMA`

    Comma-separated values, with support for quoted literal strings.

  * `TAB`

    Tab-separated values, with support for quoted literal strings.

  Default: `COMMA`

* `"header"`: *configuration expression<[boolean](preface.html#definition-boolean)>,optional*

  A flag to treat the first row of the file as a header row.

  When the first row of the file is treated as a header row, the data in that row is disregarded and cannot be returned by a lookup operation.

  Default: `true`.

* `"fields"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  A list of keys in the order they appear in a record.

  If `fields` is not set, the keys are assigned automatically by the column numbers of the file.

* `"target"`: *<[lvalue-expression](preface.html#definition-lvalue-expression)>, required*

  Expression that yields the target object to contain the record.

  The target object is a `Map<String, String>`, where the fields are the keys. For example, if the target is `${attributes.file}` and the record has a `username` field and a `password` field mentioned in the fields list, Then you can access the user name as `${attributes.file.username}` and the password as `${attributes.file.password}`.

  See also [Expressions](Expressions.html#Expressions).

* `"key"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The key used for the lookup operation.

* `"value"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The value to be looked-up in the file.

  See also [Expressions](Expressions.html#Expressions).

### More information

[org.forgerock.openig.filter.FileAttributesFilter](../_attachments/apidocs/org/forgerock/openig/filter/FileAttributesFilter.html)

## ForwardedRequestFilter

Rebase the request URI to a computed scheme, host name, and port.

Use this filter to configure redirects when a request is forwarded by an upstream application such as a TLS offloader.

### Usage

```json
{
  "name": string,
  "type": "ForwardedRequestFilter",
  "config": {
    "scheme": runtime expression<string>,
    "host": runtime expression<string>,
    "port": runtime expression<number>
  }
}
```

### Properties

At least one of `scheme`, `host`, or `port` must be configured.

* `"scheme"`: *runtime expression<[string](preface.html#definition-string)>, optional*

  The scheme to which the request is rebased, for example, `https`.

  Default: Not rebased to a different scheme

* `"host"`: *runtime expression<[string](preface.html#definition-string)>, optional*

  The host to which the request is rebased.

  Default: Not rebased to a different host

* `"port"`: *runtime expression<[number](preface.html#definition-number)>, optional*

  The port to which the request is rebased.

  Default: Not rebased to a different port

### Example

In the following configuration, IG runs behind an AWS load balancer, to perform a login page redirect to an authentication party, using the original URI requested by the client.

IG can access the URI used by the load balancer to reach IG, but can't access the original request URI.

The load balancer breaks the original request URI into the following headers, and adds them to the incoming request:

* `X-Forwarded-Proto`: Scheme

* `X-Forwarded-Port`: Port

* `Host`: Original host name, and possibly the port.

```json
{
  "type": "ForwardedRequestFilter",
  "config": {
    "scheme": "${request.headers['X-Forwarded-Proto'][0]}",
    "host": "${split(request.headers['Host'][0], ':')[0]}",
    "port": "${integer(request.headers['X-Forwarded-Port'][0])}"
  }
}
```

### More information

[org.forgerock.openig.filter.ForwardedRequestFilter](../_attachments/apidocs/org/forgerock/openig/filter/ForwardedRequestFilter.html)

## HeaderFilter

Removes headers from and adds headers to request and response messages. Headers are added to any existing headers in the message. To replace a header, remove the header and then add it again.

### Usage

```json
{
  "name": string,
  "type": "HeaderFilter",
  "config": {
    "messageType": configuration expression<enumeration>,
    "remove": [ configuration expression<string>, ... ],
    "add": {
      string: [ runtime expression<string>, ... ], ...
    }
  }
}
```

### Properties

* \`"messageType": *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

  The type of message for which to filter headers. Must be either `"REQUEST"` or `"RESPONSE"`.

* `"remove"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  The names of header fields to remove from the message.

* `"add"`: *[object](preface.html#definition-object), optional*

  One or more headers to add to a request, with the format `name: [ value, …​ ]`, where:

  * *name* is a string for a header name.

  * *value* is a runtime expression that resolves to one or more header values.

|   |                                                                                                                                                                                                                                                             |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | For IG in web container mode, sending or receiving headers or trailers whose names or values contain non-ASCII characters can cause unspecified behavior at the HTTP server level, and character corruption at the ClientHandler/ReverseProxyHandler level. |

### Examples

#### Replace host header on an incoming request

The following example replaces the host header on the incoming request with the value `myhost.com`:

```json
{
  "name": "ReplaceHostFilter",
  "type": "HeaderFilter",
  "config": {
    "messageType": "REQUEST",
    "remove": [ "host" ],
    "add": {
      "host": [ "myhost.com" ]
    }
  }
}
```

#### Add a header to a response

The following example adds a `Set-Cookie` header to the response:

```json
{
  "name": "SetCookieFilter",
  "type": "HeaderFilter",
  "config": {
    "messageType": "RESPONSE",
    "add": {
      "Set-Cookie": [ "mysession=12345" ]
    }
  }
}
```

#### Add headers to a request

The following example adds the headers `custom1` and `custom2` to the request:

```json
{
  "name": "SetCustomHeaders",
  "type": "HeaderFilter",
  "config": {
    "messageType": "REQUEST",
    "add": {
      "custom1": [ "12345", "6789" ],
      "custom2": [ "abcd" ]
    }
  }
}
```

#### Add a token value to a response

The following example adds the value of session's policy enforcement token to the `pef_sso_token` header in the response:

```json
{
  "type": "HeaderFilter",
  "config": {
    "messageType": "RESPONSE",
    "add": {
      "pef_sso_token": ["${session.pef_token}"]
    }
  }
}
```

#### Add headers and logging results

The following example adds a message to the request and response as it passes through the Chain, and the `capture` on the ReverseProxyHandler logs the result. With IG and the sample application set up as described in the [Getting started](../getting-started/preface.html), access this route on <http://ig.example.com:8080/home/chain>.

```json
{
  "condition": "${find(request.uri.path, '^/home/chain')}",
  "handler": {
    "type": "Chain",
    "comment": "Base configuration defines the capture decorator",
    "config": {
      "filters": [
        {
          "type": "HeaderFilter",
          "comment": "Add a header to all requests",
          "config": {
            "messageType": "REQUEST",
            "add": {
              "MyHeaderFilter_request": [
                "Added by HeaderFilter to request"
              ]
            }
          }
        },
        {
          "type": "HeaderFilter",
          "comment": "Add a header to all responses",
          "config": {
            "messageType": "RESPONSE",
            "add": {
              "MyHeaderFilter_response": [
                "Added by HeaderFilter to response"
              ]
            }
          }
        }
      ],
      "handler": {
        "type": "ReverseProxyHandler",
        "comment": "Log request, pass it to the sample app, log response",
        "capture": "all",
        "baseURI": "http://app.example.com:8081"
      }
    }
  }
}
```

The chain receives the request and context and processes it as follows:

* The first `HeaderFilter` adds a header to the incoming request.

* The second `HeaderFilter` manages responses not requests, so it simply passes the request and context to the handler.

* The `ReverseProxyHandler` captures (logs) the request.

* The `ReverseProxyHandler` forwards the transformed request to the protected application.

* The protected application passes a response to the `ReverseProxyHandler`.

* The `ReverseProxyHandler` captures (logs) the response.

* The second `HeaderFilter` adds a header added to the response.

* The first `HeaderFilter` is configured to manage requests, not responses, so it simply passes the response back to IG.

The following example lists some of the HTTP requests and responses captured as they flow through the chain. You can search the log files for `MyHeaderFilter_request` and `MyHeaderFilter_response`.

```http
# Original request from user-agent
GET http://ig.example.com:8080/home/chain HTTP/1.1
Accept: /
Host: ig.example.com:8080

# Add a header to the request (inside IG) and direct it to the protected application
GET http://app.example.com:8081/home/chain HTTP/1.1
Accept: /
Host: ig.example.com:8080
MyHeaderFilter_request: Added by HeaderFilter to request

# Return the response to the user-agent
HTTP/1.1 200 OK
Content-Length: 1809
Content-Type: text/html; charset=ISO-8859-1

# Add a header to the response (inside IG)
HTTP/1.1 200 OK
Content-Length: 1809
MyHeaderFilter_response: Added by HeaderFilter to response
```

### More information

[org.forgerock.openig.filter.HeaderFilter](../_attachments/apidocs/org/forgerock/openig/filter/HeaderFilter.html)

## HttpBasicAuthenticationClientFilter

Authenticates clients according to the HTTP basic access authentication scheme.

HTTP basic access authentication is a simple challenge and response mechanism, where a server requests credentials from a client, and the client passes them to the server in an `Authorization` header. The credentials are base-64 encoded. To protect them, use SSL encryption for the connections between the server and client. For more information, see [RFC 2617](http://www.ietf.org/rfc/rfc2617.txt).

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Compare the purpose of this filter with that of the following filters:- [ClientCredentialsOAuth2ClientFilter](#ClientCredentialsOAuth2ClientFilter), which authenticates clients by their OAuth 2.0 credentials to obtain an access token from an authorization server.

- [ClientSecretBasicAuthenticationFilter](#ClientSecretBasicAuthenticationFilter), which fulfils the same role of transforming OAuth 2.0 credentials to an `Authorization` header, but is more strict for OAuth 2.0 requirements. |

Use HttpBasicAuthenticationClientFilter in a service-to-service context, where services need to access resources protected by HTTP basic access authentication.

### Usage

```json
{
  "name": string,
  "type": "HttpBasicAuthenticationClientFilter",
  "config": {
    "username": configuration expression<string>,
    "passwordSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference,
    "urlEncodeCredentials": configuration expression<boolean>
  }
}
```

### Properties

* `"username"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The username of the client to authenticate.

* `"passwordSecretId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The secret ID required to obtain the client password.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to obtain the `passwordSecretId`. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

* `"urlEncodeCredentials"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

  Set to `true` to URL-encoded credentials before base64-encoding them.

  Default: `false`

### Example

The following example shows the flow of information when a client service accesses a resource protected by HTTP basic access authentication:

![A client service accesses a resource protected by HTTP basic access authentication.](_images/HttpBasicAuthenticationClientFilter.svg)Set Up the Example

1. Add the following script to the IG configuration as `$HOME/.openig/scripts/groovy/BasicAuthResourceServerFilter.groovy` (on Windows, `%appdata%\OpenIG\scripts\groovy\BasicAuthResourceServerFilter.groovy` ):

   ```groovy
   /*
    * This script is a simple implementation of HTTP basic access authentication on
    * server side.
    * It expects the following arguments:
    *  - realm: the realm to display when the user-agent prompts for
    *    username and password if none were provided.
    *  - username: the expected username
    *  - password: the expected password
    */

   import static org.forgerock.util.promise.Promises.newResultPromise;

   import java.nio.charset.Charset;
   import org.forgerock.util.encode.Base64;

   String authorizationHeader = request.getHeaders().getFirst("Authorization");
   if (authorizationHeader == null) {
       // No credentials provided, reply that they are needed.
       Response response = new Response(Status.UNAUTHORIZED);
       response.getHeaders().put("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
       return newResultPromise(response);
   }

   String expectedAuthorization = "Basic " + Base64.encode((username + ":" + password).getBytes(Charset.defaultCharset()))
   if (!expectedAuthorization.equals(authorizationHeader)) {
       return newResultPromise(new Response(Status.FORBIDDEN));
   }
   // Credentials are as expected, let's continue
   return next.handle(context, request);
   ```

   The script is a simple implementation of the HTTP basic access authentication scheme.

   For information about scripting filters and handlers, see [Extend IG](../gateway-guide/extending.html).

2. Add the following route to IG:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/http-basic-access.json
   ```

   ```
   %appdata%\OpenIG\config\routes\http-basic-access.json
   ```

   ```json
   {
     "name": "http-basic-access",
     "baseURI": "http://ig.example.com:8080",
     "condition" : "${find(request.uri.path, '^/http-basic-access')}",
     "heap": [
       {
         "name": "httpBasicAuthEnabledClientHandler",
         "type": "Chain",
         "capture": "all",
         "config": {
           "filters": [
             {
               "type": "HttpBasicAuthenticationClientFilter",
               "config": {
                 "username": "myclient",
                 "passwordSecretId": "password.secret.id",
                 "secretsProvider": {
                   "type": "Base64EncodedSecretStore",
                   "config": {
                     "secrets": {
                       "password.secret.id": "cGFzc3dvcmQ="
                     }
                   }
                 }
               }
             }
           ],
           "handler": "ForgeRockClientHandler"
         }
       }
     ],
     "handler": {
       "type": "ScriptableHandler",
       "config": {
         "type": "application/x-groovy",
         "clientHandler": "httpBasicAuthEnabledClientHandler",
         "source": [
           "request.uri.path = '/http-basic-protected-resource'",
           "return http.send(context, request);"
         ]
       }
     }
   }
   ```

   Note the following features of the route:

   * The route matches requests to `/http-basic-access`.

   * The ScriptableHandler rewrites the request to target it to `/http-basic-protected-resource`, and then calls the HTTP client, that has been redefined to use the httpBasicAuthEnabledClientHandler.

   * The httpBasicAuthEnabledClientHandler calls the HttpBasicAuthenticationClientFilter to authenticate the client, using the client's credentials.

3. Add the following route to IG:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/http-basic-protected-resource.json
   ```

   ```
   %appdata%\OpenIG\config\routes\http-basic-protected-resource.json
   ```

   ```json
   {
     "name": "http-basic-protected-resource",
     "condition": "${find(request.uri.path, '^/http-basic-protected-resource')}",
     "handler": {
       "type": "Chain",
       "config": {
         "filters": [
           {
             "name": "HttpBasicAuthResourceServerFilter",
             "type": "ScriptableFilter",
             "config": {
               "type": "application/x-groovy",
               "file": "BasicAuthResourceServerFilter.groovy",
               "args": {
                 "realm": "IG Protected Area",
                 "username": "myclient",
                 "password": "password"
               }
             }
           }
         ],
         "handler": {
           "type": "StaticResponseHandler",
           "config": {
             "status": 200,
             "headers": {
               "Content-Type": [ "text/html; charset=UTF-8" ]
             },
             "entity": "<html><body><h2>Access Granted</h2></body></html>"
           }
         }
       }
     }
   }
   ```

   Notice the following features of the route:

   * The route matches requests to `/http-basic-protected-resource`.

   * The ScriptableFilter provides a script to implement a simple HTTP basic access authentication scheme, that compares the provided credentials with the expected credentials.

   * When the client is authenticated, the StaticResponseHandler returns a message that access is granted.

4. Access the route on <http://ig.example.com:8080/http-basic-access>.

   Because the expected credentials were provided in the request, a message shows that access is granted.

## HttpBasicAuthFilter

Authenticate clients by providing the client credentials as a basic authorization header in the request. The credentials are base64-encoded.

This filter performs HTTP basic access authentication, described in [RFC 2617](http://www.ietf.org/rfc/rfc2617.txt).

Use this filter primarily for password replay scenarios, where the password is stored externally in clear text.

If challenged for authentication via a `401 Unauthorized` status code by the server, this filter retries the request with credentials attached. After an HTTP authentication challenge is issued from the remote server, all subsequent requests to that remote server that pass through the filter include the user credentials.

If authentication fails (including the case where no credentials are yielded from expressions), then processing is diverted to the specified authentication failure handler.

### Usage

```json
{
    "name": string,
    "type": "HttpBasicAuthFilter",
    "config": {
        "username": runtime expression<string>,
        "password": runtime expression<string>,
        "failureHandler": Handler reference,
        "cacheHeader": configuration expression<boolean>
    }
}
```

### Properties

* `"username"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The username to supply during authentication.

  See also [Expressions](Expressions.html#Expressions).

* `"password"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The password to supply during authentication.

  See also [Expressions](Expressions.html#Expressions).

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), required*

  Dispatch to this Handler if authentication fails.

  Provide either the name of a Handler object defined in the heap, or an inline Handler configuration object.

  See also [Handlers](Handlers.html).

* `"cacheHeader"`: *configuration expression<[boolean](preface.html#definition-boolean)>,optional*

  Whether or not to cache credentials in the session after the first successful authentication, and then replay those credentials for subsequent authentications in the same session.

  With `"cacheHeader": false`, the filter generates the header for each request. This is useful, for example, when users change their passwords during a browser session.

  Default: `true`

### Example

```json
{
    "name": "TomcatAuthenticator",
    "type": "HttpBasicAuthFilter",
    "config": {
        "username": "tomcat",
        "password": "tomcat",
        "failureHandler": "TomcatAuthFailureHandler",
        "cacheHeader": false
    }
}
```

### More information

[org.forgerock.openig.filter.HttpBasicAuthFilter](../_attachments/apidocs/org/forgerock/openig/filter/HttpBasicAuthFilter.html)

## IdTokenValidationFilter

Validates an ID token by checking the standard claims, `aud`, `exp`, and `iat`. If specified in the configuration, this filter also checks the ID token issuer and signature.

This filter passes data into the context as follows:

* If the JWT is validated, the request continues down the chain. The data is provided in the [JwtValidationContext](RequestsResponsesContexts.html#JwtValidationContext).

* If the JWT is not validated, data is provided in the [JwtValidationErrorContext](RequestsResponsesContexts.html#JwtValidationErrorContext).

  If a failure handler is configured, the request passes to the failure handler. Otherwise, an HTTP 403 Forbidden is returned.

The `iat` claim is required, and the `iat` minus the `skewAllowance` must be before the current time on the IG clock. For information, see [OpenID Connect Core 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-core-1_0.html).

### Usage

```json
{
   "name": string,
   "type": "IdTokenValidationFilter",
   "config": {
     "idToken": runtime expression<string>,
     "audience": configuration expression<string>,
     "issuer": configuration expression<string>,
     "skewAllowance": configuration expression<duration>,
     "verificationSecretId": configuration expression<secret-id>,
     "secretsProvider": SecretsProvider reference,
     "customizer": JwtValidatorCustomizer reference,
     "failureHandler": Handler reference
   }
}
```

### Properties

* `"idToken"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The ID token as an expression representing the JWT or signed JWT in the request. Cannot be null.

* `"audience"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The `aud` claim to check on the JWT. Cannot be null.

* `"issuer"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The `iss` claim to check on the JWT. Can be null.

- `"skewAllowance"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

  The duration to add to the validity period of a JWT to allow for clock skew between different servers. To support a zero-trust policy, the skew allowance is by default zero.

  A `skewAllowance` of 2 minutes affects the validity period as follows:

  * A JWT with an `iat` of 12:00 is valid from 11:58 on the IG clock.

  * A JWT with an `exp` 13:00 is expired after 13:02 on the IG clock.

  Default: `zero`

* `"verificationSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required to verify the signature of signed tokens*

  The secret ID for the secret to verify the signature of signed tokens.

  If configured, the token must be signed. If not configured, IG does not verify the signature.

  For information about how signatures are validated, see [Validating the signature of signed tokens](../gateway-guide/about.html#secret-valid-signature). For information about how each type of secret store resolves named secrets, see [Secrets](secrets.html).

- `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

* `"customizer"`: *JwtValidatorCustomizer [reference](preface.html#definition-reference), optional*

  A set of validation constraints for JWT claims and sub-claims. If a claim is not validated against the constraint, the JWT is not validated.

  The customizer does not override existing constraints, such as `aud`, `iss`, `exp`, and `iat`, which are predefined in the IdTokenValidationFilter, Defining a new constraint on an already constrained claim has an impact only if the new constraint is more restrictive.

  JwtValidatorCustomizer provides a ScriptableJwtValidatorCustomizer to enrich a `builder` object by using its methods. Get more information about the following items:

  * The `builder` object, at [Available Objects](Scripts.html#Scripts-availableob).

  * Transformer methods, to enrich the builder object, at [org.forgerock.openig.util.JsonValues](../_attachments/apidocs/org/forgerock/openig/util/JsonValues.html).

  * Constraints, at [org.forgerock.openig.tools.jwt.validation.Constraints](../_attachments/apidocs/org/forgerock/openig/tools/jwt/validation/Constraints.html).

  * Other properties for ScriptableJwtValidatorCustomizer, at [Scripts](Scripts.html).

  The following examples provide checks:

  * Check that the value of the claim `greaterThan5` is greater than 5

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('/greaterThan5', JsonValue::asInteger, isGreaterThan(5))"
        ]
      }
    }
    ```

  * Check that the value of the claim `sub` is `george`

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('subname', JsonValue::asString, isEqualTo('george'))"
        ]
      }
    }
    ```

  * Check that the value of the custom sub-claim is `ForgeRock`

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('customclaim/subclaim', JsonValue::asString, isEqualTo('ForgeRock'));"
        ]
      }
    }
    ```

  * Check the value of multiple claims

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('aud', listOf(JsonValue::asString), contains('My App'))",
          "       .claim('iat', instant(), isInThePast())",
          "       .claim('exp', instant(), isInTheFuture());",
          "builder.claim('iss', JsonValue::asString, isEqualTo('ForgeRock AM'));"
        ]
      }
    }
    ```

  * Check that the value of `val1` is greater than `val2`

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [ "builder.claim('/val1', JsonValue::asInteger, isGreaterThan(claim('/val2').asInteger()))" ]
      }
    }
    ```

  * Check that the value of `val1` is greater than `val2`, when both are YYYY-MM-DD dates

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "Function<JsonValue, java.time.LocalDate, Exception> asDate() {",
          "  return (jsonValue) -> java.time.LocalDate.parse(jsonValue.asString());",
          "}",
          "builder.claim('claim1', asDate(), isGreaterThan(claim('claim2').as(asDate())));"
        ]
      }
    }
    ```

  * Check that the claim issuer matches the regex pattern

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [ "builder.claim('iss', JsonValue::asString, find(~/.*am\.example\.(com|org)/))" ]
      }
    }
    ```

Default: Claims are not validated

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request on failure.

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 403 Forbidden, the request stops being executed.

### Example

Validate an id_token

1. Set up AM:

   1. Set up AM as described in [Validate access tokens through the introspection endpoint](../gateway-guide/oauth2-rs.html#oauth2-rs-introspect).

   2. Select Applications > OAuth 2.0 > Clients, and add the additional scope `openid` to `client-application`.

2. Set up IG:

   1. Add the following route to IG:

      * Linux

      * Windows

      ```
      $HOME/.openig/config/routes/idtokenvalidation.json
      ```

      ```
      %appdata%\OpenIG\config\routes\idtokenvalidation.json
      ```

      ```json
      {
        "name": "idtokenvalidation",
        "condition": "${find(request.uri.path, '^/idtokenvalidation')}",
        "capture": "all",
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [{
              "type": "IdTokenValidationFilter",
              "config": {
                "idToken": "<id_token_value>",
                "audience": "client-application",
                "issuer": "http://am.example.com:8088/openam/oauth2",
                "failureHandler": {
                  "type": "ScriptableHandler",
                  "config": {
                    "type": "application/x-groovy",
                    "source": [
                      "def response = new Response(Status.FORBIDDEN)",
                      "response.headers['Content-Type'] = 'text/html; charset=utf-8'",
                      "def errors = contexts.jwtValidationError.violations.collect{it.description}",
                      "def display = \"<html>Can't validate id_token:<br> ${contexts.jwtValidationError.jwt} \"",
                      "display <<=\"<br><br>For the following errors:<br> ${errors.join(\"<br>\")}</html>\"",
                      "response.entity=display as String",
                      "return response"
                    ]
                  }
                },
                "verificationSecretId": "verify",
                "secretsProvider": {
                  "type": "JwkSetSecretStore",
                  "config": {
                    "jwkUrl": "http://am.example.com:8088/openam/oauth2/connect/jwk_uri"
                  }
                }
              }
            }],
            "handler": {
              "type": "StaticResponseHandler",
              "config": {
                "status": 200,
                "headers": {
                  "Content-Type": [ "text/html; charset=UTF-8" ]
                },
                "entity": "<html><body>Validated id_token:<br> ${contexts.jwtValidation.value}</body></html>"
              }
            }
          }
        }
      }
      ```

      Notice the following features of the route:

      * The route matches requests to `/idtokenvalidation`.

      * A SecretsProvider declares a JwkSetSecretStore to validate secrets for signed JWTs, which specifies the URL to a JWK set on AM that contains the signing keys.

      * The property `verificationSecretId` is configured with a value. If this property is not configured, the filter does not verify the signature of tokens.

      * The JwkSetSecretStore specifies the URL to a JWK set on AM, that contains signing keys identified by a `kid`. The signature of the token is verified as follows:

        * If the value of a `kid` in the JWK set matches a `kid` in the the signed JWT, the JwkSetSecretStore verifies the signature.

        * If the JWT doesn't have a `kid`, or if the JWK set doesn't contain a key with the same value, the JwkSetSecretStore looks for valid secrets with the same purpose as the value of `verificationSecretId`.

      * If the filter validates the token, the StaticResponseHandler displays the token value from the context `${contexts.jwtValidation.value}`. Otherwise, the ScriptableHandler displays the token value and a list of violations from the context `${contexts.jwtValidationError.violations}`

3. Test the setup:

   1. In a terminal window, use a `curl` command similar to the following to retrieve an id_token:

      ```bash
      $ curl -s \
      --user "client-application:password" \
      --data "grant_type=password&username=demo&password=Ch4ng31t&scope=openid" \
      http://am.example.com:8088/openam/oauth2/access_token

      {
       "access_token":"...",
       "scope":"openid",
       "id_token":"...",
       "token_type":"Bearer",
       "expires_in":3599
      }
      ```

      * In the route, replace `<id_token_value>` with the value of the `id_token` returned in the previous step.

   2. Access the route on <http://ig.example.com:8080/idtokenvalidation>.

      The validated token is displayed.

      * In the route, invalidate the token by changing the value of the audience or issuer, and then access the route again.

        The value of the token, and the reasons that the token is invalid, are displayed.

### More information

[org.forgerock.openig.filter.oauth2.client.IdTokenValidationFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/client/IdTokenValidationFilterHeaplet.html)

[org.forgerock.openig.filter.jwt.JwtValidationContext](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationContext.html)

[org.forgerock.openig.filter.jwt.JwtValidationErrorContext](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationErrorContext.html)

[OpenID Connect Core 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-core-1_0.html)

## JwtBuilderFilter

Collects data at runtime, packs it in a JSON Web Token (JWT), and places the resulting JWT into the [JwtBuilderContext](RequestsResponsesContexts.html#JwtBuilderContext).

Configure JwtBuilderFilter to create an unsigned JWT, a signed JWT, a signed then encrypted JWT, or an encrypted JTW:

* Sign the JWT so that an application can validate the authenticity of the claims/data. The JWT can be signed with a shared secret or private key, and verified with a shared secret or corresponding public key.

* Encrypt the JWT to reduce the risk of a data breach.

For a flexible way to pass identity or other runtime information to the protected application, use this filter with a [HeaderFilter](#HeaderFilter).

To enable downstream filters and handlers to verify signed and/or encrypted JWTs built by this filter, use this filter with a [JwkSetHandler](Handlers.html#JwkSetHandler).

### Usage

```json
{
  "name": string,
  "type": "JwtBuilderFilter",
  "config": {
    "template": map or runtime expression<map>,
    "secretsProvider": SecretsProvider reference,
    "signature": object,
    "encryption": object
  }
}
```

### Properties

* `"template"`: *[map](preface.html#definition-map) or runtime expression\<map>, required*

  A map of information taken from the request or associated contexts in IG.

  If this property is a map, the structure must have the format `Map<String, Object>`, and map values are evaluated as runtime expressions. For example,

  ```json
  "template": {
    "name": "${contexts.userProfile.commonName}",
    "email": "${contexts.userProfile.rawInfo.mail[0]}",
    "address": "${contexts.userProfile.rawInfo.postalAddress[0]}",
    "phone": "${contexts.userProfile.rawInfo.telephoneNumber[0]}"
  }
  ```

  If this property is an expression, its evaluation must give an object of type [map](preface.html#definition-map), `Map<String, Object>`. For example,

  ```json
  "template": "${contexts.attributes}"
  ```

  See also [Expressions](Expressions.html#Expressions).

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), optional*

  The SecretsProvider object to query for JWT signing or encryption keys. For more information, see [SecretsProvider](secrets.html#SecretsProvider).

  Default: The route's default secret service. For more information, see [Default secrets object](secrets.html#default-secrets-object).

* `"signature"`: *[object](preface.html#definition-object), optional*

  |   |                                                                                                                                                                                |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  |   | The use of unsigned or unencrypted JWTs is deprecated and not considered secure. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  A JWT signature to allow the authenticity of the claims/data to be validated. A signed JWT can be encrypted.

  `JwtBuilderFilter.encryption` takes precedence over this property.

  ```json
  {
    "signature": {
      "secretId": configuration expression<secret-id>,
      "algorithm": configuration expression<string>,
      "encryption": object,
      "keystore":  KeyStore reference, //deprecated
      "alias": configuration expression<string>, //deprecated
      "password": configuration expression<string> //deprecated
    }
  }
  ```

  * `"secretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required if `signature` is used*

    The secret ID of the key to sign the JWT.

  * `"algorithm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    The algorithm to sign the JWT.

    The following algorithms are supported but not necessarily tested in IG:

    * Algorithms described in [RFC 7518: Cryptographic Algorithms for Digital Signatures and MACs](https://www.rfc-editor.org/rfc/rfc7518#section-3).

      For RSASSA-PSS, you must install Bouncy Castle. For information, see [The Legion of the Bouncy Castle](https://www.bouncycastle.org).

    * From IG 6.1, `Ed25519` described in [CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)](https://www.rfc-editor.org/rfc/rfc8037).

      Default: RS256

  * `"encryption"`: *[object](preface.html#definition-object), optional*

    Configuration to encrypt the JWT signature.

    ```json
    {
      "encryption": {
        "secretId": configuration expression<secret-id>,
        "algorithm": configuration expression<string>,
        "method": configuration expression<string>
      }
    }
    ```

    * `"secretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, optional*

      The secret ID of the key used to encrypt the JWT signature. The value is mapped to key `aliases` in [KeyStoreSecretStore](secrets.html#KeyStoreSecretStore).

    * `"algorithm"`: *configuration expression<[string](preface.html#definition-string)>, required*

      The algorithm used to encrypt the JWT signature.

      For information about available algorithms, see [RFC 7518: "alg" (Algorithm) Header Parameter Values for JWE](https://www.rfc-editor.org/rfc/rfc7518#section-4.1).

    * `"method"`: *configuration expression<[string](preface.html#definition-string)>, required*

      The method used to encrypt the JWT signature.

      For information about available methods, see [RFC 7518: "enc" (Encryption Algorithm) Header Parameter Values for JWE](https://www.rfc-editor.org/rfc/rfc7518#section-5.1).

  * `"keystore"`: *KeyStore reference, optional*

    |   |                                                                                                                                                                                |
    | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    |   | This property is deprecated; use the `signature` subproperty `secretId` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

    The Java KeyStore containing the key used to sign the JWT.

    The name of a KeyStore object defined in the heap, or an inline KeyStore configuration object.

  * `"alias"`: *configuration expression\<string>, required if `signature` is used*

    |   |                                                                                                                                                                                |
    | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    |   | This property is deprecated; use the `signature` subproperty `secretId` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

    Alias for the key.

    Note Because KeyStore converts all characters in its key aliases to lower case, use only lowercase in alias definitions of a KeyStore.

  * `"password"`: *expression\<string>, required if `signature` is used*

    |   |                                                                                                                                                                                |
    | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    |   | This property is deprecated; use the `signature` subproperty `secretId` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

    Password for the key.

* `"encryption"`: *[object](preface.html#definition-object), optional*

  |   |                                                                                                                                                                                |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  |   | The use of unsigned or unencrypted JWTs is deprecated and not considered secure. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  Configuration to encrypt the JWT. This property take precedence over `JwtBuilderFilter.signature`.

  ```json
  {
    "encryption": {
      "secretId": secret-id,
      "algorithm": configuration expression<string>,
      "method": configuration expression<enumeration>
    }
  }
  ```

  * `"secretId"`: *[secret-id](preface.html#definition-secretid), optional*

    The secret ID of the key used to encrypt the JWT. The value is mapped to key `aliases` in [KeyStoreSecretStore](secrets.html#KeyStoreSecretStore).

  * `"algorithm"`: *configuration expression<[string](preface.html#definition-string)>, required*

    The algorithm used to encrypt the JWT.

    For information about available algorithms, see [RFC 7518: "alg" (Algorithm) Header Parameter Values for JWE](https://www.rfc-editor.org/rfc/rfc7518#section-4.1).

  * `"method"`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, required*

    The method used to encrypt the JWT.

    For information about available methods, see [RFC 7518: "enc" (Encryption Algorithm) Header Parameter Values for JWE](https://www.rfc-editor.org/rfc/rfc7518#section-5.1).

### Examples

For examples, see [Pass runtime data downstream in a JWT](../gateway-guide/runtime.html)

### More information

[org.forgerock.openig.filter.JwtBuilderFilter](../_attachments/apidocs/org/forgerock/openig/filter/JwtBuilderFilter.html)

[org.forgerock.openig.filter.JwtBuilderContext](../_attachments/apidocs/org/forgerock/openig/filter/JwtBuilderContext.html)

## JwtValidationFilter

Validates an unsigned, signed, encrypted, or signed and encrypted JWT. The order of signing and encryption is not important; a JWT can be signed and then encrypted, or encrypted and then signed.

If the JWT is validated, the request continues down the chain. The data is provided in the [JwtValidationContext](RequestsResponsesContexts.html#JwtValidationContext).

If the JWT is not validated, data is provided in the [JwtValidationErrorContext](RequestsResponsesContexts.html#JwtValidationErrorContext). If a failure handler is configured, the request passes to the failure handler. Otherwise, an HTTP 403 Forbidden is returned.

### Usage

```json
{
  "name": string,
  "type": "JwtValidationFilter",
  "config": {
    "jwt": runtime expression<string>,
    "verificationSecretId": configuration expression<secret-id>,
    "decryptionSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference,
    "skewAllowance": configuration expression<duration>,
    "customizer": JwtValidatorCustomizer reference,
    "failureHandler": Handler reference
  }
}
```

### Properties

* `"jwt"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The value of the JWT in the request. Cannot be null.

- `"verificationSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required to verify the signature of signed tokens*

  The secret ID for the secret to verify the signature of signed tokens.

  If configured, the token must be signed. If not configured, IG does not verify the signature.

  For information about how signatures are validated, see [Validating the signature of signed tokens](../gateway-guide/about.html#secret-valid-signature). For information about how each type of secret store resolves named secrets, see [Secrets](secrets.html).

- `"decryptionSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required if AM secures access tokens with encryption*

  The secret ID for the secret to verify the encryption of tokens.

  If configured, the token must be encrypted. If not configured, IG does not verify the encryption.

  For information about how each type of secret store resolves named secrets, see [Secrets](secrets.html).

- `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The [SecretsProvider](secrets.html#SecretsProvider) to use to resolve queried secrets, such as passwords and cryptographic keys. Provide either the name of a SecretsProvider object defined in the heap, or specify a SecretsProvider object inline.

* `"customizer"`: *JwtValidatorCustomizer [reference](preface.html#definition-reference), optional*

  A set of validation constraints for JWT claims and sub-claims. If a claim is not validated against the constraint, the JWT is not validated.

  The customizer does not override existing constraints, such as `aud`, `iss`, `exp`, and `iat`, which are predefined in the IdTokenValidationFilter, Defining a new constraint on an already constrained claim has an impact only if the new constraint is more restrictive.

  JwtValidatorCustomizer provides a ScriptableJwtValidatorCustomizer to enrich a `builder` object by using its methods. Get more information about the following items:

  * The `builder` object, at [Available Objects](Scripts.html#Scripts-availableob).

  * Transformer methods, to enrich the builder object, at [org.forgerock.openig.util.JsonValues](../_attachments/apidocs/org/forgerock/openig/util/JsonValues.html).

  * Constraints, at [org.forgerock.openig.tools.jwt.validation.Constraints](../_attachments/apidocs/org/forgerock/openig/tools/jwt/validation/Constraints.html).

  * Other properties for ScriptableJwtValidatorCustomizer, at [Scripts](Scripts.html).

  The following examples provide checks:

  * Check that the value of the claim `greaterThan5` is greater than 5

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('/greaterThan5', JsonValue::asInteger, isGreaterThan(5))"
        ]
      }
    }
    ```

  * Check that the value of the claim `sub` is `george`

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('subname', JsonValue::asString, isEqualTo('george'))"
        ]
      }
    }
    ```

  * Check that the value of the custom sub-claim is `ForgeRock`

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('customclaim/subclaim', JsonValue::asString, isEqualTo('ForgeRock'));"
        ]
      }
    }
    ```

  * Check the value of multiple claims

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "builder.claim('aud', listOf(JsonValue::asString), contains('My App'))",
          "       .claim('iat', instant(), isInThePast())",
          "       .claim('exp', instant(), isInTheFuture());",
          "builder.claim('iss', JsonValue::asString, isEqualTo('ForgeRock AM'));"
        ]
      }
    }
    ```

  * Check that the value of `val1` is greater than `val2`

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [ "builder.claim('/val1', JsonValue::asInteger, isGreaterThan(claim('/val2').asInteger()))" ]
      }
    }
    ```

  * Check that the value of `val1` is greater than `val2`, when both are YYYY-MM-DD dates

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "Function<JsonValue, java.time.LocalDate, Exception> asDate() {",
          "  return (jsonValue) -> java.time.LocalDate.parse(jsonValue.asString());",
          "}",
          "builder.claim('claim1', asDate(), isGreaterThan(claim('claim2').as(asDate())));"
        ]
      }
    }
    ```

  * Check that the claim issuer matches the regex pattern

    ```json
    "customizer": {
      "type": "ScriptableJwtValidatorCustomizer",
      "config": {
        "type": "application/x-groovy",
        "source": [ "builder.claim('iss', JsonValue::asString, find(~/.*am\.example\.(com|org)/))" ]
      }
    }
    ```

Default: Claims are not validated

* `"skewAllowance"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

  The duration to add to the validity period of a JWT to allow for clock skew between different servers. To support a zero-trust policy, the skew allowance is by default zero.

  A `skewAllowance` of 2 minutes affects the validity period as follows:

  * A JWT with an `iat` of 12:00 is valid from 11:58 on the IG clock.

  * A JWT with an `exp` 13:00 is expired after 13:02 on the IG clock.

  Default: `zero`

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request on failure.

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 403 Forbidden, the request stops being executed.

### Example

For an example of using JwtValidationFilter, see [Validate JWTs](../gateway-guide/validate-jwt.html).

### More information

[org.forgerock.openig.filter.jwt.JwtValidationFilter](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationFilter.html)

[org.forgerock.openig.filter.jwt.JwtValidationContext](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationContext.html)

[org.forgerock.openig.filter.jwt.JwtValidationErrorContext](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationErrorContext.html)

[OpenID Connect Core 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-core-1_0.html)

## LocationHeaderFilter

For a response that generates a redirect to the proxied application, this filter rewrites the Location header on the response to redirect the user to IG.

### Usage

```json
{
    "name": string,
    "type": "LocationHeaderFilter",
    "config": {
        "baseURI": runtime expression<url>
    }
}
```

An alternative value for type is RedirectFilter.

### Properties

* `"baseURI"`: *runtime expression<[url](preface.html#definition-url)>,optional*

  The base URI of the IG instance. This is used to rewrite the Location header on the response.

  The result of the expression must be a string that represents a valid URI, but is not a real `java.net.URI` object. For example, it would be incorrect to use `${request.uri}`, which is not a String but a MutableUri.

  Default: Redirect to the original URI specified in the request.

  See also [Expressions](Expressions.html#Expressions).

### Example

In the following example, IG listens on `https://ig.example.com:443` and the application it protects listens on `http://app.example.com:8081`. The filter rewrites redirects that would normally take the user to locations under `http://app.example.com:8081` to go instead to locations under `https://ig.example.com:443`.

```json
{
     "name": "LocationRewriter",
     "type": "LocationHeaderFilter",
     "config": {
         "baseURI": "https://ig.example.com:443/"
      }
}
```

### More information

[org.forgerock.openig.filter.LocationHeaderFilter](../_attachments/apidocs/org/forgerock/openig/filter/LocationHeaderFilter.html)

## OAuth2ClientFilter

In IG 7.2, this filter was renamed to [AuthorizationCodeOAuth2ClientFilter](AuthorizationCodeOAuth2ClientFilter.html).

For backward compatibility, the name OAuth2ClientFilter can still be used in routes in this release. However, to prevent problems in future releases, update your configuration as soon as possible.

## OAuth2ResourceServerFilter

Validates a request containing an OAuth 2.0 access token. The filter expects an OAuth 2.0 token from the HTTP Authorization header of the request, such as the following example header, where the OAuth 2.0 access token is `1fc…​ec9`:

```http
Authorization: Bearer 1fc...ec9
```

The filter performs the following tasks:

* Extracts the access token from the request header.

* Uses the configured access token resolver to resolve the access token against an authorization server, and validate the token claims.

* Checks that the token has the scopes required by the filter configuration.

* Injects the access token info into the [OAuth2Context](RequestsResponsesContexts.html#OAuth2Context).

The following errors can occur during access token validation:

| Error                                                                                                              | Response from the filter to the user-agent                  |
| ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------- |
| Combination of the filter configuration and access token result in an invalid request to the authorization server. | `HTTP 400 Bad Request`                                      |
| There is no access token in the request header.                                                                    | `HTTP 401 Unauthorized WWW-Authenticate: Bearer realm="IG"` |
| The access token isn't valid, for example, because it has expired.                                                 | `HTTP 401 Unauthorized`                                     |
| The access token doesn't have all of the scopes required in the OAuth2ResourceServerFilter configuration.          | `HTTP 403 Forbidden`                                        |

### Usage

```json
{
  "name": string,
  "type": "OAuth2ResourceServerFilter",
  "config": {
    "accessTokenResolver": AccessTokenResolver reference,
    "cache": object,
    "executor": Executor service reference,
    "requireHttps": configuration expression<boolean>,
    "realm": configuration expression<string>,
    "scopes": [ runtime expression<string>, ... ] or ScriptableResourceAccess reference
  }
}
```

An alternative value for type is OAuth2RSFilter.

### Properties

* `"accessTokenResolver"`: *AccessTokenResolver [reference](preface.html#definition-reference), required*

  Resolves an access token against an authorization server. Configure one of the following access token resolvers:

  * [TokenIntrospectionAccessTokenResolver](AccessTokenResolvers.html#TokenIntrospectionAccessTokenResolver)

  * [StatelessAccessTokenResolver](AccessTokenResolvers.html#StatelessAccessTokenResolver)

  * [ConfirmationKeyVerifierAccessTokenResolver](AccessTokenResolvers.html#ConfirmationKeyVerifierAccessTokenResolver)

  * [ScriptableAccessTokenResolver](AccessTokenResolvers.html#ScriptableAccessTokenResolver)

  To decorate an AccessTokenResolver, add the decoration at the `accessTokenResolver` level. The following example uses the default timer decorator to record the time that a TokenIntrospectionAccessTokenResolver takes to process a request:

  ```json
  {
    "accessTokenResolver": {
      "type": "TokenIntrospectionAccessTokenResolver",
      "config": {
        ...
      },
    "timer": true
    }
  }
  ```

* `"cache"`: *[object](preface.html#definition-object), optional*

  Configuration of caching for OAuth 2.0 access tokens. By default, access tokens are not cached. For an alternative way of caching of OAuth 2.0 access tokens, configure [CacheAccessTokenResolver](AccessTokenResolvers.html#CacheAccessTokenResolver).

  When an access token is cached, IG can reuse the token information without repeatedly asking the authorization server to verify the access token. When caching is disabled, IG must ask the authorization server to verify the access token for each request.

  *(From AM 6.5.3.)* When an access_token is revoked on AM, the CacheAccessTokenResolver can delete the token from the cache when both of the following conditions are true:

  * The `notification` property of AmService is enabled.

  * The delegate AccessTokenResolver provides the token metadata required to update the cache.

  When a refresh_token is revoked on AM, all associated access tokens are automatically and immediately revoked.

  ```json
  "cache": {
    "enabled": configuration expression<boolean>,
    "defaultTimeout": configuration expression<duration>,
    "maxTimeout": configuration expression<duration>,
    "amService": AmService reference,
    "onNotificationDisconnection": configuration expression<enumeration>
  }
  ```

  * `enabled`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Enable or disable caching.

    Default: `false`

  * `defaultTimeout`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

    The duration for which to cache an OAuth 2.0 access token if it doesn't provide a valid expiry value.

    If an access token provides an expiry value that falls *before* the current time plus the `maxTimeout`, IG uses the token expiry value.

    The following example caches access tokens for these times:

    * One hour, if the access token doesn't provide a valid expiry value.

    * The duration specified by the token expiry value, when the token expiry value is shorter than one day.

    * One day, when the token expiry value is longer than one day.

      ```json
      "cache": {
        "enabled": true,
        "defaultTimeout": "1 hour",
        "maxTimeout": "1 day"
      }
      ```

    Default: `1 minute`

  * `maxTimeout`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

    The maximum duration for which to cache OAuth 2.0 access tokens.

    If an access token provides an expiry value that falls *after* the current time plus the `maxTimeout`, IG uses the `maxTimeout`.

    The duration cannot be `zero` or `unlimited`.

  * `"amService"`: *AmService [reference](preface.html#definition-reference), optional*

    *(From AM 6.5.3.)* The [AmService](MiscellaneousConfigurationObjects.html#AmService) to use for the WebSocket notification service. To evict revoked access tokens from the cache, enable the `notifications` property of AmService.

  * `onNotificationDisconnection`: *configuration expression<[enumeration](preface.html#definition-enumeration)>, optional*

    An `amService` must be configured for this property to have effect.

    The strategy to manage the cache when the WebSocket notification service is disconnected, and IG receives no notifications for AM events. If the cache is not cleared it can become outdated, and IG can allow requests on revoked sessions or tokens.

    Cached entries that expire naturally while the notification service is disconnected are removed from the cache.

    Use one of the following values:

    * `NEVER_CLEAR`

      * When the notification service is disconnected:

        * Continue to use the existing cache.

        * Deny access for requests that are not cached, but do not update the cache with these requests.

      * When the notification service is reconnected:

        * Continue to use the existing cache.

        * Query AM for incoming requests that are not found in the cache, and update the cache with these requests.

    * `CLEAR_ON_DISCONNECT`

      * When the notification service is disconnected:

        * Clear the cache.

        * Deny access to all requests, but do not update the cache with these requests.

      * When the notification service is reconnected:

        * Query AM for all requests that are not found in the cache. (Because the cache was cleared, the cache is empty after reconnection.)

        * Update the cache with these requests.

    * `CLEAR_ON_RECONNECT`

      * When the notification service is disconnected:

        * Continue to use the existing cache.

        * Deny access for requests that are not cached, but do not update the cache with these requests.

      * When the notification service is reconnected:

        * Query AM for all requests that are not found in the cache. (Because the cache was cleared, the cache is empty after reconnection.)

        * Update the cache with these requests.

    Default: `CLEAR_ON_DISCONNECT`

* `"executor"`: *Executor service [reference](preface.html#definition-reference), optional*

  An executor service to schedule the execution of tasks, such as the eviction of entries in the access token cache.

  Default: `ScheduledExecutorService`

  See also [ScheduledExecutorService](MiscellaneousConfigurationObjects.html#ScheduledExecutorService).

- `"requireHttps"`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

  Whether to require that original target URI of the request (`originalUri` in [UriRouterContext](RequestsResponsesContexts.html#UriRouterContext)) uses the HTTPS scheme.

  If the request received by the web container is not using HTTPS, the request is rejected.

  Default: true.

* `"realm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  HTTP authentication realm to include in the WWW-Authenticate response header field when returning an HTTP 401 Unauthorized status to a user-agent that need to authenticate.

  Default: OpenIG

* `"scopes"`: *array of runtime expression<[strings](preface.html#definition-string)> or ScriptableResourceAccess <[reference](preface.html#definition-reference)>, required*

  A list of one of more scopes required by the OAuth 2.0 access token.

  * array of runtime expression<[strings](preface.html#definition-string)>, required if ScriptableResourceAccess is not used

    A string, array of strings, runtime expression\<string>, or array of runtime expression\<string> to represent one or more scopes.

  - ScriptableResourceAccess <[reference](preface.html#definition-reference)>, required if "array of runtime expression\<strings>" is not used

    A script that produces a list of one or more scopes.

    The script evaluates each request dynamically and returns the scopes that request needs to access the protected resource. The script must return a `Promise<Set, ResponseException>` or a [Set\<String>](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html).

    For information about the properties of ScriptableResourceAccess, see [Scripts](Scripts.html).

    ```json
    {
      "name": string,
      "type": "ScriptableResourceAccess",
      "config": {
        "type": configuration expression<string>,
        "file": configuration expression<string>, // Use either "file"
        "source": [ string, ... ],                // or "source", but not both.
        "args": object,
        "clientHandler": Handler reference
      }
    }
    ```

    Default: Empty

### Examples

For examples using OAuth2ResourceServerFilter, see [Act as an OAuth 2.0 resource server](../gateway-guide/oauth2-rs.html).

Defining required scopes by using a script

The following example uses a ScriptableResourceAccess object to define the scopes required in a request:

* If the request path is `/rs-tokeninfo`, only the scopes `mail` is required.

* If the request path is `/rs-tokeninfo/employee`, the scopes `mail` and `employeenumber` are required.

1. Set up and test the example in [Validate access tokens through the introspection endpoint](../gateway-guide/oauth2-rs.html#oauth2-rs-introspect).

2. Add the following route to IG:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/rs-dynamicscope.json
   ```

   ```
   %appdata%\OpenIG\rs-dynamicscope.json
   ```

   ```json
   {
     "name": "rs-dynamicscope",
     "baseURI": "http://app.example.com:8081",
     "condition": "${find(request.uri.path, '^/rs-dynamicscope')}",
     "heap": [
       {
         "name": "SystemAndEnvSecretStore-1",
         "type": "SystemAndEnvSecretStore"
       },
       {
         "name": "AmService-1",
         "type": "AmService",
         "config": {
           "agent": {
             "username": "ig_agent",
             "passwordSecretId": "agent.secret.id"
           },
           "secretsProvider": "SystemAndEnvSecretStore-1",
           "url": "http://am.example.com:8088/openam/",
           "version": "7.2"
         }
       }
     ],
     "handler": {
       "type": "Chain",
       "config": {
         "filters": [
           {
             "name": "OAuth2ResourceServerFilter-1",
             "type": "OAuth2ResourceServerFilter",
             "config": {
               "scopes": {
                 "name": "myscript",
                 "type": "ScriptableResourceAccess",
                 "config": {
                   "type": "application/x-groovy",
                   "source": [
                     "// Minimal set of required scopes",
                     "def scopes = [ 'mail' ] as Set",
                     "if (request.uri.path =~ /employee$/) {",
                     "  // Require another scope to access this resource",
                     "  scopes += 'employeenumber'",
                     "}",
                     "return scopes"
                   ]
                 }
               },
               "requireHttps": false,
               "realm": "OpenIG",
               "accessTokenResolver": {
                 "name": "token-resolver-1",
                 "type": "TokenIntrospectionAccessTokenResolver",
                 "config": {
                   "amService": "AmService-1",
                   "providerHandler": {
                     "type": "Chain",
                     "config": {
                       "filters": [
                         {
                           "type": "HttpBasicAuthenticationClientFilter",
                           "config": {
                             "username": "ig_agent",
                             "passwordSecretId": "agent.secret.id",
                             "secretsProvider": "SystemAndEnvSecretStore-1"
                           }
                         }
                       ],
                       "handler": "ForgeRockClientHandler"
                     }
                   }
                 }
               }
             }
           }
         ],
         "handler": {
           "type": "StaticResponseHandler",
           "config": {
             "status": 200,
             "headers": {
               "Content-Type": [ "text/html; charset=UTF-8" ]
             },
             "entity": "<html><body><h2>Decoded access_token: ${contexts.oauth2.accessToken.info}</h2></body></html>"
           }
         }
       }
     }
   }
   ```

3. Test the setup with the `mail` scope only:

   1. In a terminal, use a `curl` command to retrieve an access token:

      ```bash
      $ mytoken=$(curl -s \
      --user "client-application:password" \
      --data "grant_type=password&username=demo&password=Ch4ng31t&scope=mail" \
      http://am.example.com:8088/openam/oauth2/access_token | jq -r ".access_token")
      ```

   2. Confirm that the access token is returned for the `/rs-dynamicscope` path:

      ```bash
      $ curl -v http://ig.example.com:8080/rs-dynamicscope --header "Authorization: Bearer ${mytoken}"

      {
        active = true,
        scope = mail,
        client_id = client-application,
        user_id = demo,
        token_type = Bearer,
        exp = 158...907,
        sub = demo,
        iss = http://am.example.com:8088/openam/oauth2, ...
        ...
      }
      ```

      * Confirm that the access token **is not** returned for the `/rs-dynamicscope/employee` path:

        ```bash
        $ curl -v http://ig.example.com:8080/rs-dynamicscope/employee --header "Authorization: Bearer ${mytoken}"
        ```

4. Test the setup with the scopes `mail` and `employeenumber`:

   1. In a terminal window, use a `curl` command similar to the following to retrieve an access token:

      ```bash
      $ mytoken=$(curl -s \
      --user "client-application:password" \
      --data "grant_type=password&username=demo&password=Ch4ng31t&scope=mail%20employeenumber" \
      http://am.example.com:8088/openam/oauth2/access_token | jq -r ".access_token")
      ```

   2. Confirm that the access token **is** returned for the `/rs-dynamicscope/employee` path:

      ```bash
      $ curl -v http://ig.example.com:8080/rs-dynamicscope/employee --header "Authorization: Bearer ${mytoken}"
      ```

### More information

[org.forgerock.openig.filter.oauth2.OAuth2ResourceServerFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/OAuth2ResourceServerFilterHeaplet.html)

[org.forgerock.http.oauth2.OAuth2Context](../_attachments/apidocs/org/forgerock/http/oauth2/OAuth2Context.html)

[org.forgerock.http.oauth2.AccessTokenInfo](../_attachments/apidocs/org/forgerock/http/oauth2/AccessTokenInfo.html)

[OAuth2Context](RequestsResponsesContexts.html#OAuth2Context)

[ConfirmationKeyVerifierAccessTokenResolver](AccessTokenResolvers.html#ConfirmationKeyVerifierAccessTokenResolver)

[TokenIntrospectionAccessTokenResolver](AccessTokenResolvers.html#TokenIntrospectionAccessTokenResolver)

[StatelessAccessTokenResolver](AccessTokenResolvers.html#StatelessAccessTokenResolver)

[ScriptableAccessTokenResolver](AccessTokenResolvers.html#ScriptableAccessTokenResolver)

[The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)

[The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750)

## OAuth2TokenExchangeFilter

Identifies a client's access token or ID token (a *subject token*), and communicates with an authorization service, such as AM, to exchange it for a new token (an *issued token*):

* When the OAuth2TokenExchangeFilter succesfully exchanges a token, it injects the issued token and its scopes into the [OAuth2TokenExchangeContext](RequestsResponsesContexts.html#OAuth2TokenExchangeContext).

* When the OAuth2TokenExchangeFilter fails to exchange a token, it injects information about the failure into the [OAuth2FailureContext](RequestsResponsesContexts.html#OAuth2FailureContext), which is provided to the `failureHandler`.

The scopes for issued token can be *restricted* or *expanded* by the authorization services:

* Restricted when the token scopes are a subset of those available to the subject token.

* Expanded when they have scopes that are not included in the subject token.

Use this filter in the *impersonation* use case. For more information, see [OAuth 2.0 Token Exchange](https://docs.pingidentity.com/pingam/7.2/oauth2-guide/oauth2-token-exchange.html) in AM's *OAuth 2.0 guide*.

### Usage

```json
{
  "name": string,
  "type": "OAuth2TokenExchangeFilter",
    "config": {
      "subjectToken": runtime expression<string>,
      "amService": AmService reference,
      "endpoint": configuration expression<url>,
      "subjectTokenType": configuration expression<string>,
      "requestedTokenType": configuration expression<string>,
      "scopes": [ runtime expression<string>, ... ] or ScriptableResourceAccess reference,
      "resource": configuration expression<url>,
      "audience": configuration expression<string>,
      "endpointHandler": Handler reference,
      "failureHandler": Handler reference
  }
}
```

### Configuration

* `"subjectToken"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The location of the subject token in the inbound request.

* `"amService"`: *AmService [reference](preface.html#definition-reference), required if `endpoint` is not configured*

  The AmService to use as the authorization service.

  Configure either 'amService' or 'endpoint'. If both are configured, 'amService' takes precedence.

* `"endpoint"`: *configuration expression<[url](preface.html#definition-url)>, required if `amService` is not configured*

  The URI for the authorization service.

  Configure either 'amService' or 'endpoint'. If both are configured, 'amService' takes precedence.

* `"subjectTokenType"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The subject token type.

  Default: `URN_ACCESS_TOKEN`

* `"requestedTokenType"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The type of token being requested.

  Default: `URN_ACCESS_TOKEN`

* `"scopes"`: *array of runtime expression<[strings](preface.html#definition-string)> or ScriptableResourceAccess <[reference](preface.html#definition-reference)>, required*

  A list of one of more scopes required by the OAuth 2.0 access token.

  * array of runtime expression<[strings](preface.html#definition-string)>, required if ScriptableResourceAccess is not used

    A string, array of strings, runtime expression\<string>, or array of runtime expression\<string> to represent one or more scopes.

  - ScriptableResourceAccess <[reference](preface.html#definition-reference)>, required if "array of runtime expression\<strings>" is not used

    A script that produces a list of one or more scopes.

    The script evaluates each request dynamically and returns the scopes that request needs to access the protected resource. The script must return a `Promise<Set, ResponseException>` or a [Set\<String>](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html).

    For information about the properties of ScriptableResourceAccess, see [Scripts](Scripts.html).

    ```json
    {
      "name": string,
      "type": "ScriptableResourceAccess",
      "config": {
        "type": configuration expression<string>,
        "file": configuration expression<string>, // Use either "file"
        "source": [ string, ... ],                // or "source", but not both.
        "args": object,
        "clientHandler": Handler reference
      }
    }
    ```

    Default: Empty

* `"resource"`: *configuration expression<[url](preface.html#definition-url)>, optional*

  The target service URI where the issued token is intended to be used.

* `"audience"`: *configuration expression<[url](preface.html#definition-url)>, optional*

  The target service name where the token is intended to be used.

* `"endpointHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  The handler to exchange tokens on the authorization endpoint.

  Configure this property as a [Chain](Handlers.html#Chain), using one of the following filters for client authentication:

  * [ClientSecretBasicAuthenticationFilter](#ClientSecretBasicAuthenticationFilter)

  * [ClientSecretPostAuthenticationFilter](#ClientSecretPostAuthenticationFilter)

  * [EncryptedPrivateKeyJwtClientAuthenticationFilter](#EncryptedPrivateKeyJwtClientAuthenticationFilter)

  * [PrivateKeyJwtClientAuthenticationFilter](#PrivateKeyJwtClientAuthenticationFilter)

  ```json
  {
    "name": "EndpointHandler",
    "type": "Chain",
    "config": {
      "handler": "ForgeRockClientHandler",
      "filters": [
        {
          "type": "ClientSecretBasicAuthenticationFilter",
          "config": {
            "clientId": "serviceConfidentialClient",
            "clientSecretId": "client.secret.id",
            "secretsProvider" : "SystemAndEnvSecretStore-1",
          }
        }
      ]
    }
  }
  ```

  Default: ForgeRockClientHandler

* `"failureHandler"`: *Handler <[reference](preface.html#definition-reference)>, optional*

  Handler to manage a failed request.

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. The handler can access information in the [OAuth2FailureContext](RequestsResponsesContexts.html#OAuth2FailureContext).

  Default: `500 Internal Server Error`, the request stops being executed.

### Example

For an example of how this filter is used, see [OAuth 2.0 token exchange](../gateway-guide/token-exchange.html).

### More information

[org.forgerock.http.oauth2.OAuth2TokenExchangeFilter](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/OAuth2TokenExchangeFilter.html)

[OAuth2TokenExchangeContext](RequestsResponsesContexts.html#OAuth2TokenExchangeContext)

[OAuth2FailureContext](RequestsResponsesContexts.html#OAuth2FailureContext)

[The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)

## PasswordReplayFilter

For requests directed to a login page, this filter extracts credentials, and replays them.

Requests that are not directed to the login page are passed along to the next filter or handler in the chain.

The PasswordReplayFilter does not retry failed authentication attempts.

### Usage

```json
{
  "name": string,
  "type": "PasswordReplayFilter",
  "config": {
    "request": object,
    "loginPage": runtime expression<boolean>,
    "loginPageContentMarker": pattern,
    "credentials": Filter reference,
    "headerDecryption": object,
    "loginPageExtractions": [ object, ... ]
  }
}
```

### Properties

* `"request"`: *<[object](preface.html#definition-object)>, required*

  The HTTP request message that replays the credentials.

  ```json
  {
    "request": object,
      "method": config expression<string>,
      "uri": runtime expression<string>,
      "version": configuration expression<string>,
      "entity": runtime expression<string>,
      "headers": map,
      "form": map
  }
  ```

  For information about the properties of `request` see [Request](Request.html).

  The JSON object of `request` is the `config` content of a [StaticRequestFilter](#StaticRequestFilter).

* `"loginPage"`: *runtime expression<[boolean](preface.html#definition-boolean)>, required unless `loginPageContentMarker` is defined*

  `true`: Direct the request to a login page, extract credentials, and replay them.

  `false`: Pass the request unchanged to the next filter or handler in the chain.

  The following example expression resolves to `true` when the request is an HTTP GET, and the request URI path is `/login`:

  ```none
  ${find(request.uri.path, '/login') and (request.method == 'GET')}
  ```

* `"loginPageContentMarker"`: *[pattern](preface.html#definition-pattern), required unless `loginPage` is defined*

  A pattern that matches when a response entity is a login page.

  For an example route that uses this property, see [Login form with password replay and cookie filters](../gateway-guide/templates.html#template-login-replay-cookie-filters).

  See also [Patterns](Patterns.html).

* `"credentials"`: *Filter [reference](preface.html#definition-reference), optional*

  Filter that injects credentials, making them available for replay. Consider using a `FileAttributesFilter` or an `SqlAttributesFilter`.

  When this is not specified, credentials must be made available to the request by other means.

  See also [Filters](#).

* `"headerDecryption"`: *[object](preface.html#definition-object), optional*

  Object to decrypt request headers that contain credentials to replay.

  ```json
  {
    "headerDecryption": object,
      "algorithm": configuration expression<string>,
      "headers": [ configuration expression<string>, ... ],
      "keySecretId": configuration expression<secret-id>,
      "secretsProvider": SecretsProvider reference,
      "charset": configuration expression<string>,
      "key": string, //deprecated
      "keyType": string //deprecated
  }
  ```

  * `"algorithm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    Algorithm used for decryption. Use the same algorithm that is used to send the encrypted credentials.

    Default: `AES/ECB/PKCS5Padding`

  * `"headers"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

    The names of header fields to decrypt.

    Default: Do not decrypt any headers.

  * `"keySecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required*

    The secret ID of the key to encrypt or decrypt the headers. This property takes precedence over the deprecated property `key`.

  * `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

    The SecretsProvider to resolve queried secrets, such as passwords and cryptographic keys. For allowed formats, see [SecretsProvider](secrets.html#SecretsProvider).

  * `"charset"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    The name of the charset used to encrypt or decrypt values, as described in [Class Charset](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/charset/Charset.html).

    Default: `UTF-8`

  * `"key"`: *string, optional*

    |   |                                                                                                                                                                                        |
    | - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    |   | The use of this property is deprecated; use `keySecretId` and `secretsProvider` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

    Base64 encoded key value.

  * `"keyType"`: *string, required*

    |   |                                                                                                                                                                                        |
    | - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    |   | The use of this property is deprecated; use `keySecretId` and `secretsProvider` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

    Algorithm name for the secret key.

    Default: AES

* `"loginPageExtractions"`: *array of <[objects](preface.html#definition-object)>, optional*

  Objects to extract values from the login page entity.

  ```json
  {
    "loginPageExtractions": [
      {
        "name": string,
        "pattern": pattern
      },
      ...
    ]
  }
  ```

  For an example route that uses this property, see [Login which requires a hidden value from the login page](../gateway-guide/templates.html#template-login-hidden-value).

  The extract configuration array is a series of configuration objects. To extract multiple values, use multiple extract configuration objects. Each object has the following fields:

  * `"name"`: *[string](preface.html#definition-string), required*

    Name of the field where the extracted value is put.

    The names are mapped into `attributes.extracted`.

    For example, if the name is `nonce`, the value can be obtained with the expression `${attributes.extracted.nonce}`.

    The name `isLoginPage` is reserved to hold a boolean that indicates whether the response entity is a login page.

  * `"pattern"`: *[pattern](preface.html#definition-pattern), required*

    The regular expression pattern to find in the entity.

    The pattern must contain one capturing group. (If it contains more than one, only the value matching the first group is placed into `attributes.extracted`.)

    For example, suppose the login page entity contains a nonce required to authenticate, and the nonce in the page looks like `nonce='n-0S6_WzA2Mj'`. To extract `n-0S6_WzA2Mj`, set `"pattern": " nonce='(.*)'"`.

### Example

The following example authenticates requests using static credentials when the request URI path is `/login`. This PasswordReplayFilter example does not include any mechanism for remembering when authentication has already been successful, it simply replays the authentication every time that the request URI path is `/login`:

```json
{
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [{
        "type": "PasswordReplayFilter",
        "config": {
          "loginPage": "${request.uri.path == '/login'}",
          "request": {
            "method": "POST",
            "uri": "https://www.example.com:8444/login",
            "form": {
              "username": [
                "MY_USERNAME"
              ],
              "password": [
                "MY_PASSWORD"
              ]
            }
          }
        }
      }],
      "handler": "ReverseProxyHandler"
    }
  }
}
```

For additional examples, see [Configuration templates](../gateway-guide/templates.html), and the Javadoc for the PasswordReplayFilter class.

### More information

[org.forgerock.openig.filter.PasswordReplayFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/PasswordReplayFilterHeaplet.html)

## PolicyEnforcementFilter

Requests policy decisions from AM, which allows or denies the request based on the request context, the request URI, and the AM policies.

### Processing requests after a policy decision

After a policy decision, IG continues to process requests as follows:

* If the request is allowed, processing continues.

* If the request is denied with advices, IG checks whether it can respond to the advices. If IG can respond, it sends a redirect and information about how to meet the conditions in the advices.

  By default, the request is redirected to AM. If the SingleSignOnFilter property `loginEndpoint` is configured, the request is redirected to that endpoint.

* If the request is denied without advice, or if IG cannot respond to the advice, IG forwards the request to a `failureHandler` declared in the `PolicyEnforcementFilter`. If there is no `failureHandler`, IG returns a 403 Forbidden.

* If an error occurs during the process, IG returns 500 Internal Server Error.

### Using advices from policy decisions

Attributes and advices returned by the policy decision are stored in the `policyDecision` context. For information, see [PolicyDecisionContext](RequestsResponsesContexts.html#PolicyDecisionContext).

IG responds to the following advice types from AM:

* `AuthLevel`: The minimum authentication level at which a user-agent must authenticate to access a resource.

* `AuthenticateToService`: The name of an authorization chain or service to which a user-agent must authenticate to access a resource.

* `AuthenticateToRealm`: The name of a realm to which a user-agent must authenticate to access a resource.

* `AuthScheme`: The name of an authentication module to which a user-agent must authenticate to access a resource, the policy set name, and the authentication timeout.

* `Transaction`: The additional actions that a user-agent must perform before having a one-time access to the protected resource.

### Notes on configuring policies in AM

In the AM policy, remember to configure the `Resources` parameter with the URI of the protected application.

The request URI from IG must match the `Resources` parameter defined in the AM policy. If the URI of the incoming request is changed before it enters the policy filter (for example, by rebasing or scripting), remember to change the `Resources` parameter in AM policy accordingly.

### WebSocket notifications for policy changes

When WebSocket notifications are set up for changes to policies, IG receives a notification from AM when a policy decision is created, deleted, or updated.

For information about setting up WebSocket notifications, using them to clear the policy cache, and including them in the server logs, see [WebSocket Notifications](../maintenance-guide/tuning.html#amservice-websocket).

### Usage

```json
{
  "name": string,
  "type": "PolicyEnforcementFilter",
  "config": {
    "amService": AmService reference,
    "pepRealm": configuration expression<string>,
    "ssoTokenSubject": runtime expression<string>,
    "jwtSubject": runtime expression<string>,
    "claimsSubject": map,
    "cache": object,
    "application": configuration expression<string>,
    "environment": map,
    "failureHandler": Handler reference,
    "resourceUriProvider": ResourceUriProvider reference,
    "executor": Executor service reference //deprecated
  }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  The AmService object to use for the following properties:

  * `agent`, the credentials of the IG agent in AM. When the agent is authenticated, the token can be used for tasks such as getting the user's profile, making policy evaluations, and connecting to the AM notification endpoint.

  * `realm`: Realm of the IG agent in AM.

  * `url`, the URL of an AM service to use for session token validation and authentication.

  * `ssoTokenHeader`, the name of the HTTP header that provides the session token created by AM

  * `amHandler`, the handler to use when requesting policy decisions from AM.

  * `version`: The version of the AM server.

    The AM version is derived as follows, in order of precedence:

    * Discovered value: AmService discovers the AM version. If `version` is configured with a different value, AmService ignores the value of `version` and issues a warning.

    * Value in `version`: AmService cannot discover the AM version, and `version` is configured.

    * Default value of AM 6: AmService cannot discover the AM version, and `version` is not configured.

    See also [AmService](MiscellaneousConfigurationObjects.html#AmService).

* `"pepRealm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The AM realm where the policy set is located.

  Default: The realm declared for `amService`.

* `"ssoTokenSubject"`: \_runtime expression<[string](preface.html#definition-string)>, required if neither of the following properties are present: `jwtSubject`, `claimsSubject`

  The AM SSO or CDSSO token ID string for the subject making the request to the protected resource.

  `ssoTokenSubject` can take the following values:

  * `${contexts.ssoToken.value}`, when the SingleSignOnFilter is used for authentication

  * `${contexts.ssoToken.value}` or `${contexts.cdsso.token}`, when the CrossDomainSingleSignOnFilter is used for authentication

    When there is no SSO (API protection), `ssoTokenSubject` usually points to a header value such as `${request.headers.iPlanetDirectoryPro[0]}`, where `iPlanetDirectoryPro` is the name of the default AM session cookie. To find the name of your AM session cookie, see [Find the name of your AM session cookie](../gateway-guide/preface.html#am-session-cookie).

* `"jwtSubject"`: \_runtime expression<[string](preface.html#definition-string)>, required if neither of the following properties are present: `ssoTokenSubject`, `claimsSubject`

  The JWT string for the subject making the request to the protected resource.

  To use the raw id_token (base64, not decoded) returned by the OpenID Connect Provider during authentication, place an `AuthorizationCodeOAuth2ClientFilter` filter before the PEP filter, and then use `${attributes.openid.id_token}` as the expression value.

  See also [AuthorizationCodeOAuth2ClientFilter](#AuthorizationCodeOAuth2ClientFilter) and [Expressions](Expressions.html#Expressions).

* `"claimsSubject"`: *[map](preface.html#definition-map), required if neither of the following properties are present: `jwtSubject`, \`"ssoTokenSubject\`*

  A representation of JWT claims for the subject.

  The claim `"sub"` must be specified. Other claims are optional.

  The map can be structured as follows:

  * As a runtime expression of a map, where the evaluation is an object of type `Map<String, Object>`.

  * As a map whose key is a string, and whose value is a runtime expression.

  Examples

  ```json
  "claimsSubject": "${attributes.openid.id_token_claims}"
  ```

  ```json
  "claimsSubject": {
    "sub": "${attributes.subject_identifier}",
    "iss": "am.example.com"
  }
  ```

  For an example of using `claimsSubject` as a map, see [Example Policy Enforcement Using claimsSubject](#PEF-example) on this reference page.

* `"application"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The ID of the AM policy set to use when requesting policy decisions.

  Default: `iPlanetAMWebAgentService`, provided by AM's default policy set

* `cache`: *[object](preface.html#definition-object), optional*

  Enable and configure caching of policy decisions from AM, based on *Caffeine*. For more information, see the GitHub entry, [Caffeine](https://github.com/ben-manes/caffeine).

  ```json
  {
    "cache": {
      "enabled": configuration expression<boolean>,
      "defaultTimeout": configuration expression<duration>,
      "executor": Executor service reference,
      "maximumSize": configuration expression<number>,
      "maximumTimeToCache": configuration expression<duration>,
      "onNotificationDisconnection": configuration expression<enumeration>
    }
  }
  ```

  Default: Policy decisions are not cached.

  |   |                                                         |
  | - | ------------------------------------------------------- |
  |   | Policy decisions that contain advices are never cached. |

  The following code example caches AM policy decisions without advices for these times:

  * One hour, when the policy decision doesn't provide a `ttl` value.

  * The duration specified by the `ttl`, when `ttl` is shorter than one day.

  * One day, when `ttl` is longer than one day.

  ```json
  "cache": {
    "enabled": true,
    "defaultTimeout": "1 hour",
    "maximumTimeToCache": "1 day"
  }
  ```

  * `enabled`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    Enable or disable caching of policy decisions.

    When a policy decision is cached, IG can reuse the policy decision without repeatedly asking AM for a new policy decision. When caching is disabled, IG must ask AM to make a decision for each request.

    Default: `false`

  * `defaultTimeout`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

    The default duration for which to cache AM policy decisions.

    If an AM policy decision provides a valid `ttl` value to specify the time until which the policy decision remains valid, IG uses that value or the `maxTimeout`.

    Default: `1 minute`

  * `"executor"`: *Executor service [reference](preface.html#definition-reference), optional*

    An executor service to schedule the execution of tasks, such as the eviction of entries in the cache.

    Default: `ForkJoinPool.commonPool()`

  * `"maximumSize"`: *configuration expression<[number](preface.html#definition-number)>, optional*

    The maximum number of entries the cache can contain.

    Default: Unlimited/unbound.

  * `maximumTimeToCache`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

    The maximum duration for which to cache AM policy decisions.

    If the `ttl` value provided by the AM policy decision is after the current time plus the `maximumTimeToCache`, IG uses the `maximumTimeToCache`.

    The duration cannot be `zero` or `unlimited`.

  * `onNotificationDisconnection`: *configuration expression\<enumeration>, optional*

    The strategy to manage the cache when the WebSocket notification service is disconnected, and IG receives no notifications for AM events. If the cache is not cleared it can become outdated, and IG can allow requests on revoked sessions or tokens.

    Cached entries that expire naturally while the notification service is disconnected are removed from the cache.

    Use one of the following values:

    * `NEVER_CLEAR`

      * When the notification service is disconnected:

        * Continue to use the existing cache.

        * Deny access for requests that are not cached, but do not update the cache with these requests.

      * When the notification service is reconnected:

        * Continue to use the existing cache.

        * Query AM for incoming requests that are not found in the cache, and update the cache with these requests.

    * `CLEAR_ON_DISCONNECT`

      * When the notification service is disconnected:

        * Clear the cache.

        * Deny access to all requests, but do not update the cache with these requests.

      * When the notification service is reconnected:

        * Query AM for all requests that are not found in the cache. (Because the cache was cleared, the cache is empty after reconnection.)

        * Update the cache with these requests.

    * `CLEAR_ON_RECONNECT`

      * When the notification service is disconnected:

        * Continue to use the existing cache.

        * Deny access for requests that are not cached, but do not update the cache with these requests.

      * When the notification service is reconnected:

        * Query AM for all requests that are not found in the cache. (Because the cache was cleared, the cache is empty after reconnection.)

        * Update the cache with these requests.

    Default: `CLEAR_ON_DISCONNECT`

* `"environment"`: *[map](preface.html#definition-map), optional*

  Strings to forward to AM with the a policy decision request, to represent the environment (or context) of the request. Forward any HTTP header or any value that the AM policy definition can use.

  The map can be structured as follows:

  * As a runtime expression of a map, where the evaluation is an object of type `Map<String, Object>`.

  * As a map whose key is a string, and whose value is a runtime expression.

  AM can use the environment conditions to set the circumstances under which a policy applies. For example, environment conditions can specify that the policy applies only during working hours or only when accessing from a specific IP address.

  In the following example, the `PolicyEnforcementFilter` forwards standard and non-standard request headers, an ID token, and the IP address of the subject making the request:

  ```json
  "environment": {
    "H-Via": "${request.headers['Via']}",
    "H-X-Forwarded-For": "${request.headers['X-Forwarded-For']}",
    "H-myHeader": "${request.headers['myHeader']}",
    "id_token": [
      "${attributes.openid.id_token}"
    ],
    "IP": [
      "${contexts.client.remoteAddress}"
    ]
  }
  ```

* `"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  Handler to treat the request if it is denied by the policy decision.

  In the following example, the `failureHandler` is a chain with a scriptable filter. If there are some advices with the policy decision, the script recovers the advices for processing. Otherwise, it passes the request to the `StaticResponseHandler` to display a message.

  ```json
  "failureHandler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "ScriptableFilter",
          "config": {
            "type": "application/x-groovy",
            "source": [
              "if (contexts.policyDecision.advices['MyCustomAdvice'] != null) {",
              "  return handleCustomAdvice(context, request)",
              "} else {",
              "  return next.handle(context, request)",
              "}"
            ]
          }
        }
      ],
      "handler": {
        "type": "StaticResponseHandler",
        "config": {
          "status": 403,
          "headers": {
            "Content-Type": [ "text/plain; charset=UTF-8" ]
          },
          "entity": "Restricted area. You do not have sufficient privileges."
        }
      }
    }
  }
  ```

  Provide an inline handler configuration object, or the name of a handler object declared in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 403 Forbidden, the request stops being executed.

* `"resourceUriProvider"`: *ResourceUriProvider [reference](preface.html#definition-reference), optional*

  Return the resource URL to include in policy decision requests to AM. Configure one of the following ResourceUriProviders inline or in the heap:

  * `RequestResourceUriProvider`

  * `ScriptableResourceUriProvider`

  Default: `RequestResourceUriProvider`

  * `RequestResourceUriProvider`

    Return a resource URL to include in policy decision requests to AM, by using the original URI of the request or the `baseURI` of the route.

    ```json
    "resourceUriProvider": {
      "type": "RequestResourceUriProvider",
      "config": {
        "useOriginalUri": configuration expression<boolean>,
        "includeQueryParams": configuration expression<boolean>
      }
    }
    ```

    * `useOriginalUri`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

      A flag to use the original URI of the request as the resource URL in policy decision requests to AM.

      * `true`: Use the original URI of the request as the resource URL when requesting policy decisions from AM.

      * `false`: Use the `baseURI` of the route as the resource URL when requesting policy decisions from AM.

      Default: `false`

    * `includeQueryParams`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

      A flag to include query parameters in the resource URL when requesting policy decisions from AM:

      * `true`: Include query parameters in the resource URL. For example, use the following URL with a query parameter: `http://ig.example.com:8080/login?demo=capture`.

      * `false`: Exclude query parameters from the resource URL. For example, exclude the query parameter from the previous example: `http://ig.example.com:8080/login`.

        For AM policies that specify resource URLs without query parameters, use this option to reduce the amount of cached information.

      Default: `true`

  * `ScriptableResourceUriProvider`

    Use a script to return a resource URL to include in policy decision requests to AM. The result of the script must be a string that represents the resource URL.

    ```json
    "resourceUriProvider": {
      "type": "ScriptableResourceUriProvider",
      "config": {
        "type": configuration expression<string>,
        "file": configuration expression<string>, // Use either "file"
        "source": [ string, ... ],                // or "source", but not both.
        "args": object,
        "clientHandler": Handler reference
      }
    }
    ```

    For information about these properties, see [Scripts](Scripts.html).

    The following example script replaces existing query parameters with a single parameter:

    ```json
    "resourceUriProvider": {
      "type": "ScriptableResourceUriProvider",
      "config": {
        "type": "application/x-groovy",
        "source": [
          "request.uri.setQuery('fromIG=true')",
          "return request.uri.toASCIIString()"
        ]
      }
    }
    ```

* `"executor"`: *Executor service [reference](preface.html#definition-reference), optional*

  |   |                                                                                                                                                                            |
  | - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | This property is deprecated; use the `cache` subproperty `executor` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  An executor service to schedule the execution of tasks, such as the eviction of entries in the cache.

  Default: `ForkJoinPool.commonPool()`

### Example policy enforcement using claimsSubject

This route is a variant of the route in [Enforce AM policy decisions in the same domain](../gateway-guide/pep.html#pep-sso). It enforces a policy decision from AM, using `claimsSubject` instead of `ssoTokenSubject` to identify the subject.

To use this route:

1. Set up AM as described in [Enforce AM policy decisions in the same domain](../gateway-guide/pep.html#pep-sso).

2. In AM, select the policy you created in the previous step, and add a new resource:

   * Resource Type: `URL`

   * Resource pattern: `*://*:*/*`

   * Resource value: `http://app.example.com:8081/home/pep-claims`

3. In the same policy, add the following subject condition:

   * `Any of`

   * Type : `OpenID Connect/JwtClaim`

   * claimName : `iss`

   * claimValue : `am.example.com`

4. Set an environment variable for the IG agent password, and then restart IG:

   ```bash
   $ export AGENT_SECRET_ID='cGFzc3dvcmQ='
   ```

   The password is retrieved by a SystemAndEnvSecretStore, and must be base64-encoded.

5. Add the following route to serve static resources, such as .css, for the sample application:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/static-resources.json
   ```

   ```
   %appdata%\OpenIG\config\routes\static-resources.json
   ```

   ```json
   {
     "name" : "sampleapp-resources",
     "baseURI" : "http://app.example.com:8081",
     "condition": "${find(request.uri.path,'^/css')}",
     "handler": "ReverseProxyHandler"
   }
   ```

6. Add the following route to IG:

   * Linux

   * Windows

   ```
   $HOME/.openig/config/routes/04-pep-claims.json
   ```

   ```
   %appdata%\OpenIG\config\routes\04-pep-claims.json
   ```

   ```json
   {
     "name": "pep-claims",
     "baseURI": "http://app.example.com:8081",
     "condition": "${find(request.uri.path, '^/home/pep-claims')}",
     "heap": [
       {
         "name": "SystemAndEnvSecretStore-1",
         "type": "SystemAndEnvSecretStore"
       },
       {
         "name": "AmService-1",
         "type": "AmService",
         "config": {
           "url": "http://am.example.com:8088/openam",
           "agent": {
             "username": "ig_agent",
             "passwordSecretId": "agent.secret.id"
           },
           "secretsProvider": "SystemAndEnvSecretStore-1",
           "version": "7.2"
         }
       }
     ],
     "handler": {
       "type": "Chain",
       "config": {
         "filters": [
           {
             "name": "SingleSignOnFilter-1",
             "type": "SingleSignOnFilter",
             "config": {
               "amService": "AmService-1"
             }
           },
           {
             "name": "PolicyEnforcementFilter-1",
             "type": "PolicyEnforcementFilter",
             "config": {
               "application": "PEP-SSO",
               "claimsSubject": {
                 "sub": "${contexts.ssoToken.info.uid}",
                 "iss": "am.example.com"
               },
               "amService": "AmService-1"
             }
           }
         ],
         "handler": "ReverseProxyHandler"
       }
     }
   }
   ```

7. Go to <http://ig.example.com:8080/home/pep-claims>.

8. Log in to AM as user `demo`, password `Ch4ng31t`.

   AM returns a policy decision that grants access to the sample application.

### More information

[org.forgerock.openig.openam.PolicyEnforcementFilter](../_attachments/apidocs/org/forgerock/openig/openam/PolicyEnforcementFilter.html)

[org.forgerock.openig.openam.PolicyDecisionContext](../_attachments/apidocs/org/forgerock/openig/openam/PolicyDecisionContext.html)

[PolicyDecisionContext](RequestsResponsesContexts.html#PolicyDecisionContext)

AM's [Authorization guide](https://docs.pingidentity.com/pingam/7.2/authorization-guide/index.html)

## PrivateKeyJwtClientAuthenticationFilter

Supports client authentication with the `private_key_jwt` client-assertion, using an unencrypted JWT.

Clients send a signed JWT to the authorization server. IG builds and signs the JWT, and prepares the request as in the following example:

```http
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=...&
client_id=<clientregistration_id>&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
client_assertion=PHNhbWxwOl ... ZT
```

Use this filter with an endpoint handler that requires authentication with the with the `private_key_jwt` client-assertion, using an unencrypted JWT. For example, the `endpointHandler` handler in the [OAuth2TokenExchangeFilter](#OAuth2TokenExchangeFilter).

### Usage

```json
{
  "name": string,
  "type": "PrivateKeyJwtClientAuthenticationFilter",
  "config": {
    "clientId": configuration expression<string>,
    "tokenEndpoint": configuration expression<url>,
    "secretsProvider": SecretsProvider reference,
    "signingSecretId": configuration expression<secret-id>,
    "signingAlgorithm": configuration expression<string>,
    "jwtExpirationTimeout": configuration expression<duration>,
    "claims": map
  }
}
```

### Configuration

* `"clientId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The `client_id` obtained when registering with the authorization server.

* `"tokenEndpoint"`: *configuration expression<[url](preface.html#definition-url)>, required*

  The URL to the authorization server's OAuth 2.0 token endpoint.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The SecretsProvider to resolve queried secrets, such as passwords and cryptographic keys. For allowed formats, see [SecretsProvider](secrets.html#SecretsProvider).

* `"signingSecretId"`: *configuration expression<[string](preface.html#definition-string)>, required*

  Reference to the keys used to sign the JWT.

* `"signingAlgorithm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The JSON Web Algorithm (JWA) used to sign the JWT, such as:

  * `RS256`: RSA using SHA-256

  * `ES256`: ECDSA with SHA-256 and NIST standard P-256 elliptic curve

  * `ES384`: ECDSA with SHA-384 and NIST standard P-384 elliptic curve

  * `ES512`: ECDSA with SHA-512 and NIST standard P-521 elliptic curve

  Default: `RS256`

* `"jwtExpirationTimeout"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

  The duration for which the JWT is valid.

  Default: 1 minute

* `"claims"`: *[map](preface.html#definition-map), optional*

  The claims used in the authentication.

  The map can be structured as follows:

  * As a configuration expression of a map, where the evaluation is an object of type `Map<String, Object>`.

  * As a map whose key is a string, and whose values are configuration expressions.

  Default: Empty

## ResourceOwnerOAuth2ClientFilter

|   |                                                                                                                                                                                                                                                                                                                                                                                                               |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | This filter uses the *Resource Owner Password Credentials* grant type. According to information in the [The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749#section-10.7), minimize use of this grant type and utilize other grant types whenever possible. Use this filter in a service-to-service context, where services need to access resources protected by OAuth 2.0. |

Authenticates OAuth 2.0 clients by using the resource owner's OAuth 2.0 credentials to obtain an access token from an authorization server, and injecting the access token into the inbound request as a Bearer Authorization header.

Client authentication is provided by the `endpointHandler` property, which uses a client authentication filter.

The ResourceOwnerOAuth2ClientFilter refreshes the access token as required.

For more information, see [RFC 6749 - Resource Owner Password Grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3).

### Usage

```json
{
  "name": string,
  "type": "ResourceOwnerOAuth2ClientFilter",
  "config": {
    "username": configuration expression<string>,
    "passwordSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference,
    "tokenEndpoint": configuration expression<url>,
    "scopes": [ configuration expression<string>, ... ],
    "endpointHandler": Handler reference
  }
}
```

### Properties

* `"username"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The resource owner username to supply during authentication.

* `"passwordSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required*

  The secret ID to obtain the resource owner password.

* `"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

  The SecretsProvider to resolve queried secrets, such as passwords and cryptographic keys. For allowed formats, see [SecretsProvider](secrets.html#SecretsProvider).

- `"tokenEndpoint"`: *configuration expression<[url](preface.html#definition-url)>, required*

  The URL to the authorization server's OAuth 2.0 token endpoint.

- `"scopes"`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

  Array of scope strings to request from the authorization server.

  Default: Empty, request no scopes.

- `"endpointHandler"`: *Handler [reference](preface.html#definition-reference), optional*

  The Handler to exchange tokens on the authorization endpoint.

  Configure this property as a [Chain](Handlers.html#Chain), using one of the following client authentication filters:

  * [ClientSecretBasicAuthenticationFilter](#ClientSecretBasicAuthenticationFilter)

  * [ClientSecretPostAuthenticationFilter](#ClientSecretPostAuthenticationFilter)

  * [PrivateKeyJwtClientAuthenticationFilter](#PrivateKeyJwtClientAuthenticationFilter)

  ```json
  {
    "name": "myHandler",
    "type": "Chain",
    "config": {
      "handler": "ForgeRockClientHandler",
      "filters": [
        {
          "type": "ClientSecretBasicAuthenticationFilter",
          "config": {
            "clientId": "myConfidentialClient",
            "clientSecretId": "my.client.secret.id",
            "secretsProvider" : "mySystemAndEnvSecretStore",
          }
        }
      ]
    }
  }
  ```

  Default: ForgeRockClientHandler

### Examples

For an example, see [Using OAuth 2.0 resource owner password credentials](../gateway-guide/oauth2-resourceowner.html).

### More information

[org.forgerock.openig.filter.oauth2.client.ResourceOwnerOAuth2ClientFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/client/ResourceOwnerOAuth2ClientFilterHeaplet.html)

[org.forgerock.openig.filter.oauth2.OAuth2ResourceServerFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/oauth2/OAuth2ResourceServerFilterHeaplet.html)

[OAuth2ResourceServerFilter](#OAuth2ResourceServerFilter)

[The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749)

[The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750)

## ScriptableFilter

Processes requests and responses by using a Groovy script.

When a ScriptableFilter processes a request, it can execute `return next.handle(context, request)` to call the next filter or handler in the current chain and return the value from the call. Actions on the response must be performed in the Promise's callback methods.

Scripts must return a [Promise\<Response, NeverThrowsException>](../_attachments/apidocs/org/forgerock/util/promise/Promise.html) or a [Response](../_attachments/apidocs/org/forgerock/http/protocol/Response.html).

This section describes the usage of ScriptableFilter, and refers to the following sections of the documentation:

* For information about script properties, available global objects, and automatically imported classes, see [Scripts](Scripts.html).

* For information about creating scriptable objects in Studio, see [Scripts in Studio](../gateway-guide/extending.html#scripting-studio) and [Configure scriptable throttling](../gateway-guide/throttling.html#throttling-scriptable).

### Usage

```json
{
    "name": string,
    "type": "ScriptableFilter",
    "config": {
        "type": configuration expression<string>,
        "file": configuration expression<string>, // Use either "file"
        "source": [ string, ... ],                // or "source", but not both.
        "args": map,
        "clientHandler": Handler reference
    }
}
```

### Properties

For information about properties for ScriptableFilter, see [Scripts](Scripts.html).

### Examples

For an example scriptable filter that recovers policy advices from AM, see the `failureHandler` property of [PolicyEnforcementFilter](#PolicyEnforcementFilter).

### More information

[Scripts](Scripts.html)

[org.forgerock.openig.filter.ScriptableFilter](../_attachments/apidocs/org/forgerock/openig/filter/ScriptableFilter.html)

## SessionInfoFilter

Calls the AM endpoint for session information, and makes the data available as a new context to downstream IG filters and handlers. For information, see [SessionInfoContext](RequestsResponsesContexts.html#SessionInfoContext).

### WebSocket notifications for sessions

When WebSocket notifications are set up for sessions, IG receives a notification from AM when a user logs out of AM, or when the AM session is modified, closed, or times out. IG then evicts entries that are related to the event from the `sessionCache`.

For information about setting up WebSocket notifications, using them to clear the session cache, and including them in the server logs, see [WebSocket notifications](../maintenance-guide/tuning.html#amservice-websocket).

### Usage

```json
{
  "name": string,
  "type": "SessionInfoFilter",
  "config": {
    "amService": AmService reference,
    "ssoToken": runtime expression<string>
  }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  The [AmService](AmService.html) object to use for communication with AM.

  The following `sessionProperties`, are retrieved from AM:

  * When `sessionProperties` in AmService is configured, listed session properties with a value.

  * When `sessionProperties` in AmService is not configured, all session properties with a value.

  * Properties with a value that are required by IG but not specified by `sessionProperties` in AmService. For example, when the session cache is enabled, session properties related to the cache are automatically retrieved.

  Properties with a value are returned, properties with a null value are not returned.

* `"ssoToken"`: *runtime expression<[string](preface.html#definition-string)>, optional*

  Location of the AM SSO or CDSSO token.

  This property can take the following values:

  * `${contexts.ssoToken.value}`, when the SingleSignOnFilter is used for authentication

  * `${contexts.ssoToken.value}` or `${contexts.cdsso.token}`, when the CrossDomainSingleSignOnFilter is used for authentication

  * `${request.headers['mySsoToken'][0]}`, where the SSO or CDSSO token is the first value of the `mySsoToken` header in the request.

  Default: `${request.cookies['AmService-ssoTokenHeader'][0].value}`, where `AmService-ssoTokenHeader` is the name of the header or cookie where the AmService expects to find SSO or CDSSO tokens.

### Examples

For an example that uses the SessionInfoFilter, see [Retrieve a username from the sessionInfo context](../gateway-guide/profile-am.html#UserProfileFilter-retrieve-username-sessinfo).

### More information

[org.forgerock.openig.openam.SessionInfoFilter](../_attachments/apidocs/org/forgerock/openig/openam/SessionInfoFilter.html)

[org.forgerock.openig.openam.SessionInfoContext](../_attachments/apidocs/org/forgerock/openig/openam/SessionInfoContext.html)

[SessionInfoContext](RequestsResponsesContexts.html#SessionInfoContext)

AM's [Authorization guide](https://docs.pingidentity.com/pingam/7.2/authorization-guide/)

## SetCookieUpdateFilter

Updates the attribute values of Set-Cookie headers in a cookie. This filter facilitates the transition to the SameSite and secure cookie settings required by newer browsers. Use SetCookieUpdateFilter at the beginning of a chain to guarantee security along the chain.

Set-Cookie headers must conform to grammar in [RFC 6265: Set-Cookie](https://www.rfc-editor.org/rfc/rfc6265#section-4.1).

### Usage

```json
{
  "name": string,
  "type": "SetCookieUpdateFilter",
  "config": {
   "cookies": {
     "cookie-name": {
       "attribute-name": "attribute-value",
       ...
     }
     ...
   }
 }
}
```

### Properties

* `"cookies"`: *[map](preface.html#definition-map), required*

  Configuration that matches case-sensitive cookie names to response cookies, and specifies how matching cookies attribute values should be updated. Each cookie begins with a name-value pair, where the value is one or more attribute-value pairs.

  * cookie-name: *[pattern](preface.html#definition-pattern), required*

    The name of a cookie contained in the `Set-Cookie` header, as a pattern.

    To change the attribute value on all existing cookies, specify `.*`.

    If a cookie is named more than once, either explicitly or by the wildcard (`*`), the rules are applied to the cookie in the order they appear in the map.

    In the following example, the SameSite attribute of the CSRF cookie first takes the value `none`, and then that value is overwritten by the value `LAX`.

    ```json
    "cookies": {
      "CSRF": {
        "value": "myValue",
        "secure": ${true},
        "SameSite": "none"
      }
      ".*": {
        "SameSite": "LAX"
      }
    }
    ```

  * attribute-name: *[enumeration](preface.html#definition-enumeration), required*

    A case-insensitive enumeration of a Set-Cookie attribute name.

    Attribute names include `SameSite`, `secure`, `http-only`, `value`, `expires`, `Max-Age`, `path`, and `domain`. For more information, see [RFC 6265: Set-Cookie](https://www.rfc-editor.org/rfc/rfc6265#section-4.1).

  * attribute-value: *runtime expression\<string, boolean, or integer>, required*

    The replacement value for the named attribute. The value must conform to the expected type for the attribute name:

    * `secure`: runtime expression\<boolean>. Required if `SameSite` is `none`

    * `http-only`: runtime expression\<boolean>.

    * `Max-Age`: runtime expression<[number](preface.html#definition-number)>.

    * `SameSite`, and all other attribute names: runtime expression\<string>.

    For all values except `expires`, specify `${previous}` to reuse the existing value for the attribute. The following example adds five seconds to the `Max-Age` attribute:

    ```json
    "Max-Age": "${integer(previous+5)}",
    ```

    If the named the Set-Cookie header doesn't contain the named attribute, `${previous}` returns null.

### Examples

The following example updates attributes of all existing Set-Cookie headers:

```json
{
  "name": "SetCookieUpdateFilter",
  "condition": "${find(request.uri.path, '/home')}",
  "baseURI": "http://app.example.com:8081",
  "heap": [],
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [{
        "type": "SetCookieUpdateFilter",
        "config": {
          "cookies": {
            ".*": {
              "SameSite": "LAX",
              "domain": "ig.example.com",
              "Max-Age": "${session.maxAge}",
              "Secure": "${true}"
            }
          }
        }
      }],
      "handler": "ReverseProxyHandler"
    }
  }
}
```

### More information

[org.forgerock.openig.filter.SetCookieUpdateFilter](../_attachments/apidocs/org/forgerock/openig/filter/SetCookieUpdateFilter.html)

## SingleSignOnFilter

Tests for the presence and validity of an SSO token in the cookie header of a request:

* If an SSO token is present, the filter calls AM to validate the SSO token. If the SSO token is valid, the request continues along the chain. The token value and additional information are stored in the `ssoToken` context. For information, see [SsoTokenContext](RequestsResponsesContexts.html#SsoTokenContext).

* If the SSO token is not present, or is empty or invalid, IG checks the `goto` query parameter for the presence of the redirection marker:

  * If the redirection marker parameter is present (for example, `_ig=true`), IG fails the request because the cookie domain is incorrectly configured.

  * If the redirection marker is not present, IG redirects the user-agent to the AM login page or another provided login page. For information about enabling, disabling, and naming the redirection marker, see the `redirectionMarker` property on this page.

For more information about SSO, see [Single sign-on and cross-domain single sign-on](../gateway-guide/sso.html).

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | To prevent issues with performance when accessing large resources, such as .jpg and .js files, consider using the SingleSignOnFilter with the following options:- The `sessionCache`, so that IG can reuse session token information without repeatedly asking AM to verify the session token.

- A ConditionalFilter, so that requests to access large resources skip the SingleSignOnFilter. For an example configuration, see the example in [ConditionalFilter](#ConditionalFilter). |

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | When AM is using CTS-based sessions, it does not monitor idle time for client-side sessions, and so refresh requests are ignored.When the SingleSignOnFilter is used for authentication with AM, after a time AM can view the session as idle even though the user continues to interact with IG. The user session can eventually time out.*(From AM 6.5.3.)* When AM is using CTS-based sessions, use the `sessionIdleRefresh` property of AmService to refresh idle sessions, and prevent unwanted timeouts. |

### WebSocket notifications for sessions

When WebSocket notifications are set up for sessions, IG receives a notification from AM when a user logs out of AM, or when the AM session is modified, closed, or times out. IG then evicts entries that are related to the event from the `sessionCache`.

For information about setting up WebSocket notifications, using them to clear the session cache, and including them in the server logs, see [WebSocket notifications](../maintenance-guide/tuning.html#amservice-websocket).

### Usage

```json
{
  "name": string,
  "type": "SingleSignOnFilter",
    "config": {
      "amService": AmService reference,
      "authenticationService": configuration expression<string>,
      "redirectionMarker": object,
      "realm": configuration expression<string>,
      "defaultLogoutLandingPage": configuration expression<url>,
      "loginEndpoint": runtime expression<url>,
      "logoutExpression": runtime expression<boolean>,
      "logoutEndpoint": pattern //deprecated
  }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  An AmService object to use for the following properties:

  * `agent`, the credentials of the IG agent in AM. When the agent is authenticated, the token can be used for tasks such as getting the user's profile, making policy evaluations, and connecting to the AM notification endpoint.

  * `realm`: Realm of the IG agent in AM.

  * `url`, the URL of an AM service to use for session token validation and authentication when `loginEndpoint` is not specified.

  * `ssoTokenHeader`, the name of the cookie that contains the session token created by AM.

  * `amHandler`, the handler to use when communicating with AM to validate the token in the incoming request.

  * `sessionCache`, the configuration of a cache for session information from AM.

  * `version`: The version of the AM server.

    The AM version is derived as follows, in order of precedence:

    * Discovered value: AmService discovers the AM version. If `version` is configured with a different value, AmService ignores the value of `version` and issues a warning.

    * Value in `version`: AmService cannot discover the AM version, and `version` is configured.

    * Default value of AM 6: AmService cannot discover the AM version, and `version` is not configured.

- `redirectionMarker`: *[object](preface.html#definition-object), optional*

  ```json
  "redirectionMarker": {
     "enabled": configuration expression<boolean>,
     "name": configuration expression<string>
  }
  ```

  * `enabled`: *configuration expression<[boolean](preface.html#definition-boolean)>, optional*

    When `true`, use a redirection marker to limit the number of authentication redirects.

    When there is no SSO session due to, for example, SSO cookie name misconfiguration, an authentication request fails and is redirected back to IG. The scenario can result in infinite authentication redirects.

Consider enabling the redirection marker during development, then disabling it to prevent it being captured in bookmarks.

\+ Default: `true`

* `name`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The name of the redirection marker query parameter to use when `enabled` is `true`.

  Default: `_ig`

- `"authenticationService"`: *configuration expression<[string](preface.html#definition-string)>,optional*

  The name of an AM authentication tree or authentication chain to use for authentication.

  Default: AM's default authentication service.

  For an example that uses `authenticationService`, see [Authenticate with SSO through an AM authentication tree](../gateway-guide/sso.html#proc-sso-authservice).

  For more information about authentication trees and chains, see [Authentication nodes and trees](https://docs.pingidentity.com/pingam/7.2/authentication-guide/about-authentication-trees.html) and [Authentication modules and chains](https://docs.pingidentity.com/pingam/7.2/authentication-guide/about-authentication-modules-and-chains.html) in AM's *Authentication and SSO* guide.

- `"realm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The AM realm where the user is authenticated.

  Default: The realm declared for `amService`.

* `"defaultLogoutLandingPage"`: *configuration expression<[url](preface.html#definition-url)>, optional*

  The URL to which a request is redirected if `logoutExpression` is evaluated as true.

  If this property is not an absolute URL, the request is redirected to the IG domain name.

  This parameter is effective only when `logoutExpression` is specified.

  Default: None, processing continues.

* `"loginEndpoint"`: *runtime expression<[url](preface.html#definition-url)>, optional*

  The URL of a service instance for the following tasks:

  * Manage authentication and the location to which the request is redirected after authentication.

  * Process policy advices after an AM policy decision denies a request with supported advices. The PolicyEnforcementFilter redirects the request to this URL, with information about how to meet the conditions in the advices.

    For examples of different advice types, and the conditions that cause AM to return advices, see AM's [Authorization guide](https://docs.pingidentity.com/pingam/7.2/authorization-guide/). For information about supported advice types in IG, see [Using Advices From Policy Decisions](#pef-advices).

    Default: The value of `url` in `amService`

  Authentication can be performed in the following ways:

  * Directly through AM, with optional authentication parameters in the query string, such as `service`, `module`, and `realm`. For a list of authentication parameters that you can include in the query string, see [Authenticating (browser)](https://docs.pingidentity.com/pingam/7.2/authentication-guide/authn-from-browser.html) in AM's *Authentication and SSO* guide.

    The value must include a redirect with a `goto` parameter.

    The following example uses AM as the authentication service, and includes the `service` authentication parameter:

    ```json
    "loginEndpoint": "https://am.example.com/openam?service=TwoFactor&goto=${urlEncodeQueryParameterNameOrValue(contexts.router.originalUri)}"
    ```

  * Through the URL of another application, with optional authentication parameters in the query string, such as `service`, `module`, and `realm`. The application must create a session with an AM instance to set an SSO token and return the request to the redirect location.

    The value can optionally include a redirect with a `goto` parameter or different parameter name.

    The following example uses an authentication service that is not AM, and includes a redirect parameter:

    ```json
    "loginEndpoint": "https://authservice.example.com/auth?redirect=${urlEncodeQueryParameterNameOrValue(contexts.router.originalUri)}"
    ```

    When using this option, review the cookie domains to make sure that cookies set by the authentication server are properly conveyed to the IG instance.

- `"logoutExpression"`: *runtime expression<[boolean](preface.html#definition-boolean)>, optional*

  A flag to indicate that a logout condition is met. The condition is based on the request:

  * `true`: The AM session token for the end user is revoked. If a `defaultLogoutLandingPage` is specified, the request is redirected to that page.

  * `false`: The request continues to be processed.

    The following example expressions can be used to trigger revocation of the end user token:

  * The request URI contains `/logout`:

    ```none
    ${find(request.uri, '/logout')}
    ```

  * The request path starts with `/logout`:

    ```none
    ${find(request.uri.path, '^/logout')}
    ```

  * The request query includes the `logOff=true` query parameter:

    ```none
    ${find(request.uri.query, 'logOff=true')}
    ```

  Default: `${false}`

- `"logoutEndpoint"`: *pattern, optional*

  |   |                                                                                                                                                                       |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | The use of this property is deprecated; use `logoutExpression` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  A string denoting a regular expression pattern for a URL. When a request matches the pattern, IG performs the logout process and the AM authentication token for the end user is revoked.

  If a defaultLogoutLandingPage is specified, the request is redirected to that page. Otherwise, the request continues to be processed.

  Default: Logout is not managed by this filter.

### More information

[org.forgerock.openig.openam.SingleSignOnFilter](../_attachments/apidocs/org/forgerock/openig/openam/SingleSignOnFilter.html)

[org.forgerock.openig.openam.SsoTokenContext](../_attachments/apidocs/org/forgerock/openig/openam/SsoTokenContext.html)

[SsoTokenContext](RequestsResponsesContexts.html#SsoTokenContext)

## SqlAttributesFilter

Executes a SQL query through a prepared statement and exposes its first result. Parameters in the prepared statement are derived from expressions. The query result is exposed in an object whose location is specified by the `target` expression. If the query yields no result, then the resulting object is empty.

The execution of the query is performed lazily; it does not occur until the first attempt to access a value in the target. This defers the overhead of connection pool, network and database query processing until a value is first required. This also means that the parameters expressions is not evaluated until the object is first accessed.

### Usage

```json
{
  "name": string,
  "type": "SqlAttributesFilter",
   "config": {
     "dataSource": JdbcDataSource reference,
     "preparedStatement": configuration expression<string>,
     "parameters": [ runtime expression<string>, ... ],
     "target": lvalue-expression
   }
}
```

### Properties

* `"dataSource"`: *JdbcDataSource [reference](preface.html#definition-reference), required*

  |   |                                                                                                                                                                                                                    |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  |   | `dataSource` as a JNDI lookup name is deprecated; use `dataSource` as a JdbcDataSource configuration object instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The JdbcDataSource to use for connections. Configure JdbcDataSource as described in [JdbcDataSource](MiscellaneousConfigurationObjects.html#JdbcDataSource).

* `"preparedStatement"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The parameterized SQL query to execute, with `?` parameter placeholders.

* `"parameters"`: *array of runtime expressions\<strings>, optional*

  The parameters to evaluate and include in the execution of the prepared statement.

  See also [Expressions](Expressions.html#Expressions).

* `"target"`: *<[lvalue-expression](preface.html#definition-lvalue-expression)>, required*

  Expression that yields the target object that will contain the query results.

  See also [Expressions](Expressions.html#Expressions).

### Example

Using the user's session ID from a cookie, query the database to find the user logged in and set the profile attributes in the attributes context:

```json
{
        "name": "SqlAttributesFilter",
        "type": "SqlAttributesFilter",
        "config": {
              "target": "${attributes.sql}",
              "dataSource": "java:comp/env/jdbc/mysql",
              "preparedStatement": "SELECT f.value AS 'first', l.value AS 'last', u.mail AS 'email', GROUP_CONCAT(CAST(r.rid AS CHAR)) AS 'roles' FROM sessions s INNER JOIN users u ON ( u.uid = s.uid AND u.status = 1 ) LEFT OUTER JOIN profile_values f ON ( f.uid = u.uid AND f.fid = 1 ) LEFT OUTER JOIN profile_values l ON ( l.uid = u.uid AND l.fid = 2 ) LEFT OUTER JOIN users_roles r ON ( r.uid = u.uid ) WHERE (s.sid = ? AND s.uid <> 0) GROUP BY s.sid;",
              "parameters": [ "${request.cookies[keyMatch(request.cookies,'JSESSION1234')][0].value}" ]
         }
 }
```

Lines are folded for readability in this example. In your JSON, keep the values for `"preparedStatement"` and `"parameters"` on one line.

## StaticRequestFilter

Creates a new request, replacing any existing request. The request can include an entity specified in the `entity` parameter. Alternatively, the request can include a form, specified in the `form` parameter, which is included in an entity encoded in `application/x-www-form-urlencoded` format if request method is `POST`, or otherwise as (additional) query parameters in the URI. The `form` and `entity` parameters cannot be used together when the `method` is set to `POST`.

### Usage

```json
{
  "name": string,
  "type": "StaticRequestFilter",
  "config": {
    "method": configuration expression<string>,
    "uri": runtime expression<url>,
    "version": configuration expression<string>,
    "headers": {
      configuration expression<string>: [ runtime expression<string>, ... ], ...
    },
    "form": {
      configuration expression<string>: [ runtime expression<string>, ... ], ...
    },
    "entity": runtime expression<string>
  }
}
```

### Properties

* `"method"`: *configuration expression<[string](preface.html#definition-string)>, required*

  The HTTP method to be performed on the resource; for example, `GET`.

* `"uri"`: *runtime expression<[url](preface.html#definition-url)>, required*

  The fully-qualified URI of the resource being accessed; for example, `http://www.example.com/resource.txt`.

  The result of the expression must be a string that represents a valid URI, but is not a real `java.net.URI` object. For example, it would be incorrect to use `${request.uri}`, which is not a string but a mutable URI.

* `"version"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  Protocol version.

  Default: `"HTTP/1.1"`

* `"headers"`: *[map](preface.html#definition-map), optional*

  One or more headers to set for a request, with the format `name: [ value, …​ ]`, where:

  * *name* is a configuration expression<[string](preface.html#definition-string)> that resolve to a header name. If multiple expressions resolve to the same final string, *name* has multiple values.

  * *value* is one or more runtime expression<[strings](preface.html#definition-string)> that resolve to header values.

  In the following example, the header name is the value of the system variable defined in `cookieHeaderName`. The header value is stored in `contexts.ssoToken.value`:

  ```json
  "headers": {
    "${application['header1Name']}": [
      "${application['header1Value'}"
    ]
  }
  ```

|   |                                                                                                                                                                                                                                                             |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | For IG in web container mode, sending or receiving headers or trailers whose names or values contain non-ASCII characters can cause unspecified behavior at the HTTP server level, and character corruption at the ClientHandler/ReverseProxyHandler level. |

Default: Empty

* `"form"`: *[map](preface.html#definition-map), optional*

  A form to include in the request and/or `application/x-www-form-urlencoded` entity, as name-value pairs, where:

  * *name* is a configuration expression<[string](preface.html#definition-string)> that resolves to a form parameter name.

  * *value* is one or more runtime expression<[strings](preface.html#definition-string)> that resolve to form parameter values.

  When a Request `method` is `POST`, `form` is mutually exclusive with `entity`.

  Examples:

  * In the following example, the field parameter names and values are hardcoded in the form:

    ```json
    "form": {
      "username": [
        "demo"
      ],
      "password": [
        "password"
      ]
    }
    ```

  * In the following example, the values take the first value of `username` and `password` provided in the session:

    ```json
    "form": {
      "username": [
        "${session.username[0]}"
      ],
      "password": [
        "${session.password[0]}"
      ]
    }
    ```

  * In the following example, the name of the first field parameter takes the value of the expression `${application['formName']}` when it is evaluated at startup. The values take the first value of `username` and `password` provided in the session:

    ```json
    "form": {
      "${application['formName']}": [
        "${session.username[0]}"
      ],
      "${application['formPassword']}": [
        "${session.password[0]}"
      ]
    }
    ```

    Default: Empty

* `"entity"`: *runtime expression<[string](preface.html#definition-string)>, optional*

  The message entity body to include in a request.

  When a Request `method` is `POST`, `entity` is mutually exclusive with `form`.

  Methods are provided for accessing the entity as byte, string, or JSON content. For information, see [Entity](../_attachments/apidocs/org/forgerock/http/protocol/Entity.html).

  |   |                                                                                                                                                                                                      |
  | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | Attackers during reconnaissance can use messages to identify information about a deployment. For security, limit the amount of information in messages, and avoid using words that help identify IG. |

  Default: Empty

### Example

In the following example, IG replaces the browser's original HTTP GET request with an HTTP POST login request containing credentials to authenticate to the sample application. For information about how to set up and test this example, see the [Getting started](../getting-started/preface.html).

```json
{
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "StaticRequestFilter",
          "config": {
            "method": "POST",
            "uri": "http://app.example.com:8081/login",
            "form": {
              "username": [
                "demo"
              ],
              "password": [
                "Ch4ng31t"
              ]
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  },
  "condition": "${find(request.uri.path, '^/static')}"
}
```

### More information

[org.forgerock.openig.filter.StaticRequestFilter](../_attachments/apidocs/org/forgerock/openig/filter/StaticRequestFilter.html)

## SwitchFilter

Verifies that a specified condition is met. If the condition is met or no condition is specified, the request is diverted to the associated handler, with no further processing by the switch filter.

### Usage

```json
{
    "name": string,
    "type": "SwitchFilter",
    "config": {
        "onRequest": [
            {
                "condition": runtime expression<boolean>,
                "handler": Handler reference
            },
            ...
        ],
        "onResponse": [
            {
                "condition": runtime expression<boolean>,
                "handler": Handler reference
            },
            ...
        ]
    }
}
```

### Properties

* `"onRequest"`: *array of [objects](preface.html#definition-object), optional*

  Conditions to test (and handler to dispatch to, if `true`) before the request is handled.

* `"onResponse"`: *array of [objects](preface.html#definition-object), optional*

  Conditions to test (and handler to dispatch to, if `true`) after the response is handled.

* `"condition"`: *runtime expression<[boolean](preface.html#definition-boolean)>, optional*

  A flag to indicate that a condition is met:

  * `true`: The request is dispatched to the handler.

  * `false`: The request is not dispatched to the handler, and the next condition in the list is tried.

    When the last condition in the list returns `false`, the request is passed to the next filter or handler in the chain.

  Default: `${true}`

* `"handler"`: *Handler [reference](preface.html#definition-reference), required*

  Dispatch to this handler if the condition yields `true`.

  Provide either the name of a Handler object defined in the heap, or an inline Handler configuration object.

  See also [Handlers](Handlers.html).

### Example

This example intercepts the response if it is equal to 200 and executes the LoginRequestHandler. This filter might be used in a login flow where the request for the login page must go through to the target, but the response should be intercepted in order to send the login form to the application. This is typical for scenarios where there is a hidden value or cookie returned in the login page, which must be sent in the login form:

```json
{
    "name": "SwitchFilter",
    "type": "SwitchFilter",
    "config": {
        "onResponse": [
            {
                "condition": "${response.status.code == 200}",
                "handler": "LoginRequestHandler"
            }
        ]
    }
}
```

### More information

[org.forgerock.openig.filter.SwitchFilter](../_attachments/apidocs/org/forgerock/openig/filter/SwitchFilter.html)

## ThrottlingFilter

Limits the rate that requests pass through a filter. The maximum number of requests that a client is allowed to make in a defined time is called the *throttling rate*.

When the throttling rate is reached, IG issues an HTTP status code 429 `Too Many Requests` and a `Retry-After` header, whose value is rounded up to the number of seconds to wait before trying the request again.

```http
GET http://ig.example.com:8080/home/throttle-scriptable HTTP/1.1
. . .
HTTP/1.1 429 Too Many Requests
Retry-After: 10
```

### Usage

```json
{
    "name": string,
    "type": "ThrottlingFilter",
    "config": {
        "requestGroupingPolicy": runtime expression<string>,
        "throttlingRatePolicy": ThrottlingPolicy reference,  //Use either "throttlingRatePolicy"
        "rate": {                                            //or "rate", but not both.
            "numberOfRequests": configuration expression<number>,
            "duration": configuration expression<duration>
        },
        "cleaningInterval": configuration expression<duration>,
        "executor": ScheduledExecutorService reference
    }
}
```

### Properties

* `"requestGroupingPolicy"`: *runtime expression<[string](preface.html#definition-string)>, optional*

  An expression to identify the partition to use for the request. In many cases the partition identifies an individual client that sends requests, but it can also identify a group that sends requests. The expression can evaluate to the client IP address or user ID, or an OpenID Connect subject/issuer.

  The value for this expression must not be null.

  Default: Empty string; all requests share the same partition

  See also [Expressions](Expressions.html#Expressions).

* `"throttlingRatePolicy"`: *ThrottlingPolicy [reference](preface.html#definition-reference), required if `rate` is not used*

  A reference to, or inline declaration of, a policy to apply for throttling rate. The following policies can be used:

  * [MappedThrottlingPolicy](ThrottlingPolicies.html#MappedThrottlingPolicy)

  * [ScriptableThrottlingPolicy](ThrottlingPolicies.html#ScriptableThrottlingPolicy)

  * [DefaultRateThrottlingPolicy](ThrottlingPolicies.html#DefaultRateThrottlingPolicy)

  This value for this parameter must not be null.

* `"rate"`: *[object](preface.html#definition-object), required if `throttlingRatePolicy` is not used*

  The throttling rate to apply to requests. The rate is calculated as the number of requests divided by the duration:

- `"numberOfRequests"`: *configuration expression\<integer>, required*

  The number of requests allowed through the filter in the time specified by `"duration"`.

* `"duration"`: *configuration expression<[duration](preface.html#definition-duration)>, required*

  A time interval during which the number of requests passing through the filter is counted.

- `"cleaningInterval"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

  The time to wait before cleaning outdated partitions. The value must be more than zero but not more than one day.

- `"executor"`: *ScheduledExecutorService [reference](preface.html#definition-reference), optional*

  An executor service to schedule the execution of tasks, such as the clean up of partitions that are no longer used.

  Default: `ScheduledExecutorService`

  See also [ScheduledExecutorService](MiscellaneousConfigurationObjects.html#ScheduledExecutorService).

### Examples

* [Example of a Mapped Throttling Policy](ThrottlingPolicies.html#example-throttling-mapped)

* [Example of a Scriptable Throttling Policy](ThrottlingPolicies.html#example-throttling-scriptable)

The following route defines a throttling rate of 6 requests/10 seconds to requests. For information about how to set up and test this example, see [Configure Simple Throttling](../gateway-guide/throttling.html#throttling-simple).

```json
{
  "name": "00-throttle-simple",
  "baseURI": "http://app.example.com:8081",
  "condition": "${find(request.uri.path, '^/home/throttle-simple')}",
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "ThrottlingFilter",
          "name": "ThrottlingFilter-1",
          "config": {
            "requestGroupingPolicy": "",
            "rate": {
              "numberOfRequests": 6,
              "duration": "10 s"
            }
          }
        }
      ],
      "handler": "ReverseProxyHandler"
    }
  }
}
```

### More information

[org.forgerock.openig.filter.throttling.ThrottlingFilterHeaplet](../_attachments/apidocs/org/forgerock/openig/filter/throttling/ThrottlingFilterHeaplet.html)

## TokenTransformationFilter

Transforms a token issued by AM to another token type.

The TokenTransformationFilter makes the result of the token transformation

available to downstream handlers in the `sts` context. For information, see [StsContext](RequestsResponsesContexts.html#StsContext).

The current implementation uses REST Security Token Service (STS) APIs to transform an OpenID Connect ID Token (`id_token`) into a SAML 2.0 assertion. The subject confirmation method is Bearer, as described in [Profiles for the OASIS Security Assertion Markup Language (SAML) V2.0 ](http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf).

The TokenTransformationFilter makes the result of the token transformation available to downstream handlers in the `issuedToken` property of the `${contexts.sts}` context.

The TokenTransformationFilter configuration references a REST STS instance that must be set up in AM before the TokenTransformationFilter can be used. The REST STS instance exposes a preconfigured transformation under a specific REST endpoint. For information about setting up a REST STS instance, see the AM documentation.

Errors that occur during the token transformation cause a error response to be returned to the client and an error message to be logged for the IG administrator.

### Usage

```json
{
    "name": "string",
    "type": "TokenTransformationFilter",
    "config": {
        "amService": AmService reference,
        "idToken": runtime expression<string>,
        "instance": configuration expression<string>,
        "username": configuration expression<string>, //deprecated
        "password": configuration expression<string>  //deprecated
    }
}
```

### Properties

* `"amService"`: *AmService [reference](preface.html#definition-reference), required*

  The [AmService](MiscellaneousConfigurationObjects.html#AmService) heap object to use for the following properties:

  * `agent`, the credentials of the IG agent in AM, to authenticate IG as an AM REST STS client, and to communicate WebSocket notifications from AM to IG. This credentials are evaluated when the route is initialized

  * `url`, the URL of an AM service to use for session token validation and authentication. Authentication and REST STS requests are made to this service.

  * `realm`, the AM realm containing the following information:

    * The AM application that can make the REST STS request and whose credentials are the username and password.

    * The STS instance described by the instance field.

  * `ssoTokenHeader`, the name of the HTTP header that provides the SSO token for the REST STS client subject.

  * `amHandler`, the handler to use for authentication and STS requests to AM.

* `"idToken"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The value of the OpenID Connect ID token. The expected value is a string that is the JWT encoded `id_token`.

* `"instance"`: *configuration expression<[string](preface.html#definition-string)>, required*

  An expression evaluating to the name of the REST STS instance.

  This expression is evaluated when the route is initialized, so the expression cannot refer to `request` or `contexts`.

* `"username"`: *string, required*

  |   |                                                                                                                                                                                   |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | The use of this property is deprecated; use the AmService property `agent` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The username to authenticate IG as an AM REST STS client.

* `"password"`: *expression, required*

  |   |                                                                                                                                                                                   |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | The use of this property is deprecated; use the AmService property `agent` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The password to authenticate IG as an AM REST STS client.

### Example

The following example shows a configuration for a TokenTransformationFilter:

```json
{
  "type": "TokenTransformationFilter",
  "config": {
    "amService": "MyAmService",
    "idToken": "${attributes.openid.id_token}",
    "instance": "openig"
  }
}
```

For an example of how to set up and test the TokenTransformationFilter, see [Transform OpenID Connect ID tokens into SAML assertions](../gateway-guide/ttf.html).

### More information

[org.forgerock.openig.openam.TokenTransformationFilter](../_attachments/apidocs/org/forgerock/openig/openam/TokenTransformationFilter.html)

[org.forgerock.openig.openam.StsContext](../_attachments/apidocs/org/forgerock/openig/openam/StsContext.html)

[StsContext](RequestsResponsesContexts.html#StsContext)

## TransactionIdOutboundFilter

Inserts the ID of a transaction into the header of a request.

The default TransactionIdOutboundFilter is created by IG, and used in [ForgeRockClientHandler](ForgeRockClientHandler.html), as follows:

```json
{
     "name": "ForgeRockClientHandler",
     "type": "ForgeRockClientHandler",
     "config": {
         "filters": [ "TransactionIdOutboundFilter" ],
         "handler": "ClientHandler"
     }
}
```

### More information

[org.forgerock.http.filter.TransactionIdOutboundFilter](../_attachments/apidocs/org/forgerock/http/filter/TransactionIdOutboundFilter.html)

## UmaFilter

This filter acts as a policy enforcement point, protecting access as a User-Managed Access (UMA) resource server. Specifically, this filter ensures that a request for protected resources includes a valid requesting party token with appropriate scopes before allowing the response to flow back to the requesting party.

### Usage

```json
{
    "name": string,
    "type": "UmaFilter",
    "config": {
        "protectionApiHandler": Handler reference,
        "umaService": UmaService reference,
        "realm": configuration expression<string>
    }
}
```

### Properties

* `"protectionApiHandler"`: *Handler [reference](preface.html#definition-reference), required*

  The handler to use when interacting with the UMA authorization server for token introspection and permission requests, such as a ClientHandler capable of making an HTTPS connection to the server.

  For details, see [Handlers](Handlers.html).

* `"umaService"`: *UmaService [reference](preface.html#definition-reference), required*

  The UmaService to use when protecting resources.

  For details, see [UmaService](MiscellaneousConfigurationObjects.html#UmaService).

* `"realm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

  The UMA realm set in the response to a request for a protected resource that does not include a requesting party token enabling access to the resource.

  Default: `uma`

### More information

[User-Managed Access (UMA) Profile of OAuth 2.0](https://docs.kantarainitiative.org/uma/rec-uma-core.html)

[org.forgerock.openig.uma.UmaResourceServerFilter](../_attachments/apidocs/org/forgerock/openig/uma/UmaResourceServerFilter.html)

## UriPathRewriteFilter

Rewrite a URL path, using a bidirectional mapping:

* In the request flow, `fromPath` is mapped to `toPath`.

* In the response flow, `toPath` is mapped to `fromPath`.

IG overwrites a response header only when all of the following conditions are true:

* The response includes a header such as `Location` or `Content-Location`

* The URI of the response header matches the mapping

* The value of response header is a relative path or its `scheme://host:port` value matches the base URI.

### Usage

```json
{
  "name": string,
  "type": "UriPathRewriteFilter",
  "config": {
    "mappings": object,
    "failureHandler": Handler reference
  }
}
```

### Properties

* `"mappings"`: [object](preface.html#definition-object), required

  One or more bidirectional mappings between URL paths. For example mappings, request scenarios, and an example route, see [Examples](#UriPathRewriteFilter-example).

  ```json
  {
    "mappings": {
      "/fromPath1": "/toPath1",
      "/fromPath2": "/toPath2",
      ...
    }
  }
  ```

  Paths are given by a `configuration expression<string>`. Consider the following points when you define paths:

  * The incoming URL must start with the mapping path.

  * When more than one mapping applies to a URL, the most specific mapping is used.

  * Duplicate `fromPath` values are removed without warning.

  * Trailing slashes `/` are removed from path values.

  * If the response includes a `Location` or `Content-Location` header with a `toPath` in its URL, the response is rewritten with `fromPath`.

* `"failureHandler"`: handler [reference](preface.html#definition-reference), optional

  Failure handler to be invoked if an invalid URL is produced when the request path is mapped, or when the response `Location` or `Content-Location` header URI path is reverse-mapped.

  Provide an inline handler declaration, or the name of a handler object defined in the heap. See also [Handlers](Handlers.html).

  Default: HTTP 500

### Examples

#### Valid and invalid mapping examples

The following mapping examples are valid:

* Single `fromPath` and `toPath`

  ```json
  "mappings": {
    "/fromPath1": "/toPath1",
    "/fromPath2": "/toPath2"
  }
  ```

* Expressions in the `fromPath` and `toPath`

  ```json
  "mappings": {
    "/${join(array(`fromPath`, 'path1'), `/`)}": "/${join(array(`toPath`, 'path2'), `/`)}"
  }
  ```

* Expressions in the `fromPath` and `toPath` that use predefined heap properties

  ```json
  "mappings": {
    "${fromPath}": "${toPath}"
  }
  ```

* No mappings—the configuration is valid, but has no effect

  ```json
  "mappings": { }
  ```

* Duplicate `toPath`

  ```json
  "mappings": {
    "/fromPath1": "/toPath",
    "/fromPath2": "/toPath"
  }
  ```

* Duplicate `fromPath`—the configuration is overwritten without warning

  ```json
  "mappings": {
    "/fromPath": "/toPath1",
    "/fromPath": "/toPath2"
  }
  ```

The following mapping examples are not valid

* No `toPath`

  ```json
  "mappings": {
    "/fromPath": ""
  }
  ```

  ```json
  "mappings": {
    "/fromPath": "${unknown}"
  }
  ```

* Invalid `toPath`

  ```json
  "mappings": {
    "/fromPath": "${invalidExpression}"
  }
  ```

* No `fromPath`

  ```json
  "mappings": {
    "": "/toPath"
  }
  ```

  ```json
  "mappings": {
      "${unknown}": "/toPath"
  }
  ```

* Invalid `fromPath`

  ```json
  "mappings": {
      "${invalidExpression}": "/toPath"
  }
  ```

#### Example request scenarios

| Description                                                        | Mapping                                                          | Inbound URI                                   | Rewritten URI                               |
| ------------------------------------------------------------------ | ---------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------- |
| Basic path                                                         | ```json
"mappings": {
  "/fromPath": "/toPath"
}
```             | http\://example.com/fromPath/remainder        | http\://example.com/toPath/remainder        |
| Root context, where the inbound request URI has a `/` path segment | ```json
"mappings": {
  "/": "/rootcontext"
}
```                | http\://example.com/                          | http\://example.com/rootcontext/            |
| Root context, where the inbound URI has a `/` path segment         | ```json
"mappings": {
  "/rootcontext": "/"
}
```                | http\://example.com/rootcontext/              | http\://example.com/                        |
| Root context, where the inbound request URI has an empty path      | ```json
"mappings": {
  "/": "/rootcontext"
}
```                | http\://example.com                           | http\://example.com/rootcontext             |
| Root context, where the rewritten URI has an empty path            | ```json
"mappings": {
  "/rootcontext": "/"
}
```                | http\://example.com/rootcontext               | http\://example.com                         |
| Root context, with path remainder                                  | ```json
"mappings": {
  "/": "/rootcontext"
}
```                | http\://example.com/remainder                 | http\://example.com/rootcontext/remainder   |
| Root context, with path remainder                                  | ```json
"mappings": {
  "/rootcontext": "/"
}
```                | http\://example.com/rootcontext/remainder     | http\://example.com/remainder               |
| Root context, where the trailing `/` on `toPath` is ignored        | ```json
"mappings": {
  "/": "/rootcontext/"
}
```               | http\://example.com/remainder                 | http\://example.com/rootcontext/remainder   |
| Path with dot-segments:                                            | ```json
"mappings": {
  "/fromPath": "/toPath1/../toPath2"
}
``` | http\://example.com/fromPath                  | http\://example.com/toPath1/../toPath2      |
| Path with syntax:                                                  | ```json
"mappings": {
  "/fromPath;v=1.1": "/toPath,1.1"
}
```   | http\://example.com/fromPath;v=1.1            | http\://example.com/toPath,1.1              |
| Path with syntax:                                                  | ```json
"mappings": {
  "/$fromPath": "/$toPath"
}
```           | http\://example.com/$fromPath                 | http\://example.com/$toPath                 |
| Path with query parameters                                         | ```json
"mappings": {
  "/fromPath": "/toPath"
}
```             | http\://example.com/fromPath?param1\&param2=2 | http\://example.com/toPath?param1\&param2=2 |
| Path with fragment                                                 | ```json
"mappings": {
  "/fromPath": "/toPath"
}
```             | http\://example.com/fromPath#fragment         | http\://example.com/toPath#fragment         |

#### Example route

The example route changes a request URL as follows:

* The `baseURI` overrides the scheme, host, and port of a request URL.

* The UriPathRewriteFilter remaps the path of a request URL.

  Requests to `http://ig.example.com:8080/mylogin` are mapped to `http://app.example.com:8081/login`.

  Requests to `http://ig.example.com:8080/welcome` are mapped to `http://app.example.com:8081/home`.

  Requests to `http://ig.example.com:8080/other` are mapped to `http://app.example.com:8081/not-found`, and result in an HTTP 404.

  Requests to `http://ig.example.com:8080/badurl` are mapped to the invalid URL `http://app.example.com:8081[`, and invoke the failure handler.

```json
{
  "name": "UriPathRewriteFilter",
  "baseURI": "http://app.example.com:8081",
  "handler": {
    "type": "Chain",
    "config": {
      "filters": [
        {
          "type": "UriPathRewriteFilter",
          "config": {
            "mappings": {
              "/mylogin": "/login",
              "/welcome": "/home",
              "/other": "/not-found",
              "/badurl": "["
            },
            "failureHandler": {
              "type": "StaticResponseHandler",
              "config": {
                "status": 500,
                "headers": {
                  "Content-Type": [
                    "text/plain"
                  ]
                },
                "entity": "Invalid URL produced"
              }
            }
          }
        }
      ],
      "handler": "ClientHandler"
    }
  }
}
```

### More information

[org.forgerock.openig.filter.UriPathRewriteFilter](../_attachments/apidocs/org/forgerock/openig/filter/UriPathRewriteFilter.html)

[RFC 3986: Path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3)

## UserProfileFilter

Queries AM to retrieve the profile attributes of an user identified by their `username`.

Only profile attributes that are enabled in AM can be returned by the query. The `roles` field is not returned.

The data is made available to downstream IG filters and handlers, in the context [UserProfileContext](RequestsResponsesContexts.html#UserProfileContext).

### Usage

```json
{
  "name": string,
  "type": "UserProfileFilter",
  "config": {
    "username": runtime expression<string>,
    "userProfileService": UserProfileService reference,
    "amService": AmService reference, //deprecated
    "ssoToken": runtime expression<string>,  //deprecated
    "profileAttributes": array of runtime expressions<string>  //deprecated
  }
}
```

### Properties

* `"username"`: *runtime expression<[string](preface.html#definition-string)>, required*

  The username of an AM subject. This filter retrieves profile attributes for the subject.

* `"userProfileService"`: *UserProfileService [reference](preface.html#definition-reference), required*

  The service to retrieve profile attributes from AM, for the subject identified by `username`.

  ```json
  "userProfileService": {
    "type": "UserProfileService",
    "config": {
      "amService": AmService reference,
      "cache": object,
      "profileAttributes": [ configuration expression<string>, ... ],
      "realm": configuration expression<string>
    }
  }
  ```

  * `"amService"`: *AmService [reference](preface.html#definition-reference), required*

    The AmService heap object to use for the following properties:

    * `agent`, the credentials of the IG agent in AM. When the agent is authenticated, the token can be used for tasks such as getting the user's profile, making policy evaluations, and connecting to the AM notification endpoint.

      * `url`: URL of the AM server where the user is authenticated.

      * `amHandler`: Handler to use when communicating with AM to fetch the requested user's profile.

    * `realm`: Realm of the IG agent in AM.

    * `version`: The version of the AM server.

      The AM version is derived as follows, in order of precedence:

      * Discovered value: AmService discovers the AM version. If `version` is configured with a different value, AmService ignores the value of `version` and issues a warning.

      * Value in `version`: AmService cannot discover the AM version, and `version` is configured.

      * Default value of AM 6: AmService cannot discover the AM version, and `version` is not configured.

  * `"cache"`: *[object](preface.html#definition-object), optional*

    Caching of AM user profiles, based on *Caffeine*. For more information, see the GitHub entry, [Caffeine](https://github.com/ben-manes/caffeine).

    When caching is enabled, IG can reuse cached profile attributes without repeatedly querying AM. When caching is disabled, IG must query AM for each request, to retrieve the required user profile attributes.

    Default: No cache.

    ```json
    "cache": {
        "enabled": configuration expression<boolean>,
        "executor": Executor reference,
        "maximumSize": configuration expression<number>,
        "maximumTimeToCache": configuration expression<duration>,
    }
    ```

    * `enabled`: *configuration expression<[boolean](preface.html#definition-boolean)>,optional*

      Enable or disable caching of user profiles. When `false`, the cache is disabled but the cache configuration is maintained.

      Default: `true` when `cache` is configured

    * `executor`: *Executor [reference](preface.html#definition-reference), optional*

      An executor service to schedule the execution of tasks, such as the eviction of entries in the cache.

      Default: `ForkJoinPool.commonPool()`

    * `"maximumSize"`: *configuration expression<[number](preface.html#definition-number)>, optional*

      The maximum number of entries the cache can contain.

      Default: Unlimited/unbound

    * `maximumTimeToCache`: *configuration expression<[duration](preface.html#definition-duration)>, required*

      The maximum duration for which to cache user profiles.

      The duration cannot be `zero`.

  * `profileAttributes`: *array of configuration expression<[strings](preface.html#definition-string)>, optional*

    List of one or more fields to return and store in UserProfileContext.

    Field names are defined by the underlying repository in AM. When AM is installed with the default configuration, the repository is ForgeRock Directory Services.

    The following convenience accessors are provided for commonly used fields:

    * `cn`: Retrieved through `${contexts.userProfile.commonName}`

    * `dn`: Retrieved through `${contexts.userProfile.distinguishedName}`

    * `realm`: Retrieved through `${contexts.userProfile.realm}`

    * `username`: Retrieved through `${contexts.userProfile.username}`

    All other available fields can be retrieved through `${contexts.userProfile.rawInfo}` and `${contexts.userProfile.asJsonValue()}`.

    When `profileAttributes` is configured, the specified fields **and** the following fields are returned: `username`, `_id`, and `_rev`.

    Default: All available fields are returned.

  * `"realm"`: *configuration expression<[string](preface.html#definition-string)>, optional*

    The AM realm where the subject is authenticated.

    Default: The realm declared for `amService`.

* `"ssoToken"`: *runtime expressions\<string>, optional*

  |   |                                                                                                                                                               |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | The use of this property is deprecated; use `username` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  Location of the AM SSO token. For example, with `${request.headers['mySsoToken'].values[0]}` the SSO token is the first value of the `mySsoToken` header in the request.

  If an SSO token is not available in the request, an error is returned.

  Default: `${request.cookies['AmService-ssoTokenHeader'][0].value}`, where `AmService-ssoTokenHeader` is the name of the header or cookie where the AmService expects to find SSO tokens.

* `"amService"`: *AmService [reference](preface.html#definition-reference), optional*

  |   |                                                                                                                                                                                                     |
  | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | The use of this property is deprecated; use the `userProfileService` subproperty `amService` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  The AmService heap object to use.

* `"profileAttributes"`: *array of runtime expressions\<string>, optional*

  |   |                                                                                                                                                                                                             |
  | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | The use of this property is deprecated; use the `userProfileService` subproperty `profileAttributes` instead. For more information, refer to [Deprecation](../release-notes/deprecated-functionality.html). |

  List of field names in AM to retrieve.

  When this property is not configured, all available fields are returned. When this property is configured, the specified fields and the following fields are returned: `username`, `_id`, and `_rev`.

  Field names are defined by the underlying repository in AM. For example, when AM is installed with the default configuration, the repository is ForgeRock Directory Server.

  The following convenience accessors are provided for commonly used fields:

  * `cn`, retrieved through `${contexts.userProfile.commonName}`

  * `dn`, retrieved through `${contexts.userProfile.distinguishedName}`

  * `realm`, retrieved through `${contexts.userProfile.realm}`

  * `username`, retrieved through `${contexts.userProfile.username}`

  All other available fields can be retrieved through `${contexts.userProfile.rawInfo}` and `${contexts.userProfile.asJsonValue()}`.

  Default: All available fields are returned.

### Example

For examples that use the UserProfileFilter, see [Get user profile information from AM](../gateway-guide/profile-am.html).

### More information

[org.forgerock.openig.openam.UserProfileFilter](../_attachments/apidocs/org/forgerock/openig/openam/UserProfileFilter.html)

[org.forgerock.openig.tools.userprofile.UserProfileService](../_attachments/apidocs/org/forgerock/openig/tools/userprofile/UserProfileService.html)

[org.forgerock.openig.openam.UserProfileContext](../_attachments/apidocs/org/forgerock/openig/openam/UserProfileContext.html)

[UserProfileContext](RequestsResponsesContexts.html#UserProfileContext)

AM's [Authorization guide](https://docs.pingidentity.com/pingam/7.2/authorization-guide/)
