Web
The Arconia Multitenancy Web module adds HTTP-specific multitenancy support for Spring MVC applications. It provides tenant resolution from HTTP headers or cookies, a servlet filter for automatic context management, and a controller annotation for convenient access to the current tenant.
Dependencies
Add the Arconia Multitenancy Web Spring Boot Starter dependency to your project.
-
Gradle
-
Maven
dependencies {
implementation 'io.arconia:arconia-multitenancy-web-spring-boot-starter'
}
<dependency>
<groupId>io.arconia</groupId>
<artifactId>arconia-multitenancy-web-spring-boot-starter</artifactId>
</dependency>
The web starter includes the core multitenancy module, so all context, resolution, tenant details, and observability features are available automatically.
HTTP Tenant Resolution
The web module resolves the tenant identifier from each incoming HTTP request using a configurable strategy.
Header-Based Resolution
By default, the tenant identifier is resolved from the X-TenantId HTTP header.
-
HTTPie
-
curl
http :8080/api/resource X-TenantId:acme
curl -H "X-TenantId: acme" http://localhost:8080/api/resource
You can customize the header name:
arconia:
multitenancy:
resolution:
http:
header:
header-name: X-Custom-Tenant
Cookie-Based Resolution
Alternatively, you can resolve the tenant from an HTTP cookie by switching the resolution mode.
arconia:
multitenancy:
resolution:
http:
resolution-mode: cookie
By default, the cookie name is TENANT-ID. You can customize it:
arconia:
multitenancy:
resolution:
http:
resolution-mode: cookie
cookie:
cookie-name: MY-TENANT
Configuration Properties
| Property | Default | Description |
|---|---|---|
|
|
Whether HTTP tenant resolution is enabled. |
|
|
Mode of HTTP resolution. Options: |
|
|
Name of the HTTP header from which to resolve the current tenant. |
|
|
Name of the HTTP cookie from which to resolve the current tenant. |
Tenant Context Filter
The TenantContextFilter is a servlet filter that intercepts incoming HTTP requests, resolves the tenant, optionally verifies it via a TenantVerifier, and establishes the tenant context for the duration of the request using a ScopedValue binding. It publishes TenantContextAttachedEvent on entry and TenantContextClosedEvent on completion, triggering all registered event listeners.
If the tenant identifier cannot be resolved (e.g., the header is missing) or verification fails (e.g., the tenant is not found or disabled), the filter returns an HTTP 400 Bad Request response with a ProblemDetail JSON body describing the error.
Spring Security Integration
When using Spring Security, the TenantContextFilter is auto-configured as a standard servlet filter and runs outside the security filter chain. To ensure tenant context is available during security processing (e.g., for tenant-aware authentication or authorization), you must register the filter in the security filter chain so that it runs before security filters:
import io.arconia.multitenancy.web.context.filters.TenantContextFilter;
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationFilter;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http, TenantContextFilter tenantContextFilter) throws Exception {
return http
.addFilterBefore(tenantContextFilter, BearerTokenAuthenticationFilter.class)
// ... other security configuration
.build();
}
Ignoring Paths
Certain paths can be excluded from tenant resolution. By default, the following paths are ignored:
-
/actuator/** -
/webjars/** -
/css/** -
/js/** -
.ico
You can add additional paths to ignore without replacing the defaults:
arconia:
multitenancy:
resolution:
http:
filter:
additional-ignore-paths:
- /health
- /public/**
You can also replace the default ignored paths entirely:
arconia:
multitenancy:
resolution:
http:
filter:
ignore-paths:
- /actuator/**
- /public/**
Disabling the Filter
You can disable the tenant context filter while keeping the rest of the multitenancy configuration active:
arconia:
multitenancy:
resolution:
http:
filter:
enabled: false
Configuration Properties
| Property | Default | Description |
|---|---|---|
|
|
Whether the HTTP filter resolving the current tenant is enabled. |
|
|
HTTP request paths for which tenant resolution will not be performed. |
|
|
Additional HTTP request paths for which tenant resolution will not be performed. |
@TenantIdentifier Annotation
In Spring MVC controllers, you can inject the current tenant identifier directly into handler method parameters using the @TenantIdentifier annotation.
import io.arconia.multitenancy.web.context.annotations.TenantIdentifier;
@RestController
class TenantController {
@GetMapping("/tenant")
String currentTenant(@TenantIdentifier String tenantId) {
return tenantId;
}
}
The annotation resolves the value from the TenantContext and supports String parameters.
You can also use the TenantContext directly to access the tenant identifier from any component, not just controllers. The @TenantIdentifier annotation is a convenience for Spring MVC handler methods.
|
Custom Tenant Resolution
You can implement your own HTTP tenant resolution strategy by providing a custom HttpRequestTenantResolver bean. This replaces the default header or cookie resolver.
import io.arconia.multitenancy.web.context.resolvers.HttpRequestTenantResolver;
@Bean
HttpRequestTenantResolver customTenantResolver() {
return request -> {
// Custom logic to extract tenant from the request
return request.getParameter("tenant");
};
}
HttpRequestTenantResolver is a specialization of the core TenantResolver<T> interface for HttpServletRequest sources.