Class PasswordReplayFilterHeaplet

java.lang.Object
org.forgerock.openig.heap.GenericHeaplet
org.forgerock.openig.filter.PasswordReplayFilterHeaplet
All Implemented Interfaces:
Heaplet

public class PasswordReplayFilterHeaplet extends GenericHeaplet
Supports password replay feature in a composite filter. Two use cases are supported:
  • Replaying credentials when a login page is queried (on the request flow)
  • Replaying credentials when a login page is returned (on the response flow)

A variation on the first case is possible: it can let the request flow and extract values from the server's response.

This filter supports value extraction for any server-provided values that would be re-used in the authentication request.

Credentials must be installed by a filter that will only be placed in a chain when needed (in case they're not already there).

Then an authentication request is built (using a StaticRequestFilter) and sent down the chain. Note that:

  • There is no retry in case of authentication failure
  • Extracted patterns need to have at least a single regex group, the first one is always used

Usage examples:

Authenticate on behalf of the user when a login page is GET

When a GET request to the login page is intercepted, IG will generate an alternative authentication request and send it in place of the original request. The response is forwarded as-is to the caller. All other requests are forwarded untouched.

     {
         "loginPage": "${find(request.uri.path, '/login') and (request.method == 'GET')}",
         "request": {
           "method": "POST",
           "uri": "http://internal.example.com/login",
           "form": {
             "username": [ "${attributes.username}" ],
             "password": [ "${attributes.password}" ]
           }
         }
       }
     
 

Authenticate on behalf of the user when a login page is returned

When a response that is identified to be a login page is intercepted, IG will generate an authentication request and send it. The authentication response is ignored ATM. Then IG replays the original incoming request.

     {
         "loginPageContentMarker": "I'm a login page",
         "request": {
           "method": "POST",
           "uri": "http://internal.example.com/login",
           "headers": {
             "X-OpenAM-Username": [ "${attributes.username}" ],
             "X-OpenAM-Password": [ "${attributes.password}" ]
           }
         }
       }
     
 

Options

Obtain credentials

The PasswordReplay Filter can be configured (with the credentials attribute) to invoke an additional Filter that would be responsible to obtain credentials and make them available in the request processing data structures. These values can then be used to create an appropriate authentication request.

The credentials attribute expects a reference to a Filter heap object.

Examples of such filters can be FileAttributesFilter (to load credentials from a local CSV file) or SqlAttributesFilter (to load credentials from a database).

     {
         "loginPageContentMarker": "I'm a login page",
         "credentials": {
             "type": "FileAttributesFilter",
             "config": {
                 "file": "${system.home}/users.csv",
                 "key": "uid",
                 "value": "${attributes.whoami}",
                 "target": "${attributes.user}"
             }
         }
         "request": {
           "method": "POST",
           "uri": "http://internal.example.com/login",
           "headers": {
             "X-OpenAM-Username": [ "${attributes.user.uid}" ],
             "X-OpenAM-Password": [ "${attributes.user.password}" ]
           }
         }
       }
     
 

Extract custom values from intercepted response page

The login page can contain a form with hidden fields that is sent to the IDP. Because this filter doesn't interpret the content of the returned form and generate a new authentication request, it needs a way to extract values from the response entity.

Multiple values can be extracted at once, using pattern matching (and the EntityExtractFilter under the hood). Unlike the EntityExtractFilter, only one group is supported, and the matched group value is placed in the results. All extracted values are placed in a Map available in attributes.extracted.

     {
         "loginPageContentMarker": "I'm a login page",
         "loginPageExtractions": [
             {
                 "name": "nonce",
                 "pattern": " nonce='(.*)'"
             }
         ],
         "request": {
           "method": "POST",
           "uri": "http://internal.example.com/login",
           "form": {
             "username": [ "${attributes.username}" ],
             "password": [ "${attributes.password}" ]
             "nonce": [ "${attributes.extracted.nonce}" ]
           }
         }
       }
     
 
  • Constructor Details

    • PasswordReplayFilterHeaplet

      public PasswordReplayFilterHeaplet()
  • Method Details