-
-
Notifications
You must be signed in to change notification settings - Fork 45
Add configurable REST servlet context paths via boot.properties #140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
279c85f
c007489
010feb1
0cfad86
21f1fa5
22f807d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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!: | ||
|
|
@@ -181,14 +181,41 @@ 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/*", "/selfservice/*"]`). To change the default patterns for all filters, configure the servlet alias properties 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 the REST API Context Path | ||
|
|
||
| By default, the OpenIDM REST API is accessible at `/openidm/` and the Self-Service UI at `/selfservice/`. You can change these context paths without rebuilding the project by setting properties in your `conf/boot/boot.properties` file. | ||
|
|
||
| `openidm.servlet.alias`:: | ||
| The context path for the REST API. Default: `/openidm`. Example: `/myidm`. | ||
|
|
||
| `openidm.selfservice.alias`:: | ||
| The context path for the Self-Service UI. Default: `/selfservice`. Example: `/myselfservice`. | ||
|
|
||
|
Comment on lines
+195
to
+202
|
||
| For example, to change the REST API base path to `/myidm` and the Self-Service path to `/myselfservice`, add the following to `conf/boot/boot.properties`: | ||
|
|
||
| [source, console] | ||
| ---- | ||
| openidm.servlet.alias=/myidm | ||
| openidm.selfservice.alias=/myselfservice | ||
| ---- | ||
|
|
||
| After restarting OpenIDM, the REST API is available at `\https://localhost:8443/myidm/` instead of `\https://localhost:8443/openidm/`. | ||
|
|
||
| [NOTE] | ||
| ==== | ||
| If you change the REST API context path, make sure to update any servlet filter configurations in `conf/servletfilter-*.json` that use explicit `"urlPatterns"` referencing the old path. Servlet filters that rely on the default URL patterns (no `"urlPatterns"` key in the filter config) are automatically updated when OpenIDM restarts. | ||
| ==== | ||
|
|
||
|
|
||
| [#disabling-protocols] | ||
| === Disabling and Enabling Secure Protocols | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -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; | ||
|
|
@@ -90,7 +91,12 @@ 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 PROP_SELFSERVICE_ALIAS = "openidm.selfservice.alias"; | ||
| private static final String DEFAULT_SERVLET_ALIAS = "/openidm"; | ||
| private static final String DEFAULT_SELFSERVICE_ALIAS = "/selfservice"; | ||
|
|
||
| private String[] defaultServletUrlPatterns = new String[] { "/openidm/*", "/selfservice/*" }; | ||
|
|
||
| // Context of this scr component | ||
| private BundleContext bundleContext; | ||
|
|
@@ -113,6 +119,15 @@ 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); | ||
| String selfServiceAlias = IdentityServer.getInstance().getProperty(PROP_SELFSERVICE_ALIAS, DEFAULT_SELFSERVICE_ALIAS); | ||
|
|
||
| servletAlias = sanitizeAlias(servletAlias, DEFAULT_SERVLET_ALIAS); | ||
| selfServiceAlias = sanitizeAlias(selfServiceAlias, DEFAULT_SELFSERVICE_ALIAS); | ||
|
|
||
| defaultServletUrlPatterns = new String[] { servletAlias + "/*", selfServiceAlias + "/*" }; | ||
| logger.info("REST servlet URL patterns configured: {}, {}", servletAlias + "/*", selfServiceAlias + "/*"); | ||
|
Comment on lines
+123
to
+130
|
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -125,6 +140,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} | ||
| */ | ||
|
|
@@ -212,7 +276,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 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section claims the REST API and Self-Service UI context paths can be changed via
conf/boot/boot.properties, but the code changes in this PR only adjust the default servlet-filter urlPatterns and do not update the actual servlet registrations (the REST servlet alias is still hard-coded to/openidmin the API servlet component). As written, users following these instructions will not actually move the REST endpoints and may inadvertently cause filters to no longer apply. Please either implement the alias change end-to-end (servlet registrations + any hard-coded/openidmusages), or reword this section to describe the narrower behavior that’s actually implemented.