This is an automated email from the ASF dual-hosted git repository.
ashishvijaywargiya pushed a commit to branch release24.09
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/release24.09 by this push:
new 61d67c3b28 Improved: Align tenant resolution between LoginWorker and
ContextFilter (#1835) (#1841)
61d67c3b28 is described below
commit 61d67c3b28f5b77ca55fc977fd7b6207ebf5cfd2
Author: Ashish Vijaywargiya <[email protected]>
AuthorDate: Wed Sep 2 11:23:55 2026 +0530
Improved: Align tenant resolution between LoginWorker and ContextFilter
(#1835) (#1841)
`ContextFilter` and `LoginWorker` each resolve `userTenantId` for a
request but use opposite precedence, and `ContextFilter` updates the
session `delegatorName` in place when the resolved tenant changes. This
makes the two consistent.
- `LoginWorker.login(...)` now resolves `userTenantId` the same way
`ContextFilter` already does: request attribute first, request parameter
as fallback. Previously it read the parameter first, so the two could
resolve different tenants for the same request.
- `ContextFilter` now compares the tenant encoded in the session's
existing `delegatorName` (`name#tenantId`) against the tenant resolved
for the current request. When they differ it invalidates the session, so
`dispatcher`, `security` and `userLogin` are rebuilt for the current
tenant on the next request instead of `delegatorName` alone being
overwritten. A warning is logged when this happens.
No change for single-tenant deployments or when the session tenant and
the request tenant already match.
Thank you Krishna Uprit for the contribution.
Co-authored-by: Krishnauprit18 <[email protected]>
(cherry picked from trunk's commit
39ec4fda5c36094ea902b138a7eb2645f6d5dee4)
Co-authored-by: Krishna Uprit <[email protected]>
---
.../apache/ofbiz/webapp/control/ContextFilter.java | 26 ++++++++++++++++++++++
.../apache/ofbiz/webapp/control/LoginWorker.java | 8 +++++--
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ContextFilter.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ContextFilter.java
index a8ef72f1c3..3b39aa53e0 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ContextFilter.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ContextFilter.java
@@ -30,6 +30,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilGenerics;
@@ -143,6 +144,31 @@ public class ContextFilter implements Filter {
tenantId = null;
}
if (UtilValidate.isNotEmpty(tenantId)) {
+ // If an existing session already carries a delegatorName
for a different
+ // tenant than the one resolved for this request,
invalidate it here rather
+ // than only overwriting delegatorName below: dispatcher,
security and
+ // userLogin stay bound to the old tenant otherwise, so a
clean session is
+ // rebuilt on the next request instead. Use
getSession(false) so a request
+ // that has no session yet is left alone - it cannot carry
a stale tenant.
+ HttpSession existingSession =
httpRequest.getSession(false);
+ if (existingSession != null) {
+ String existingDelegatorName = (String)
existingSession.getAttribute("delegatorName");
+ if (UtilValidate.isNotEmpty(existingDelegatorName)) {
+ int hashIndex = existingDelegatorName.indexOf('#');
+ String existingTenantId =
+ hashIndex > 0 ?
existingDelegatorName.substring(hashIndex + 1).trim() : null;
+ if (existingTenantId != null &&
!tenantId.equals(existingTenantId)) {
+ // Log a fixed message only; request-derived
values (host name,
+ // userTenantId) are deliberately kept out of
the log line.
+ Debug.logWarning("Tenant context mismatch: the
session is bound to a"
+ + " different tenant than the one
resolved for this request."
+ + " Invalidating the session so a
clean per-tenant context is"
+ + " rebuilt on the next request.",
MODULE);
+ existingSession.invalidate();
+ }
+ }
+ }
+
// if the request path is a root mount then redirect to
the initial path
if ("".equals(httpRequest.getContextPath()) &&
"".equals(httpRequest.getServletPath())) {
GenericValue tenant =
EntityQuery.use(baseDelegator).from("Tenant").where("tenantId",
tenantId).queryOne();
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java
index 40f5842105..7d24627507 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java
@@ -457,8 +457,12 @@ public final class LoginWorker {
// if a tenantId was passed in, see if the userLoginId is associated
with that tenantId
// (can use any delegator for this, entity is not tenant-specific)
String tenantId = request.getParameter("userTenantId");
- if (UtilValidate.isEmpty(tenantId)) {
- tenantId = (String) request.getAttribute("userTenantId");
+ // Align with ContextFilter: when this request already carries a
resolved userTenantId
+ // attribute (for example from a hostname mapped to a tenant), that
value wins over a
+ // conflicting request parameter, so both components authenticate
against the same tenant.
+ String requestTenantId = (String) request.getAttribute("userTenantId");
+ if (UtilValidate.isNotEmpty(requestTenantId)) {
+ tenantId = requestTenantId;
}
if (UtilValidate.isNotEmpty(tenantId)) {
// see if we need to activate a tenant delegator, only do if the
current delegatorName has a hash symbol in it,