Persist URI Fragments in Login Redirects

URI fragments are optional last parts of a URL for a document, typically used to identify or navigate to a particular part of the document. The fragment part follows the URL after a hash #, for example https://tools.ietf.org/html/rfc1234#section5.

When an unauthenticated user requests a resource that includes a URI fragment, the user agent sends the URI but does not send the fragment. The fragment is lost during the authentication flow.

IG provides a FragmentFilter to track the fragment part of a URI when a request triggers a login redirect. The following image shows the flow of information when the FragmentFilter is included in the SSO authentication flow:

fragment

1-2. An unauthenticated client requests access to a fragment URL.

3. The FragmentFilter adds the AuthRedirectContext, so that downstream filters can mark the response as redirected.

4-5. The SingleSignOnFilter adds to the context to notify upstream filters that a redirect is pending, and redirects the request for authentication.

6-7. The FragmentFilter is notified by the context that a redirect is pending, and returns a new response object containing the response cookies, an autosubmit HTML form, and Javascript.

8. The user agent runs the Javascript or displays the form’s submit button for the user to click on. This operation POSTs a form request back to a fragment endpoint URI, containing the following parts:

9. The FragmentFilter creates the fragment cookie.

10-12. The client authenticates with AM.

13. The FragmentFilter intercepts the request because it contains a fragment cookie, and its URI matches the original request URI.

The filter redirects the client to the original request URI containing the fragment. The fragment cookie then expires.

14-19. The client follows the final redirect to the original request URI containing the fragment, and the sample app returns the response.

Persist URI Fragments in Login Redirects

This procedure shows how to persist a URI fragment in an SSO authentication.

  1. Set up the example in Authenticate With SSO Through the Default Authentication Service.

  2. Add the following route to IG:

    • Linux

    • Windows

    $HOME/.openig/routes/fragment.json
    appdata\OpenIG\config\routes\fragment.json
    {
      "name": "fragment",
      "baseURI": "http://app.example.com:8081",
      "condition": "${matches(request.uri.path, '^/home/sso')}",
      "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://openam.example.com:8088/openam/",
            "version": "7.1"
          }
        }
      ],
      "handler": {
        "type": "Chain",
        "config": {
          "filters": [
            {
              "name": "FragmentFilter-1",
              "type": "FragmentFilter",
              "config": {
                "fragmentCaptureEndpoint": "/home/sso"
              }
            },
            {
              "name": "SingleSignOnFilter-1",
              "type": "SingleSignOnFilter",
              "config": {
                "amService": "AmService-1"
              }
            }
          ],
          "handler": "ReverseProxyHandler"
        }
      }
    }

    Notice the following feature of the route compared to sso.json:

    • The FragmentFilter captures the fragment form data from the route condition endpoint.

  3. Test the setup:

    1. If you are logged in to AM, log out and clear any cookies.

    2. Go to http://openig.example.com:8080/home/sso#fragment.

      The SingleSignOnFilter redirects the request to AM for authentication.

    3. Log in to AM as user demo, password Ch4ng31t.

      The SingleSignOnFilter passes the request to sample app, which returns the home page. Note that the URL of the page has preserved the fragment: http://openig.example.com:8080/home/sso?_ig=true#fragment

    4. Remove the FragmentFilter from the route and test the route again.

      Note that this time the URL of the page has not preserved the fragment.