A dotCMS OSGI plugin that provides user proxy authentication for API requests without requiring explicit login credentials. This plugin allows you to set a user token and map it to specific HTTP methods and URL patterns to allow access without having to pass user credientials.
The User Proxy Plugin is a web interceptor-based solution for dotCMS that intercepts incoming HTTP requests and validates them against configured user proxy rules. It allows you to:
- Authenticate requests using pre-configured API tokens
- Control access by HTTP method (GET, POST, PUT, DELETE, etc.)
- Restrict endpoints using URL pattern matching with regex support
- Seamlessly integrate with dotCMS's native user and permission system
- Token-based Authentication: Validate requests using JWT tokens associated with dotCMS users
- IP based Authentication: Because tokens validity can be limited by IP, you can that limit access to this proxy by IP address as well.
- Method Filtering: Restrict access based on HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
- URL Pattern Matching: Support for regex patterns to match request URLs
- Per-Site Configuration: Configure user proxy rules on a per-site/host basis
- Dynamic Reloading: Configuration changes are reflected without requiring plugin restart
- Existing Auth Bypass: Automatically skips proxy validation if request already has valid authentication
- Secure Token Handling: Tokens are stored securely as char arrays and never logged in plain text
Download the pre-built bundle, or build it from source using the steps below. Only the current bundle is kept in this repository.
- dotCMS 26.10.28-02 (latest stable release verified on 2026-10-28)
- Java 25 (matching this dotCMS release)
- Maven 3.9+ (the included wrapper uses 3.9.9)
./mvnw clean packageThis will create an OSGi bundle JAR file in the target/ directory:
target/userproxy-26.10.28-02.jar
-
Upload the JAR through the dotCMS Dynamic Plugins UI, or copy it to the upload directory so dotCMS can register imported server packages (remove any older User Proxy bundle first):
cp target/userproxy-26.10.28-02.jar /path/to/dotcms/felix/upload/
-
Start or restart dotCMS. The plugin will automatically:
- Copy the app configuration YAML file
- Register the web interceptor
- Initialize event listeners
-
Verify installation by checking the dotCMS logs:
INFO com.dotcms.userproxy.osgi.Activator - Starting UserProxy Plugin INFO com.dotcms.userproxy.osgi.Activator - Starting App Listener
Configure rules in the User Proxy / Anonymous Access app for each site. Rules are evaluated in order; the first matching rule with a valid token supplies the request user. If no site rule authenticates the request, System Host rules are tried. Configuration is read through the dotCMS Apps API cache, so saves and deletions use dotCMS cluster invalidation; each node reloads its own values. Parsed rules and compiled patterns are reused in a node-local Caffeine cache keyed by the resolved configuration content, bounded to 100 configurations with a 10-minute idle expiry. Each request still reads the current Apps API configuration before selecting cached rules.
Security: Matching endpoints become publicly accessible with the token user's permissions. Use a least-privilege service account and narrow paths and methods. Keep configured regexes simple to avoid expensive matching on every request.
Upgrade note: URL patterns now match the entire request path, not a substring. Use /pages/protected/.* for subpaths, not the glob /pages/protected/*. Query strings are not matched. This release targets Java 25 and is not compatible with older Java runtimes.
{
"config": [
{
"userToken": "api-user-token-0xZjQ....",
"methods": "GET,POST,HEAD,OPTIONS",
"urls": [
"/api/v1/page/json(/.*)?",
"/api/v1/content/_search",
"/api/v1/graphql"
]
},
{
"userToken": "page-user-token-7gf16....",
"methods": "GET",
"urls": [
"/pages/protected/.*"
]
}
]
}| Parameter | Type | Description |
|---|---|---|
userToken |
String | JWT token associated with a dotCMS user. This token is used to authenticate requests. |
methods |
String | Comma-separated list of allowed HTTP methods (case-insensitive). Example: "GET,POST,PUT" |
urls |
Array[String] | Regular expressions matched against the entire request URI path, excluding the query string. |
API-only access for a service account:
{
"userToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"methods": "GET,POST",
"urls": [
"/api/v1/.*"
]
}Read-only access to specific pages:
{
"userToken": "token123...",
"methods": "GET",
"urls": [
"/pages/blog/.*",
"/pages/news/.*"
]
}GraphQL access:
{
"userToken": "token456...",
"methods": "POST",
"urls": [
"/api/v1/graphql"
]
}- Request Interception: Every incoming HTTP request is intercepted by the
UserProxyInterceptor - Pre-Authentication Check: If the request already has valid authentication, the plugin skips processing
- Configuration Lookup: The plugin retrieves user proxy configurations for the current site/host
- Rule Matching: The request's HTTP method and URI are matched against configured rules
- User Assignment: If a match is found, the token is validated and the associated user is assigned to the request
- Request Continuation: The request continues with the authenticated user context
Incoming Request
↓
Has Existing Auth? → YES → Skip Proxy → Continue
↓ NO
Load Site Config
↓
Match Method + URL Pattern? → NO → Continue as Anonymous
↓ YES
Validate JWT Token
↓
User Found? → YES → Assign User to Request
↓ NO
Continue with Original User
↓
End
While this plugin is designed for token-based configuration, requests can also use standard Authorization headers. If an Authorization header is present, the plugin will skip its proxy authentication process.
- OSGI bundle lifecycle management
- Registers the web interceptor on bundle start
- Copies app configuration YAML files
- Sets up event listeners for app secret changes
- Cleans up resources on bundle stop
- Implements
WebInterceptorinterface - Intercepts all HTTP requests (
/*) - Performs request validation and user assignment
- Reads per-host configuration through the dotCMS Apps API cache
- Immutable configuration model
- Stores user token, allowed methods, and URL patterns
- Provides request matching logic
- Loads and parses user proxy configurations
- Builds configuration map per site
- Copies plugin resources to dotCMS
- Manages app YAML configuration files
- Creates the apps directory when needed and closes copied resources
┌─────────────────────────────────────────────────────────────────┐
│ HTTP Request │
└────────────────────────────┬────────────────────────────────────┘
↓
┌────────────────────┐
│ UserProxyInterceptor│
│ .intercept() │
└────────┬────────────┘
↓
┌───────────────────────────┐
│ Has Existing Auth? │
└──────────┬────────────────┘
YES ↙ ↘ NO
↓ ↓
Result.NEXT │
↑ ↓
│ Get Host Config
│ ↓
│ UserProxyEntry.matches()
│ ↓
│ ┌───────────┐
│ │ Match? │
│ └─┬───────┬─┘
│ NO ↓ YES ↓
│ │ Validate Token
│ │ ↓
│ │ Set User on Request
│ ↓ ↓
└───────────┘
↓
Return Result.NEXT
com.dotcms.userproxy/
├── pom.xml # Maven configuration
├── README.md # This file
├── src/
│ ├── main/
│ │ ├── java/com/dotcms/userproxy/
│ │ │ ├── osgi/
│ │ │ │ ├── Activator.java # Bundle lifecycle
│ │ │ │ └── FileMoverUtil.java # File utilities
│ │ │ ├── interceptor/
│ │ │ │ └── UserProxyInterceptor.java # Web interceptor
│ │ │ ├── listener/
│ │ │ │ └── UserProxyAppListener.java # Event listener
│ │ │ ├── model/
│ │ │ │ ├── UserProxyEntry.java # Configuration model
│ │ │ │ └── UserProxyEntryMapper.java # Config loader
│ │ │ └── util/
│ │ │ └── AppKey.java # Constants
│ │ └── resources/
│ │ ├── Dotuserproxy.yml # App descriptor
│ │ └── example-userproxy.json # Example config
│ └── test/
│ └── java/com/dotcms/userproxy/ # Unit tests
└── target/ # Build output
Build the plugin using Maven:
./mvnw clean packageRun unit tests:
./mvnw testRun all checks and package the bundle:
./mvnw verifyThere are no live-server integration tests. Before production, deploy to staging and verify authentication, System Host fallback, configuration updates/deletions across nodes, and bundle stop/start.
The plugin follows dotCMS conventions:
- Maven Bundle Plugin for OSGi packaging
- Felix framework integration
- Logging via dotCMS Logger API
- Exception handling with DotRuntimeException
- Immutable models where appropriate
- dotcms-core (26.10.28-02) - dotCMS core API and framework (provided by the server)
- maven-bundle-plugin (6.2.0) - OSGi bundle packaging
- JUnit 5 (5.12.2) - Testing framework
- Mockito (5.24.0) - Mocking framework with Java 25 support
Runtime APIs are provided by dotCMS, not embedded in the plugin bundle.
Problem: The plugin fails to start.
Solutions:
- Check dotCMS logs for startup errors
- Verify Java version is 25
- Ensure JAR file is in the correct plugins directory
- Check that all required dotCMS core APIs are available
Problem: Requests are not being matched against user proxy rules.
Solutions:
- Verify the site or System Host has a configuration in the User Proxy app
- Check that URL patterns are valid regex expressions
- Ensure user token is correctly formatted and valid
- Verify HTTP method matches (case-insensitive)
- Check dotCMS logs for UserProxyInterceptor debug messages
Problem: Valid tokens are being rejected.
Solutions:
- Verify the token is a valid JWT for a dotCMS user
- Check token expiration date
- Ensure user associated with token is active and not locked
- Verify token permissions in dotCMS
Problem: App configuration changes are not reflected.
Solutions:
- Save valid JSON in the User Proxy app for the correct site
- Check System Host rules if deleted site rules still appear to grant access
- Verify dotCMS cache invalidations reach all cluster nodes
The plugin logs its activities using dotCMS Logger API:
INFO com.dotcms.userproxy.osgi.Activator - Starting UserProxy Plugin
INFO com.dotcms.userproxy.osgi.Activator - Copying UserProxy APP
INFO com.dotcms.userproxy.osgi.Activator - Starting App Listener
Enable debug logging to see detailed request matching:
log4j.logger.com.dotcms.userproxy=DEBUGWhen making changes to this plugin:
- Follow dotCMS code style conventions
- Add unit tests for new functionality
- Update this README if behavior changes
- Test with multiple dotCMS instances if possible
- Verify no regression in existing functionality
This plugin is provided as part of the dotCMS community plugins. Refer to the main dotCMS LICENSE file for licensing details.
For issues, questions, or contributions:
- Check the dotCMS documentation
- Review the code comments and JavaDoc
- Check dotCMS logs for error details
- Reach out to the dotCMS community
- Updated to dotCMS 26.10.28-02 and Java 25
- Restored request user assignment and System Host fallback
- Reused dotCMS Apps API caching instead of a separate versioned cache, with bounded content-keyed Caffeine caching for parsed rules
- Restricted rules to full-path regex matching and corrected examples
- Fixed resource copying, missing configuration handling, and malformed-JSON logging
- Added authentication and path-matching regression tests
- Initial release
- Core user proxy authentication functionality
- Support for token-based access control
- URL pattern matching with regex support
- Per-site configuration management
- dotCMS Official Documentation
- dotCMS OSGi Plugin Development
- Servlet 3.1 API (dotCMS still uses
javax.servlet) - OSGi Framework Specification