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,

Reply via email to