URI fragments in redirect
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://www.rfc-editor.org/rfc/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 FragmentFilter does not handle multiple fragment captures in parallel. If a fragment capture is in progress while IG performs another login redirect, a second fragment capture process is not triggered and the fragment is lost.
The following image shows the flow of information when the FragmentFilter is included in the SSO authentication flow:
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:
-
Request URI path (
/profile
) -
Captured fragment (
#fragment
) -
Login URI (
http://am.example.com/login?goto=…
)
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.
This procedure shows how to persist a URI fragment in an SSO authentication.
-
Set up the example in Authenticate with SSO through the default authentication service.
-
Add the following route to IG:
{ "name": "fragment", "baseURI": "http://app.example.com:8081", "condition": "${find(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://am.example.com:8088/openam/" } } ], "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.
-
-
Test the setup:
-
If you are logged in to AM, log out and clear any cookies.
-
Go to http://ig.example.com:8080/home/sso#fragment.
The SingleSignOnFilter redirects the request to AM for authentication.
-
Log in to AM as user
demo
, passwordCh4ng31t
.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://ig.example.com:8080/home/sso?_ig=true#fragment
-
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.
-