You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2026/03/19 03:51:20 UTC

(ranger) branch ranger-2.9 updated (f8e9f1220 -> daf23a439)

This is an automated email from the ASF dual-hosted git repository.

abhi pushed a change to branch ranger-2.9
in repository https://gitbox.apache.org/repos/asf/ranger.git


    from f8e9f1220 RANGER-5517: remove ranger-plugins-common dependency from kms, embeddedwebserver and shim modules (#876)
     new 1e1206273 RANGER-5499: Add support for header based authentication (#873)
     new daf23a439 RANGER-5499: Refactor to use Filter and fix error in catalina.out

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 mkdocs/.gitignore                                  |   1 +
 ...ication.java => RangerAuthenticationToken.java} |  65 ++----
 .../web/filter/RangerHeaderPreAuthFilter.java      | 127 +++++++++++
 .../RangerSecurityContextFormationFilter.java      |  49 ++--
 .../main/resources/conf.dist/ranger-admin-site.xml |  14 ++
 .../conf.dist/security-applicationContext.xml      |   4 +
 .../web/filter/TestRangerHeaderPreAuthFilter.java  | 179 +++++++++++++++
 .../TestRangerSecurityContextFormationFilter.java  | 250 +++++++++++++++++++++
 8 files changed, 631 insertions(+), 58 deletions(-)
 create mode 100644 mkdocs/.gitignore
 copy security-admin/src/main/java/org/apache/ranger/security/web/filter/{SSOAuthentication.java => RangerAuthenticationToken.java} (50%)
 create mode 100644 security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java
 create mode 100644 security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java
 create mode 100644 security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerSecurityContextFormationFilter.java


(ranger) 02/02: RANGER-5499: Refactor to use Filter and fix error in catalina.out

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

abhi pushed a commit to branch ranger-2.9
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit daf23a439bae1f3e300ec2743347099f522e2d00
Author: Abhishek Kumar <ab...@apache.org>
AuthorDate: Wed Mar 18 15:12:45 2026 -0700

    RANGER-5499: Refactor to use Filter and fix error in catalina.out
    
    (cherry picked from commit a6c21a19aa2522f882301bccce03e6c28701522a)
    (cherry picked from commit 9a57bab6237a947d9864f699de2c31b00fc280bc)
---
 .../web/filter/RangerHeaderPreAuthFilter.java      | 36 ++++++++++++++--------
 .../web/filter/TestRangerHeaderPreAuthFilter.java  |  8 ++---
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java
index 89bb78750..6672e3c3c 100644
--- a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java
+++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java
@@ -32,9 +32,8 @@
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.web.authentication.WebAuthenticationDetails;
-import org.springframework.web.filter.GenericFilterBean;
 
-import javax.annotation.PostConstruct;
+import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -47,12 +46,12 @@
 import java.util.Collection;
 import java.util.List;
 
-public class RangerHeaderPreAuthFilter extends GenericFilterBean {
+public class RangerHeaderPreAuthFilter implements Filter {
     private static final Logger LOG = LoggerFactory.getLogger(RangerHeaderPreAuthFilter.class);
 
-    public static final String PROP_HEADER_AUTH_ENABLED        = "ranger.admin.authn.header.enabled";
-    public static final String PROP_USERNAME_HEADER_NAME       = "ranger.admin.authn.header.username";
-    public static final String PROP_REQUEST_ID_HEADER_NAME     = "ranger.admin.authn.header.requestid";
+    public static final String PROP_HEADER_AUTH_ENABLED    = "ranger.admin.authn.header.enabled";
+    public static final String PROP_USERNAME_HEADER_NAME   = "ranger.admin.authn.header.username";
+    public static final String PROP_REQUEST_ID_HEADER_NAME = "ranger.admin.authn.header.requestid";
 
     private boolean headerAuthEnabled;
     private String  userNameHeaderName;
@@ -60,21 +59,32 @@ public class RangerHeaderPreAuthFilter extends GenericFilterBean {
     @Autowired
     UserMgr userMgr;
 
-    @PostConstruct
-    public void initialize(FilterConfig filterConfig) throws ServletException {
+    public RangerHeaderPreAuthFilter() {
+        loadConfiguration();
+    }
+
+    @Override
+    public void init(FilterConfig config) throws ServletException {
+        loadConfiguration();
+    }
+
+    private void loadConfiguration() {
         headerAuthEnabled  = PropertiesUtil.getBooleanProperty(PROP_HEADER_AUTH_ENABLED, false);
         userNameHeaderName = PropertiesUtil.getProperty(PROP_USERNAME_HEADER_NAME);
     }
 
     @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-        HttpServletRequest  httpRequest  = (HttpServletRequest) request;
+    public void destroy() {
+    }
 
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
         if (headerAuthEnabled) {
             Authentication existingAuthn = SecurityContextHolder.getContext().getAuthentication();
 
             if (existingAuthn == null || !existingAuthn.isAuthenticated()) {
-                String username = StringUtils.trimToNull(httpRequest.getHeader(userNameHeaderName));
+                HttpServletRequest  httpRequest = (HttpServletRequest) request;
+                String              username    = StringUtils.trimToNull(httpRequest.getHeader(userNameHeaderName));
 
                 if (StringUtils.isNotBlank(username)) {
                     List<GrantedAuthority>    grantedAuthorities = getAuthoritiesFromRanger(username);
@@ -101,8 +111,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
      * Loads authorities from Ranger DB
      */
     private List<GrantedAuthority> getAuthoritiesFromRanger(String username) {
-        List<GrantedAuthority> ret = new ArrayList<>();
-        Collection<String>    roleList = userMgr.getRolesByLoginId(username);
+        List<GrantedAuthority> ret      = new ArrayList<>();
+        Collection<String>     roleList = userMgr.getRolesByLoginId(username);
 
         if (roleList != null) {
             for (String role : roleList) {
diff --git a/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java
index 2ed69a6fb..e90dd6fae 100644
--- a/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java
+++ b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java
@@ -75,7 +75,7 @@ public void testDoFilter_disabled_passesThrough() throws Exception {
         UserMgr                   userMgr = mock(UserMgr.class);
 
         filter.userMgr = userMgr;
-        filter.initialize(null);
+        filter.init(null);
 
         HttpServletRequest  request  = mock(HttpServletRequest.class);
         HttpServletResponse response = mock(HttpServletResponse.class);
@@ -97,7 +97,7 @@ public void testDoFilter_enabled_missingUsername_passesThrough() throws Exceptio
         UserMgr                   userMgr = mock(UserMgr.class);
 
         filter.userMgr = userMgr;
-        filter.initialize(null);
+        filter.init(null);
 
         HttpServletRequest  request  = mock(HttpServletRequest.class);
         HttpServletResponse response = mock(HttpServletResponse.class);
@@ -121,7 +121,7 @@ public void testDoFilter_enabled_withUsername_setsAuthenticationFromRangerDbRole
         UserMgr                   userMgr = mock(UserMgr.class);
 
         filter.userMgr = userMgr;
-        filter.initialize(null);
+        filter.init(null);
 
         when(userMgr.getRolesByLoginId("joeuser")).thenReturn(Arrays.asList("ROLE_SYS_ADMIN", "ROLE_USER"));
 
@@ -160,7 +160,7 @@ public void testDoFilter_enabled_existingAuthenticatedContext_doesNotOverrideAut
         UserMgr                   userMgr = mock(UserMgr.class);
 
         filter.userMgr = userMgr;
-        filter.initialize(null);
+        filter.init(null);
 
         UsernamePasswordAuthenticationToken existingAuth = new UsernamePasswordAuthenticationToken("existing-user", "pwd", Collections.singletonList(new SimpleGrantedAuthority("test-role")));
 


(ranger) 01/02: RANGER-5499: Add support for header based authentication (#873)

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

abhi pushed a commit to branch ranger-2.9
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit 1e12062734992e5de38a8b910e0183c31af2d2c9
Author: Abhishek Kumar <ab...@apache.org>
AuthorDate: Wed Mar 18 12:25:53 2026 -0700

    RANGER-5499: Add support for header based authentication (#873)
    
    Co-authored-by: Madhan Neethiraj <ma...@apache.org>
    Co-authored-by: Cursor AI (assisted) <no...@cursor.com>
    (cherry picked from commit 2345c1d79d63f632bab237a8b08426d056b30f6c)
    (cherry picked from commit d40fac0b695007394dab90be0b8384f2c51aea03)
---
 mkdocs/.gitignore                                  |   1 +
 .../web/filter/RangerAuthenticationToken.java      |  55 +++++
 .../web/filter/RangerHeaderPreAuthFilter.java      | 117 ++++++++++
 .../RangerSecurityContextFormationFilter.java      |  49 ++--
 .../main/resources/conf.dist/ranger-admin-site.xml |  14 ++
 .../conf.dist/security-applicationContext.xml      |   4 +
 .../web/filter/TestRangerHeaderPreAuthFilter.java  | 179 +++++++++++++++
 .../TestRangerSecurityContextFormationFilter.java  | 250 +++++++++++++++++++++
 8 files changed, 653 insertions(+), 16 deletions(-)

diff --git a/mkdocs/.gitignore b/mkdocs/.gitignore
new file mode 100644
index 000000000..988107fe1
--- /dev/null
+++ b/mkdocs/.gitignore
@@ -0,0 +1 @@
+.cache/
\ No newline at end of file
diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerAuthenticationToken.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerAuthenticationToken.java
new file mode 100644
index 000000000..ccf43a417
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerAuthenticationToken.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.security.web.filter;
+
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+
+public class RangerAuthenticationToken extends AbstractAuthenticationToken {
+    private static final long serialVersionUID = 1L;
+
+    private final Object principal;
+    private final int    authType;
+
+    public RangerAuthenticationToken(UserDetails principal, Collection<? extends GrantedAuthority> authorities, int authType) {
+        super(authorities);
+
+        this.principal = principal;
+        this.authType  = authType;
+
+        super.setAuthenticated(true);
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return principal;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return null;
+    }
+
+    public int getAuthType() {
+        return authType;
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java
new file mode 100644
index 000000000..89bb78750
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerHeaderPreAuthFilter.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.security.web.filter;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.biz.UserMgr;
+import org.apache.ranger.common.PropertiesUtil;
+import org.apache.ranger.entity.XXAuthSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
+import org.springframework.web.filter.GenericFilterBean;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class RangerHeaderPreAuthFilter extends GenericFilterBean {
+    private static final Logger LOG = LoggerFactory.getLogger(RangerHeaderPreAuthFilter.class);
+
+    public static final String PROP_HEADER_AUTH_ENABLED        = "ranger.admin.authn.header.enabled";
+    public static final String PROP_USERNAME_HEADER_NAME       = "ranger.admin.authn.header.username";
+    public static final String PROP_REQUEST_ID_HEADER_NAME     = "ranger.admin.authn.header.requestid";
+
+    private boolean headerAuthEnabled;
+    private String  userNameHeaderName;
+
+    @Autowired
+    UserMgr userMgr;
+
+    @PostConstruct
+    public void initialize(FilterConfig filterConfig) throws ServletException {
+        headerAuthEnabled  = PropertiesUtil.getBooleanProperty(PROP_HEADER_AUTH_ENABLED, false);
+        userNameHeaderName = PropertiesUtil.getProperty(PROP_USERNAME_HEADER_NAME);
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest  httpRequest  = (HttpServletRequest) request;
+
+        if (headerAuthEnabled) {
+            Authentication existingAuthn = SecurityContextHolder.getContext().getAuthentication();
+
+            if (existingAuthn == null || !existingAuthn.isAuthenticated()) {
+                String username = StringUtils.trimToNull(httpRequest.getHeader(userNameHeaderName));
+
+                if (StringUtils.isNotBlank(username)) {
+                    List<GrantedAuthority>    grantedAuthorities = getAuthoritiesFromRanger(username);
+                    final UserDetails         principal          = new User(username, "", grantedAuthorities);
+                    RangerAuthenticationToken authToken          = new RangerAuthenticationToken(principal, grantedAuthorities, XXAuthSession.AUTH_TYPE_TRUSTED_PROXY);
+
+                    authToken.setDetails(new WebAuthenticationDetails(httpRequest));
+
+                    SecurityContextHolder.getContext().setAuthentication(authToken);
+
+                    LOG.debug("Authenticated request using trusted headers for user={}", username);
+                } else {
+                    LOG.debug("Username header '{}' is missing or empty in the request!", userNameHeaderName);
+                }
+            }
+        } else {
+            LOG.debug("Header-based authentication is disabled!");
+        }
+
+        chain.doFilter(request, response);
+    }
+
+    /**
+     * Loads authorities from Ranger DB
+     */
+    private List<GrantedAuthority> getAuthoritiesFromRanger(String username) {
+        List<GrantedAuthority> ret = new ArrayList<>();
+        Collection<String>    roleList = userMgr.getRolesByLoginId(username);
+
+        if (roleList != null) {
+            for (String role : roleList) {
+                if (StringUtils.isNotBlank(role)) {
+                    ret.add(new SimpleGrantedAuthority(role));
+                }
+            }
+        }
+
+        return ret;
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSecurityContextFormationFilter.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSecurityContextFormationFilter.java
index 71d7af0d1..65706070f 100644
--- a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSecurityContextFormationFilter.java
+++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSecurityContextFormationFilter.java
@@ -32,6 +32,7 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.ranger.biz.SessionMgr;
 import org.apache.ranger.biz.XUserMgr;
 import org.apache.ranger.common.GUIDUtil;
@@ -43,6 +44,8 @@
 import org.apache.ranger.security.context.RangerContextHolder;
 import org.apache.ranger.security.context.RangerSecurityContext;
 import org.apache.ranger.util.RestUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.core.Authentication;
@@ -50,6 +53,7 @@
 import org.springframework.web.filter.GenericFilterBean;
 
 public class RangerSecurityContextFormationFilter extends GenericFilterBean {
+	private static final Logger LOG = LoggerFactory.getLogger(RangerSecurityContextFormationFilter.class);
 
 	public static final String AKA_SC_SESSION_KEY = "AKA_SECURITY_CONTEXT";
 	public static final String USER_AGENT = "User-Agent";
@@ -65,11 +69,13 @@ public class RangerSecurityContextFormationFilter extends GenericFilterBean {
 
 	@Autowired
 	GUIDUtil guidUtil;
-		
-	String testIP = null;
+
+	private final String testIP;
+	private final String requestIdHeaderName;
 
 	public RangerSecurityContextFormationFilter() {
-		testIP = PropertiesUtil.getProperty("xa.env.ip");
+		this.testIP              = PropertiesUtil.getProperty("xa.env.ip");
+		this.requestIdHeaderName = PropertiesUtil.getProperty(RangerHeaderPreAuthFilter.PROP_REQUEST_ID_HEADER_NAME);
 	}
 
 	/*
@@ -113,14 +119,14 @@ public void doFilter(ServletRequest request, ServletResponse response,
 				requestContext.setUserAgent(userAgent);
 				requestContext.setDeviceType(httpUtil
 						.getDeviceType(httpRequest));
-				requestContext.setServerRequestId(guidUtil.genGUID());
+				requestContext.setServerRequestId(getRequestId(auth, httpRequest));
 				requestContext.setRequestURL(httpRequest.getRequestURI());
 
 				requestContext.setClientTimeOffsetInMinute(clientTimeOffset);
 				context.setRequestContext(requestContext);
 
 				RangerContextHolder.setSecurityContext(context);
-				int authType = getAuthType(httpRequest);
+				int authType = getAuthType(auth, httpRequest);
 				UserSessionBase userSession = sessionMgr.processSuccessLogin(
 						authType, userAgent, httpRequest);
 
@@ -159,25 +165,36 @@ private void setupAdminOpContext(ServletRequest request) {
 		}
 	}
 
-	private int getAuthType(HttpServletRequest request) {
-		int authType;
+	private int getAuthType(Authentication auth, HttpServletRequest request) {
+		if (auth instanceof RangerAuthenticationToken) {
+			return ((RangerAuthenticationToken) auth).getAuthType();
+		}
+
 		Object ssoEnabledObj = request.getAttribute("ssoEnabled");
 		Boolean ssoEnabled = ssoEnabledObj != null ? Boolean.valueOf(String.valueOf(ssoEnabledObj)) : PropertiesUtil.getBooleanProperty("ranger.sso.enabled", false);
 
 		if (ssoEnabled) {
-			authType = XXAuthSession.AUTH_TYPE_SSO;
+			return XXAuthSession.AUTH_TYPE_SSO;
 		} else if (request.getAttribute("spnegoEnabled") != null && Boolean.valueOf(String.valueOf(request.getAttribute("spnegoEnabled")))){
 			if (request.getAttribute("trustedProxyEnabled") != null && Boolean.valueOf(String.valueOf(request.getAttribute("trustedProxyEnabled")))) {
-				if (logger.isDebugEnabled()) {
-					logger.debug("Setting auth type as trusted proxy");
-				}
-				authType = XXAuthSession.AUTH_TYPE_TRUSTED_PROXY;
+				LOG.debug("Setting auth type as trusted proxy");
+
+				return XXAuthSession.AUTH_TYPE_TRUSTED_PROXY;
 			} else {
-				authType = XXAuthSession.AUTH_TYPE_KERBEROS;
+				return XXAuthSession.AUTH_TYPE_KERBEROS;
 			}
-		} else {
-			authType = XXAuthSession.AUTH_TYPE_PASSWORD;
 		}
-		return authType;
+
+		return XXAuthSession.AUTH_TYPE_PASSWORD;
+	}
+
+	private String getRequestId(Authentication auth, HttpServletRequest request) {
+		String ret = null;
+
+		if (requestIdHeaderName != null && auth instanceof RangerAuthenticationToken && ((RangerAuthenticationToken) auth).getAuthType() == XXAuthSession.AUTH_TYPE_TRUSTED_PROXY) {
+			ret = StringUtils.trimToNull(request.getHeader(requestIdHeaderName));
+		}
+
+		return ret != null ? ret : guidUtil.genGUID();
 	}
 }
diff --git a/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml b/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
index 2da6f1c43..d1fccc27d 100644
--- a/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
+++ b/security-admin/src/main/resources/conf.dist/ranger-admin-site.xml
@@ -271,6 +271,20 @@
 		<value>Mozilla,chrome</value>
 	</property>
 	<!-- SSO Properties Ends-->
+	<!-- Trusted header auth properties start -->
+	<property>
+		<name>ranger.admin.authn.header.enabled</name>
+		<value>false</value>
+	</property>
+	<property>
+		<name>ranger.admin.authn.header.username</name>
+		<value>x-awc-username</value>
+	</property>
+	<property>
+		<name>ranger.admin.authn.header.requestid</name>
+		<value>x-awc-requestid</value>
+	</property>
+	<!-- Trusted header auth properties end -->
 	<!-- Kerberos Properties starts-->	
 	<property>
 		<name>ranger.admin.kerberos.token.valid.seconds</name>
diff --git a/security-admin/src/main/resources/conf.dist/security-applicationContext.xml b/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
index 8c0ad7ea6..a1dcacd1a 100644
--- a/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
+++ b/security-admin/src/main/resources/conf.dist/security-applicationContext.xml
@@ -62,6 +62,7 @@ http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
 		</security:headers>
 		<security:session-management session-fixation-protection="newSession" />
 		<intercept-url pattern="/**" access="isAuthenticated()"/>
+		<security:custom-filter position="PRE_AUTH_FILTER" ref="headerPreAuthFilter" />
 		<custom-filter ref="ssoAuthenticationFilter" after="BASIC_AUTH_FILTER" />
 		<security:custom-filter ref="rangerJwtAuthWrapper" before="SERVLET_API_SUPPORT_FILTER" />
 		<security:custom-filter ref="krbAuthenticationFilter" after="SERVLET_API_SUPPORT_FILTER" />
@@ -113,6 +114,9 @@ http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
 	<beans:bean id="mdcFilter" class="org.apache.ranger.security.web.filter.RangerMDCFilter">
     </beans:bean>
 
+	<beans:bean id="headerPreAuthFilter" class="org.apache.ranger.security.web.filter.RangerHeaderPreAuthFilter">
+    </beans:bean>
+
     <beans:bean id="ssoAuthenticationFilter" class="org.apache.ranger.security.web.filter.RangerSSOAuthenticationFilter">
     </beans:bean>
 	
diff --git a/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java
new file mode 100644
index 000000000..2ed69a6fb
--- /dev/null
+++ b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerHeaderPreAuthFilter.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.security.web.filter;
+
+import org.apache.ranger.biz.UserMgr;
+import org.apache.ranger.common.PropertiesUtil;
+import org.apache.ranger.entity.XXAuthSession;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerHeaderPreAuthFilter {
+    @BeforeEach
+    public void setUp() {
+        SecurityContextHolder.clearContext();
+    }
+
+    @AfterEach
+    public void tearDown() {
+        SecurityContextHolder.clearContext();
+
+        PropertiesUtil.getPropertiesMap().remove(RangerHeaderPreAuthFilter.PROP_HEADER_AUTH_ENABLED);
+        PropertiesUtil.getPropertiesMap().remove(RangerHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME);
+        PropertiesUtil.getPropertiesMap().remove(RangerHeaderPreAuthFilter.PROP_REQUEST_ID_HEADER_NAME);
+    }
+
+    @Test
+    public void testDoFilter_disabled_passesThrough() throws Exception {
+        RangerHeaderPreAuthFilter filter  = new RangerHeaderPreAuthFilter();
+        UserMgr                   userMgr = mock(UserMgr.class);
+
+        filter.userMgr = userMgr;
+        filter.initialize(null);
+
+        HttpServletRequest  request  = mock(HttpServletRequest.class);
+        HttpServletResponse response = mock(HttpServletResponse.class);
+        FilterChain         chain    = mock(FilterChain.class);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(userMgr, never()).getRolesByLoginId(anyString());
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    public void testDoFilter_enabled_missingUsername_passesThrough() throws Exception {
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_HEADER_AUTH_ENABLED, "true");
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME, "x-awc-username");
+
+        RangerHeaderPreAuthFilter filter  = new RangerHeaderPreAuthFilter();
+        UserMgr                   userMgr = mock(UserMgr.class);
+
+        filter.userMgr = userMgr;
+        filter.initialize(null);
+
+        HttpServletRequest  request  = mock(HttpServletRequest.class);
+        HttpServletResponse response = mock(HttpServletResponse.class);
+        FilterChain         chain    = mock(FilterChain.class);
+
+        // no username header — getHeader returns null by default
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(userMgr, never()).getRolesByLoginId(anyString());
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    public void testDoFilter_enabled_withUsername_setsAuthenticationFromRangerDbRoles() throws Exception {
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_HEADER_AUTH_ENABLED, "true");
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME, "x-awc-username");
+
+        RangerHeaderPreAuthFilter filter  = new RangerHeaderPreAuthFilter();
+        UserMgr                   userMgr = mock(UserMgr.class);
+
+        filter.userMgr = userMgr;
+        filter.initialize(null);
+
+        when(userMgr.getRolesByLoginId("joeuser")).thenReturn(Arrays.asList("ROLE_SYS_ADMIN", "ROLE_USER"));
+
+        HttpServletRequest  request  = mock(HttpServletRequest.class);
+        HttpServletResponse response = mock(HttpServletResponse.class);
+
+        when(request.getHeader("x-awc-username")).thenReturn("joeuser");
+
+        FilterChain chain = new FilterChain() {
+            @Override
+            public void doFilter(ServletRequest req, ServletResponse res) {
+                org.springframework.security.core.Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+                assertNotNull(auth);
+                assertTrue(auth instanceof RangerAuthenticationToken);
+                RangerAuthenticationToken rangerAuth = (RangerAuthenticationToken) auth;
+                assertEquals(XXAuthSession.AUTH_TYPE_TRUSTED_PROXY, rangerAuth.getAuthType());
+                assertEquals("joeuser", auth.getName());
+
+                Collection<?> authorities = auth.getAuthorities();
+                assertEquals(2, authorities.size());
+                assertTrue(authorities.stream().anyMatch(a -> "ROLE_SYS_ADMIN".equals(a.toString())));
+                assertTrue(authorities.stream().anyMatch(a -> "ROLE_USER".equals(a.toString())));
+            }
+        };
+
+        filter.doFilter(request, response, chain);
+    }
+
+    @Test
+    public void testDoFilter_enabled_existingAuthenticatedContext_doesNotOverrideAuthentication() throws Exception {
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_HEADER_AUTH_ENABLED, "true");
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME, "x-awc-username");
+
+        RangerHeaderPreAuthFilter filter  = new RangerHeaderPreAuthFilter();
+        UserMgr                   userMgr = mock(UserMgr.class);
+
+        filter.userMgr = userMgr;
+        filter.initialize(null);
+
+        UsernamePasswordAuthenticationToken existingAuth = new UsernamePasswordAuthenticationToken("existing-user", "pwd", Collections.singletonList(new SimpleGrantedAuthority("test-role")));
+
+        SecurityContextHolder.getContext().setAuthentication(existingAuth);
+
+        HttpServletRequest  request  = mock(HttpServletRequest.class);
+        HttpServletResponse response = mock(HttpServletResponse.class);
+        FilterChain         chain    = mock(FilterChain.class);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(userMgr, never()).getRolesByLoginId(anyString());
+        assertEquals(existingAuth, SecurityContextHolder.getContext().getAuthentication());
+    }
+}
diff --git a/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerSecurityContextFormationFilter.java b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerSecurityContextFormationFilter.java
new file mode 100644
index 000000000..ff9f059bc
--- /dev/null
+++ b/security-admin/src/test/java/org/apache/ranger/security/web/filter/TestRangerSecurityContextFormationFilter.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.security.web.filter;
+
+import org.apache.ranger.biz.SessionMgr;
+import org.apache.ranger.biz.XUserMgr;
+import org.apache.ranger.common.GUIDUtil;
+import org.apache.ranger.common.HTTPUtil;
+import org.apache.ranger.common.PropertiesUtil;
+import org.apache.ranger.common.RangerCommonEnums;
+import org.apache.ranger.common.UserSessionBase;
+import org.apache.ranger.entity.XXAuthSession;
+import org.apache.ranger.security.context.RangerContextHolder;
+import org.apache.ranger.security.context.RangerSecurityContext;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for TestRangerSecurityContextFormationFilter class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerSecurityContextFormationFilter {
+    @AfterEach
+    public void tearDown() {
+        SecurityContextHolder.clearContext();
+        RangerContextHolder.resetSecurityContext();
+        RangerContextHolder.resetOpContext();
+    }
+
+    @Test
+    public void testDoFilter_setsSecurityHeadersAndCleansContext() throws IOException, ServletException {
+        RangerSecurityContextFormationFilter filter = new RangerSecurityContextFormationFilter();
+
+        // mock authenticated user to drive context creation path
+        GrantedAuthority auth = new SimpleGrantedAuthority("ROLE_USER");
+        Authentication authentication = new AnonymousAuthenticationToken("key", "principal", Collections.singletonList(auth));
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+        FilterChain chain = Mockito.mock(FilterChain.class);
+
+        filter.doFilter(req, res, chain);
+
+        // Verify headers
+        verify(res).setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
+        verify(res).setHeader("X-Frame-Options", "DENY");
+        verify(res).setHeader("X-XSS-Protection", "1; mode=block");
+        verify(res).setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
+        verify(res).setHeader("Content-Security-Policy",
+                "default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';font-src 'self'");
+        verify(res).setHeader("X-Permitted-Cross-Domain-Policies", "none");
+
+        verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
+
+        // filter should clean up thread locals
+        assertNull(RangerContextHolder.getSecurityContext());
+        assertNull(RangerContextHolder.getOpContext());
+    }
+
+    @Test
+    public void testDoFilter_setsCreatePrincipalsIfAbsentFlag() throws Exception {
+        RangerSecurityContextFormationFilter filter = new RangerSecurityContextFormationFilter();
+
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+
+        // Set anonymous auth to skip dependency calls but still execute
+        // setupAdminOpContext
+        GrantedAuthority ga = new SimpleGrantedAuthority("ROLE_ANON");
+        Authentication anon = new AnonymousAuthenticationToken("k", "p", Collections.singletonList(ga));
+        SecurityContextHolder.getContext().setAuthentication(anon);
+
+        when(req.getParameter("createPrincipalsIfAbsent")).thenReturn("true");
+
+        FilterChain chain = new FilterChain() {
+            @Override
+            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+                Boolean flag = RangerContextHolder.getOpContext() != null
+                        ? RangerContextHolder.getOpContext().getCreatePrincipalsIfAbsent()
+                        : null;
+                assertEquals(Boolean.TRUE, flag);
+            }
+        };
+
+        filter.doFilter(req, res, chain);
+
+        verify(res, times(1)).setHeader("X-Frame-Options", "DENY");
+    }
+
+    @Test
+    public void testGetAuthType_reflectionVariants() throws Exception {
+        RangerSecurityContextFormationFilter filter = new RangerSecurityContextFormationFilter();
+        Method m = RangerSecurityContextFormationFilter.class.getDeclaredMethod("getAuthType", Authentication.class, HttpServletRequest.class);
+        m.setAccessible(true);
+
+        List<GrantedAuthority> authorities  = Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
+        UserDetails            userDetails  = new org.springframework.security.core.userdetails.User("u", "", authorities);
+        HttpServletRequest     emptyRequest = Mockito.mock(HttpServletRequest.class);
+
+        // Header-based trusted proxy — identified via RangerAuthenticationToken, no request attributes needed
+        assertEquals(XXAuthSession.AUTH_TYPE_TRUSTED_PROXY,
+                m.invoke(filter, new RangerAuthenticationToken(userDetails, authorities, XXAuthSession.AUTH_TYPE_TRUSTED_PROXY), emptyRequest));
+
+        // SSO — identified via request attribute (RangerSSOAuthenticationFilter sets UsernamePasswordAuthenticationToken)
+        HttpServletRequest reqSso = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(reqSso.getAttribute("ssoEnabled")).thenReturn(true);
+        assertEquals(XXAuthSession.AUTH_TYPE_SSO,
+                m.invoke(filter, new org.springframework.security.authentication.UsernamePasswordAuthenticationToken("u", "pwd", authorities), reqSso));
+
+        // Kerberos — identified via spnegoEnabled attribute
+        HttpServletRequest reqKrb = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(reqKrb.getAttribute("ssoEnabled")).thenReturn(false);
+        Mockito.when(reqKrb.getAttribute("spnegoEnabled")).thenReturn(true);
+        Mockito.when(reqKrb.getAttribute("trustedProxyEnabled")).thenReturn(false);
+        assertEquals(XXAuthSession.AUTH_TYPE_KERBEROS,
+                m.invoke(filter, new org.springframework.security.authentication.UsernamePasswordAuthenticationToken("u", "pwd", authorities), reqKrb));
+
+        // Kerberos trusted proxy — both spnegoEnabled and trustedProxyEnabled
+        HttpServletRequest reqKrbTp = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(reqKrbTp.getAttribute("ssoEnabled")).thenReturn(false);
+        Mockito.when(reqKrbTp.getAttribute("spnegoEnabled")).thenReturn(true);
+        Mockito.when(reqKrbTp.getAttribute("trustedProxyEnabled")).thenReturn(true);
+        assertEquals(XXAuthSession.AUTH_TYPE_TRUSTED_PROXY,
+                m.invoke(filter, new org.springframework.security.authentication.UsernamePasswordAuthenticationToken("u", "pwd", authorities), reqKrbTp));
+
+        // Password — no RangerAuthenticationToken, ssoEnabled explicitly false, no Kerberos attributes
+        HttpServletRequest reqPwd = Mockito.mock(HttpServletRequest.class);
+        Mockito.when(reqPwd.getAttribute("ssoEnabled")).thenReturn(false);
+        assertEquals(XXAuthSession.AUTH_TYPE_PASSWORD,
+                m.invoke(filter, new org.springframework.security.authentication.UsernamePasswordAuthenticationToken("u", "pwd", authorities), reqPwd));
+    }
+
+    @Test
+    public void testDoFilter_authenticated_createsSecurityContextAndUserSession() throws Exception {
+        PropertiesUtil.getPropertiesMap().put(RangerHeaderPreAuthFilter.PROP_REQUEST_ID_HEADER_NAME, "x-awc-requestid");
+
+        try {
+            RangerSecurityContextFormationFilter filter = new RangerSecurityContextFormationFilter();
+
+            SessionMgr sessionMgr = Mockito.mock(SessionMgr.class);
+            HTTPUtil   httpUtil   = Mockito.mock(HTTPUtil.class);
+            GUIDUtil   guidUtil   = Mockito.mock(GUIDUtil.class);
+            XUserMgr   xUserMgr   = Mockito.mock(XUserMgr.class);
+
+            filter.sessionMgr = sessionMgr;
+            filter.httpUtil   = httpUtil;
+            filter.guidUtil   = guidUtil;
+            filter.xUserMgr   = xUserMgr;
+
+            List<GrantedAuthority>   authorities    = Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
+            UserDetails              userDetails    = new org.springframework.security.core.userdetails.User("user", "", authorities);
+            RangerAuthenticationToken authentication = new RangerAuthenticationToken(userDetails, authorities, XXAuthSession.AUTH_TYPE_TRUSTED_PROXY);
+
+            SecurityContextHolder.getContext().setAuthentication(authentication);
+
+            HttpServletRequest  req     = Mockito.mock(HttpServletRequest.class);
+            HttpServletResponse res     = Mockito.mock(HttpServletResponse.class);
+            HttpSession         session = Mockito.mock(HttpSession.class);
+
+            Mockito.when(req.getSession(false)).thenReturn(session);
+            Mockito.when(session.getAttribute(RangerSecurityContextFormationFilter.AKA_SC_SESSION_KEY)).thenReturn(null);
+            Mockito.when(req.getHeader(RangerSecurityContextFormationFilter.USER_AGENT)).thenReturn("Mozilla/5.0");
+            Mockito.when(req.getHeader("x-awc-requestid")).thenReturn("awc-request-1");
+            Mockito.when(req.getRequestURI()).thenReturn("/secure");
+            Mockito.when(httpUtil.getDeviceType(req)).thenReturn(RangerCommonEnums.DEVICE_BROWSER);
+
+            UserSessionBase userSession = Mockito.mock(UserSessionBase.class);
+
+            Mockito.when(userSession.getClientTimeOffsetInMinute()).thenReturn(0);
+            Mockito.when(sessionMgr.processSuccessLogin(Mockito.anyInt(), Mockito.anyString(), Mockito.any(HttpServletRequest.class)))
+                    .thenReturn(userSession);
+
+            FilterChain chain = new FilterChain() {
+                @Override
+                public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
+                    RangerSecurityContext ctx = RangerContextHolder.getSecurityContext();
+
+                    assertNotNull(ctx);
+                    assertNotNull(ctx.getRequestContext());
+                    assertEquals("awc-request-1", ctx.getRequestContext().getServerRequestId());
+                    assertSame(userSession, ctx.getUserSession());
+                }
+            };
+
+            filter.doFilter(req, res, chain);
+
+            Mockito.verify(session, Mockito.times(1)).setAttribute(Mockito.eq(RangerSecurityContextFormationFilter.AKA_SC_SESSION_KEY), Mockito.any());
+            Mockito.verify(res).setHeader("X-Frame-Options", "DENY");
+            Mockito.verify(sessionMgr, Mockito.times(1)).processSuccessLogin(Mockito.anyInt(), Mockito.anyString(), Mockito.any(HttpServletRequest.class));
+            Mockito.verify(userSession, Mockito.times(1)).setClientTimeOffsetInMinute(Mockito.anyInt());
+
+            assertNull(RangerContextHolder.getSecurityContext());
+            assertNull(RangerContextHolder.getOpContext());
+        } finally {
+            PropertiesUtil.getPropertiesMap().remove(RangerHeaderPreAuthFilter.PROP_REQUEST_ID_HEADER_NAME);
+        }
+    }
+}