January 5, 2024

Using Tomcat Rewrites to Customize the UI and Add Friendly URLs in IdentityIQ

Rewriting URLs

The problem

Let’s say you’ve written a custom SailPoint IdentityIQ (IIQ) plugin that exposes a plugin page. By default, plugins in IIQ have a technical-looking URL, like this: https://iiqdemo.example.com/identityiq/plugins/pluginPage.jsf?pn=PluginName. That’s both too much and too little information for an end user.

If your page consumes Angular state, it might have an even uglier URL like: https://iiqdemo.example.com/identityiq/plugins/pluginPage.jsf?pn=SomeOtherPlugin&identity=12345&action=enable.

We want to allow the user to navigate to a memorable, friendly URL, such as: https://iiqdemo.example.com/identityiq/myid/enable/12345. This helps the user understand the page they’re viewing and makes notifications look cleaner!

The solution

This problem can be solved by the rewrite valve. The rewrite valve is responsible for altering or redirecting the URL of the request before it reaches the webapp. It can send the browser to another page altogether, trick the webapp into thinking a different URL was requested, and even alter query string arguments.

Sidenote: If you are an elder sysadmin like myself, you may remember this concept from mod_rewrite in the Apache http server. The configuration is nearly identical.


Enabling the rewrite valve

To enable the rewrite valve, you can either enable it within Tomcat’s context.xml or within the webapp’s context.xml. We will be doing the latter. You will need to create a META-INF folder under your identityiq webapp (/path/to/tomcat/webapps/identityiq/META-INF) and place the following context.xml file there:

  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve"/>

Once you’ve done this, you can restart Tomcat to enable the valve. Note that at this point, it will do nothing, as we haven’t configured any rules. (You may want to hold off restarting Tomcat until after you’ve done the following step as well.)

Configuring the rewrite valve

Rewrite rules are specified in the file WEB-INF/rewrite.config. You will need to restart Tomcat (or, at minimum, re-deploy the webapp) to capture newly added rules.

They have the following format:

RewriteRule    ^/myid/(.+)/(.+)$    /plugins/pluginPage.jsf?pn=SomeOtherPlugin&action=$1&identity=$2   [L]`

The fields are, in order:

  • The tag RewriteRule, which specifies what this line does
  • A regular expression that matches a query URL, relative to the webapp (i.e., excluding everything up through /identityiq). In this case, it’s the “friendly URL” from the example above, starting with myid.
  • A new URL to substitute for the old one, in this case, the URL for our plugin page and its query parameters. The matching groups from the regular expression are available as $1 and $2 and so on. Unless this is a full URL (starting with https://), this will also be relative to the webapp.
  • A set of CSV options in brackets, in this case just “L” (for last), which specifies that rule evaluation stops here. IIQ will see the query for the proper pluginPage.jsf URL, but the user’s browser won’t. (If you wish, you can also specify “R” to redirect in the browser.)

You can specify as many rewrite rules as you wish. Any matching rules will run in order until an “L” flag or the end of the file is encountered.

Useful rewrite tricks

Redirecting the help page

You can use the rewrite valve to change the destination of the help icon in IIQ.

By default, this pops up a new window at the relative URL /help, which itself is just a redirect to the longer IIQ help pages. You can preempt this and redirect /help anywhere you’d like, such as your company’s internal end user documentation.

RewriteRule   ^/help           https://www.instrumentalidentity.com/ [R=permanent]

Creating a short URL for all plugin pages

You may want to expose all of your custom plugin pages using their proper plugin name, but with a nicer-looking URL.

RewriteRule        ^/company/(.+)$    /plugins/pluginPage.jsf?pn=$1      [L,QSA]

Of note here: the QSA option. This tells Tomcat that it should append the input query string (the stuff after the ?) to the new URL. This is necessary here because the redirect itself includes a query string (the pn).

If your request is for /company/Whatever?identity=yes, the redirect will go to /plugins/pluginPage.jsf?pn=Whatever&identity=yes. Since the “R” flag is not specified, the user will never see the more technical URL.

Creating a friendly URL directly to a report result

Using this rewrite, you can direct users to view reports results at /l/report/66fasd..., instead of the more technical-looking URL.

RewriteRule        ^/l/report/(.+)$       /analyze/reports/viewResult.jsf?id=$1  [L]

You can link directly to TaskResults similarly:

RewriteRule        ^/l/taskResult/(.+)$       /monitor/tasks/renderResults.jsf?TaskResultId=$1   [L]

Disabling OOTB pages altogether

Using the flag “F”, you can force Tomcat to reply with a “403 Forbidden” for any matching URL. Let’s say you want to inexplicably block access to the debug Caches page for all users:

RewriteRule ^/debug/caches.jsf$ - [F]

In the real world, you would probably use RewriteCond (conditional rule) concept to only forbid users matching certain criteria (source IP, browser type, request headers, etc). See the documentation for how these work.

A version of this post was also published on the SailPoint Developer Forums.