Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
information: "Portions copyright [year] [name of copyright owner]".

Copyright 2017 ForgeRock AS.
Portions Copyright 2024-2025 3A Systems LLC.
Portions Copyright 2024-2026 3A Systems LLC.
////

:figure-caption!:
Expand Down Expand Up @@ -135,7 +135,7 @@ Audit event publisher configuration file
Authentication configuration file for access to the REST API

`openidm/conf/boot/boot.properties`::
OpenIDM bootstrap properties
OpenIDM bootstrap properties, including HTTP/HTTPS port numbers, keystore and truststore locations, and configuration of the default URL pattern used when registering REST-related servlet filters (for example, `openidm.servlet.alias`). These settings do not change the underlying REST servlet alias (which remains `/openidm`). For details, see xref:appendix-jetty.adoc#configuring-rest-context-path["Configuring the REST API Context Path"] and xref:appendix-ports-used.adoc#appendix-ports-used["Ports Used"].

`openidm/conf/cluster.json`::
Configuration file to enable use of this OpenIDM instance in a cluster
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
information: "Portions copyright [year] [name of copyright owner]".

Copyright 2017 ForgeRock AS.
Portions Copyright 2024-2025 3A Systems LLC.
Portions Copyright 2024-2026 3A Systems LLC.
////

:figure-caption!:
Expand Down Expand Up @@ -181,14 +181,40 @@ The HTTP context under which the filter should be registered. The default is `"o
A list of servlet names to which the filter should apply. The default is `"OpenIDM REST"`.

`"urlPatterns"`::
A list of URL patterns to which the filter applies. The default is `["/*"]`.
A list of URL patterns to which the filter applies. When not specified in the filter configuration, the filter is applied to the configured REST servlet URL patterns (by default `["/openidm/*"]`). To change the default patterns for all filters, configure the servlet alias property in `conf/boot/boot.properties`. See xref:appendix-jetty.adoc#configuring-rest-context-path["Configuring the REST API Context Path"] for details.

`"initParams"`::
Filter configuration initialization parameters that are passed to the servlet filter `init` method. For more information, see link:https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/filterconfig[https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/filterconfig, window=\_top].

--


[#configuring-rest-context-path]
=== Configuring Default Servlet-Filter URL Patterns

OpenIDM servlet filters can be configured to apply to specific URL patterns. When a filter configuration in `conf/servletfilter-*.json` does not specify an explicit `"urlPatterns"` list, OpenIDM builds a default pattern from the following `conf/boot/boot.properties` property:

`openidm.servlet.alias`::
Base path used when building the default filter URL pattern for REST API endpoints. Default: `/openidm`. Example override: `/myidm`.

[IMPORTANT]
====
This property only controls which URL pattern is applied to servlet filters that do not have an explicit `"urlPatterns"` key in their filter config. It does *not* change the actual REST servlet registration, which remains at `/openidm`.
====

For example, to apply default filters to `/myidm/` instead of the standard path, add the following to `conf/boot/boot.properties` and restart OpenIDM:

[source, console]
----
openidm.servlet.alias=/myidm
----

[NOTE]
====
Servlet filter configurations in `conf/servletfilter-*.json` that use explicit `"urlPatterns"` are not affected by this property. Only filters without explicit URL patterns use the value derived from `openidm.servlet.alias`.
====


[#disabling-protocols]
=== Disabling and Enabling Secure Protocols

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
information: "Portions copyright [year] [name of copyright owner]".

Copyright 2017 ForgeRock AS.
Portions Copyright 2024-2025 3A Systems LLC.
Portions Copyright 2024-2026 3A Systems LLC.
////

:figure-caption!:
Expand Down Expand Up @@ -44,3 +44,5 @@ HTTPS access to the REST API, requiring SSL mutual authentication. Clients that
--
The Jetty configuration (in `openidm/conf/jetty.xml`) references the ports that are specified in the `boot.properties` file.

In addition to the port numbers, you can configure the default servlet-filter URL pattern for the REST API via `conf/boot/boot.properties`. By default, the REST API servlet is mapped under `/openidm/`; this servlet mapping is defined elsewhere and is not moved by the `boot.properties` setting. The `openidm.servlet.alias` property only influences the filter URL pattern applied to that context. For details, see xref:appendix-jetty.adoc#configuring-rest-context-path["Configuring the REST API Context Path"].

7 changes: 6 additions & 1 deletion openidm-servlet-registrator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
~ your own identifying information:
~ "Portions Copyrighted [year] [name of copyright owner]"
~
~ Portions Copyrighted 2024-2025 3A Systems LLC.
~ Portions Copyrighted 2024-2026 3A Systems LLC.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
Expand All @@ -42,6 +42,11 @@
<artifactId>openidm-enhanced-config</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openidentityplatform.openidm</groupId>
<artifactId>openidm-system</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openidentityplatform.openidm</groupId>
<artifactId>openidm-httpcontext</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Portions Copyrighted 2024-2025 3A Systems LLC.
* Portions Copyrighted 2024-2026 3A Systems LLC.
*/

package org.forgerock.openidm.servletregistration.impl;
Expand Down Expand Up @@ -52,6 +52,7 @@
import org.apache.commons.lang3.StringUtils;
import org.forgerock.json.JsonValue;
import org.forgerock.json.JsonValueException;
import org.forgerock.openidm.core.IdentityServer;
import org.forgerock.openidm.servletregistration.RegisteredFilter;
import org.forgerock.openidm.servletregistration.ServletRegistration;
import org.forgerock.openidm.servletregistration.ServletFilterRegistrator;
Expand Down Expand Up @@ -90,7 +91,10 @@ public class ServletRegistrationSingleton implements ServletRegistration {

private static final String[] DEFAULT_SERVLET_NAME = new String[] { "OpenIDM REST" };

private static final String[] DEFAULT_SERVLET_URL_PATTERNS = new String[] { "/openidm/*", "/selfservice/*" };
private static final String PROP_SERVLET_ALIAS = "openidm.servlet.alias";
private static final String DEFAULT_SERVLET_ALIAS = "/openidm";

private String[] defaultServletUrlPatterns = new String[] { "/openidm/*" };

// Context of this scr component
private BundleContext bundleContext;
Expand All @@ -113,6 +117,13 @@ public class ServletRegistrationSingleton implements ServletRegistration {
public void activate(ComponentContext context) {
bundleContext = context.getBundleContext();
sharedContext = webContainer.createDefaultSharedHttpContext();

String servletAlias = IdentityServer.getInstance().getProperty(PROP_SERVLET_ALIAS, DEFAULT_SERVLET_ALIAS);

servletAlias = sanitizeAlias(servletAlias, DEFAULT_SERVLET_ALIAS);

defaultServletUrlPatterns = new String[] { servletAlias + "/*" };
logger.info("REST servlet URL patterns configured: {}", servletAlias + "/*");
}

/**
Expand All @@ -125,6 +136,55 @@ public void deactivate(ComponentContext context) {
bundleContext = null;
}

private String sanitizeAlias(String alias, String defaultAlias) {
if (alias == null || alias.trim().isEmpty()) {
logger.warn("Configured alias is empty; using default: {}", defaultAlias);
return normalizeAlias(defaultAlias);
}
alias = alias.trim();
if (alias.contains("..")) {
logger.warn("Configured alias '{}' contains invalid sequence '..'; using default: {}", alias, defaultAlias);
return normalizeAlias(defaultAlias);
}
return normalizeAlias(alias);
}

/**
* Normalizes an alias so that it is safe to use when building URL patterns
* via {@code alias + "/*"}.
* <ul>
* <li>Ensures a leading "/".</li>
* <li>Strips a trailing "/*" if present.</li>
* <li>Strips a single trailing "/" when the alias length is greater than 1.</li>
* <li>Maps "/" to the empty string so the resulting pattern becomes exactly "/*".</li>
* </ul>
*
* @param alias the raw alias value (non-null, already trimmed).
* @return a normalized alias suitable for concatenation with "/*".
*/
private String normalizeAlias(String alias) {
// Ensure leading slash
if (!alias.startsWith("/")) {
alias = "/" + alias;
}

// Special-case: root context should result in "/*" when patterns are built.
if ("/".equals(alias)) {
return "";
}

// Strip trailing "/*" if present
if (alias.endsWith("/*")) {
alias = alias.substring(0, alias.length() - 2);
}

// Strip a single trailing "/" (but avoid turning "/" into empty; handled above)
if (alias.length() > 1 && alias.endsWith("/")) {
alias = alias.substring(0, alias.length() - 1);
}
return alias;
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -212,7 +272,7 @@ public URL apply(JsonValue jsonValue) throws JsonValueException {

// URL patterns to apply the filter to, e.g. one could also add "/openidmui/*");
List<String> urlPatterns = config.get(SERVLET_FILTER_URL_PATTERNS)
.defaultTo(Arrays.asList(DEFAULT_SERVLET_URL_PATTERNS))
.defaultTo(Arrays.asList(defaultServletUrlPatterns))
.asList(String.class);

// Filter init params, a string to string map
Expand Down
7 changes: 7 additions & 0 deletions openidm-zip/src/main/resources/conf/boot/boot.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Portions Copyright 2026 3A Systems LLC.

openidm.port.http=8080
openidm.port.https=8443
openidm.port.mutualauth=8444
Expand Down Expand Up @@ -64,3 +66,8 @@ javascript.exception.debug.info=false
# valid values: SSLv3, TLSv1, TLSv1.1, TLSv1.2
# defaults to TLSv1.2 if not specified
#openidm.external.rest.tls.version=TLSv1.1

# Base path used when building default servlet-filter URL patterns for the REST API.
# Note: this does NOT change the core REST servlet context path, which remains /openidm.
# Example override: /myidm
Comment on lines +70 to +72
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The added note says these properties do NOT change the core REST servlet context path (it remains /openidm), but the PR title/description and other docs in this PR describe this as changing the REST API context path. Please align the PR messaging/docs with actual behavior (or implement actual servlet alias remapping if that’s the intent).

Copilot uses AI. Check for mistakes.
#openidm.servlet.alias=/openidm
Loading