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

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


The following commit(s) were added to refs/heads/ranger-2.10 by this push:
     new 96fd9264b RANGER-5816: Add support for header based authentication in 
audit-ingestor service (#1279)
96fd9264b is described below

commit 96fd9264ba186d8a3f0872a5ffa049f8143ff47f
Author: Abhishek Kumar <[email protected]>
AuthorDate: Thu Oct 1 22:19:24 2026 -0700

    RANGER-5816: Add support for header based authentication in audit-ingestor 
service (#1279)
    
    (cherry picked from commit 3a7590544aba27016d9d543aba09cb45f163ad9a)
---
 audit-server/audit-ingestor/pom.xml                |   6 +
 .../org/apache/ranger/audit/rest/AuditREST.java    |   2 +-
 .../audit/security/AuditHeaderPreAuthFilter.java   | 142 ++++++++++++
 .../resources/conf/ranger-audit-ingestor-site.xml  |  23 ++
 .../webapp/WEB-INF/security-applicationContext.xml |   3 +
 .../security/AuditHeaderPreAuthFilterTest.java     | 257 +++++++++++++++++++++
 6 files changed, 432 insertions(+), 1 deletion(-)

diff --git a/audit-server/audit-ingestor/pom.xml 
b/audit-server/audit-ingestor/pom.xml
index 6d4655765..b05178465 100644
--- a/audit-server/audit-ingestor/pom.xml
+++ b/audit-server/audit-ingestor/pom.xml
@@ -404,6 +404,12 @@
             <version>${junit.jupiter.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/rest/AuditREST.java
 
b/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/rest/AuditREST.java
index 2ae7d14e0..37c2fce39 100644
--- 
a/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/rest/AuditREST.java
+++ 
b/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/rest/AuditREST.java
@@ -188,7 +188,7 @@ public Response logAccessAudit(@QueryParam("serviceName") 
String serviceName, @Q
                     .entity(buildErrorResponse("Authentication required to 
send audit events"))
                     .build();
         } else if (!isAllowedServiceUser(serviceName, authenticatedUser)) {
-            LOG.error("Unauthorized user: user={} is authorized report audit 
logs for service={}. Rejecting audit request.", authenticatedUser, serviceName);
+            LOG.error("Unauthorized user: user={} is not authorized to report 
audit logs for service={}. Rejecting audit request.", authenticatedUser, 
serviceName);
 
             ret = Response.status(Response.Status.FORBIDDEN)
                     .entity(buildErrorResponse("User is not authorized to send 
audit events"))
diff --git 
a/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/security/AuditHeaderPreAuthFilter.java
 
b/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/security/AuditHeaderPreAuthFilter.java
new file mode 100644
index 000000000..d414abfe3
--- /dev/null
+++ 
b/audit-server/audit-ingestor/src/main/java/org/apache/ranger/audit/security/AuditHeaderPreAuthFilter.java
@@ -0,0 +1,142 @@
+/*
+ * 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.audit.security;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.audit.server.AuditServerConfig;
+import org.apache.ranger.audit.server.AuditServerConstants;
+import org.apache.ranger.plugin.util.SpiffeIdUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import 
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+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.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Authenticates audit REST requests using identity headers set by a trusted 
proxy. The resolved
+ * principal is still subject to the per-service allowed users check in the 
audit REST API.
+ */
+public class AuditHeaderPreAuthFilter extends GenericFilterBean {
+    private static final Logger LOG = 
LoggerFactory.getLogger(AuditHeaderPreAuthFilter.class);
+
+    public static final String PROP_HEADER_AUTH_ENABLED  = 
AuditServerConstants.PROP_PREFIX_AUDIT_SERVER + "authn.header.enabled";
+    public static final String PROP_USERNAME_HEADER_NAME = 
AuditServerConstants.PROP_PREFIX_AUDIT_SERVER + "authn.header.username";
+    public static final String PROP_SPIFFE_HEADER_NAME   = 
AuditServerConstants.PROP_PREFIX_AUDIT_SERVER + "authn.header.spiffe";
+
+    private static final String DEFAULT_AUDIT_ROLE = "ROLE_USER";
+
+    private boolean      headerAuthEnabled;
+    private String       userNameHeaderName;
+    private List<String> spiffeHeaderNames;
+
+    @PostConstruct
+    protected void initialize() {
+        AuditServerConfig auditConfig = AuditServerConfig.getInstance();
+
+        headerAuthEnabled = auditConfig.getBoolean(PROP_HEADER_AUTH_ENABLED, 
false);
+
+        if (headerAuthEnabled) {
+            userNameHeaderName = 
StringUtils.trimToNull(auditConfig.get(PROP_USERNAME_HEADER_NAME));
+            spiffeHeaderNames  = 
SpiffeIdUtil.parseHeaderNames(auditConfig.get(PROP_SPIFFE_HEADER_NAME));
+
+            if (userNameHeaderName == null && spiffeHeaderNames.isEmpty()) {
+                LOG.warn("Disabling header-based authentication, as neither {} 
nor {} is set", PROP_USERNAME_HEADER_NAME, PROP_SPIFFE_HEADER_NAME);
+
+                headerAuthEnabled = false;
+            } else {
+                LOG.info("Header-based authentication is enabled: 
usernameHeader={}, spiffeHeaders={}", userNameHeaderName, spiffeHeaderNames);
+            }
+        }
+    }
+
+    @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()) {
+                HttpServletRequest httpRequest = (HttpServletRequest) request;
+                String             username    = resolvePrincipal(httpRequest);
+
+                if (username != null) {
+                    List<GrantedAuthority>              grantedAuths = 
Collections.singletonList(new SimpleGrantedAuthority(DEFAULT_AUDIT_ROLE));
+                    UserDetails                         principal    = new 
User(username, "", grantedAuths);
+                    UsernamePasswordAuthenticationToken authToken    = new 
UsernamePasswordAuthenticationToken(principal, "", grantedAuths);
+
+                    authToken.setDetails(new 
WebAuthenticationDetails(httpRequest));
+
+                    
SecurityContextHolder.getContext().setAuthentication(authToken);
+
+                    LOG.debug("Authenticated request using trusted headers for 
user={}", username);
+                } else {
+                    LOG.debug("No trusted identity header found in the 
request!");
+                }
+            }
+        } else {
+            LOG.debug("Header-based authentication is disabled!");
+        }
+
+        chain.doFilter(request, response);
+    }
+
+    /**
+     * Resolves the principal from trusted headers. The username header (user 
identity) takes
+     * precedence; when it is absent, the SPIFFE header (service identity) is 
used and the
+     * full SPIFFE ID becomes the principal (SPIFFE IDs are used as usernames 
in Ranger).
+     */
+    private String resolvePrincipal(HttpServletRequest httpRequest) {
+        String ret = userNameHeaderName != null ? 
StringUtils.trimToNull(httpRequest.getHeader(userNameHeaderName)) : null;
+
+        if (ret == null) {
+            for (String spiffeHeaderName : spiffeHeaderNames) {
+                String spiffeId = 
StringUtils.trimToNull(httpRequest.getHeader(spiffeHeaderName));
+
+                if (SpiffeIdUtil.isValidSpiffeId(spiffeId)) {
+                    LOG.debug("Resolved SPIFFE ID '{}' from header '{}'", 
spiffeId, spiffeHeaderName);
+
+                    ret = spiffeId;
+
+                    break;
+                } else if (spiffeId != null) {
+                    LOG.warn("SPIFFE header '{}' value is not a well-formed 
SPIFFE ID", spiffeHeaderName);
+                }
+            }
+        }
+
+        return ret;
+    }
+}
diff --git 
a/audit-server/audit-ingestor/src/main/resources/conf/ranger-audit-ingestor-site.xml
 
b/audit-server/audit-ingestor/src/main/resources/conf/ranger-audit-ingestor-site.xml
index f72cce1a5..a0acadfe0 100644
--- 
a/audit-server/audit-ingestor/src/main/resources/conf/ranger-audit-ingestor-site.xml
+++ 
b/audit-server/audit-ingestor/src/main/resources/conf/ranger-audit-ingestor-site.xml
@@ -182,6 +182,29 @@
         <description>Expected audiences for JWT validation 
(comma-separated)</description>
     </property>
 
+    <!-- Trusted Header Auth Configs -->
+    <property>
+        <name>ranger.audit.ingestor.authn.header.enabled</name>
+        <value>false</value>
+        <description>
+            Enable authentication using identity headers set by a trusted 
proxy (e.g. service mesh or ingress gateway).
+            Enable only when all requests reach the audit ingestor through 
that proxy, and the proxy strips these headers from client requests.
+            The authenticated user must be listed in 
ranger.audit.ingestor.service.&lt;serviceName&gt;.allowed.users to post audits.
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.audit.ingestor.authn.header.username</name>
+        <value></value>
+        <description>Name of the HTTP header (e.g. X-Forwarded-User) carrying 
the authenticated username. Takes precedence over the SPIFFE 
header(s).</description>
+    </property>
+
+    <property>
+        <name>ranger.audit.ingestor.authn.header.spiffe</name>
+        <value></value>
+        <description>Comma-separated list of HTTP header name(s) carrying a 
SPIFFE ID (e.g. spiffe://cluster/ns/&lt;ns&gt;/sa/&lt;service-account&gt;). A 
single header name is also valid. The full SPIFFE ID is used as the 
authenticated principal. When multiple headers are configured, the first one 
carrying a well-formed SPIFFE ID is used. Consulted only when the username 
header is absent.</description>
+    </property>
+
     <property>
         <name>ranger.audit.ingestor.service.dev_hdfs.allowed.users</name>
         <value>hdfs</value>
diff --git 
a/audit-server/audit-ingestor/src/main/webapp/WEB-INF/security-applicationContext.xml
 
b/audit-server/audit-ingestor/src/main/webapp/WEB-INF/security-applicationContext.xml
index 30a9fa5e2..423390d39 100644
--- 
a/audit-server/audit-ingestor/src/main/webapp/WEB-INF/security-applicationContext.xml
+++ 
b/audit-server/audit-ingestor/src/main/webapp/WEB-INF/security-applicationContext.xml
@@ -46,6 +46,7 @@ 
http://www.springframework.org/schema/util/spring-util-4.3.xsd";>
                <intercept-url pattern="/api/audit/status" 
access="permitAll()"/>
                <intercept-url pattern="/api/audit/**" 
access="isAuthenticated()"/>
                <security:access-denied-handler error-page="/index.jsp"/>
+        <custom-filter ref="auditHeaderPreAuthFilter" 
position="PRE_AUTH_FILTER" />
                <custom-filter ref="auditJwtAuthFilter" 
after="SERVLET_API_SUPPORT_FILTER" />
                <custom-filter ref="auditDelegationTokenFilter" 
before="ANONYMOUS_FILTER" />
        </security:http>
@@ -54,6 +55,8 @@ 
http://www.springframework.org/schema/util/spring-util-4.3.xsd";>
                <beans:constructor-arg value="/index.jsp"/>
        </beans:bean>
 
+    <beans:bean id="auditHeaderPreAuthFilter" 
class="org.apache.ranger.audit.security.AuditHeaderPreAuthFilter"/>
+
        <beans:bean id="auditJwtAuthFilter" 
class="org.apache.ranger.audit.security.AuditJwtAuthFilter"/>
 
        <beans:bean id="auditDelegationTokenFilter" 
class="org.apache.ranger.audit.security.AuditDelegationTokenFilter"/>
diff --git 
a/audit-server/audit-ingestor/src/test/java/org/apache/ranger/audit/security/AuditHeaderPreAuthFilterTest.java
 
b/audit-server/audit-ingestor/src/test/java/org/apache/ranger/audit/security/AuditHeaderPreAuthFilterTest.java
new file mode 100644
index 000000000..0e4598f3c
--- /dev/null
+++ 
b/audit-server/audit-ingestor/src/test/java/org/apache/ranger/audit/security/AuditHeaderPreAuthFilterTest.java
@@ -0,0 +1,257 @@
+/*
+ * 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.audit.security;
+
+import org.apache.ranger.audit.server.AuditServerConfig;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import 
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.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;
+
+class AuditHeaderPreAuthFilterTest {
+    private static final String USERNAME_HEADER = "X-Forwarded-User";
+    private static final String SPIFFE_HEADER   = "X-Spiffe-Id";
+
+    private HttpServletRequest  request;
+    private HttpServletResponse response;
+    private FilterChain         chain;
+
+    @BeforeEach
+    void setUp() {
+        SecurityContextHolder.clearContext();
+
+        request  = mock(HttpServletRequest.class);
+        response = mock(HttpServletResponse.class);
+        chain    = mock(FilterChain.class);
+    }
+
+    @AfterEach
+    void tearDown() {
+        SecurityContextHolder.clearContext();
+
+        
AuditServerConfig.getInstance().unset(AuditHeaderPreAuthFilter.PROP_HEADER_AUTH_ENABLED);
+        
AuditServerConfig.getInstance().unset(AuditHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME);
+        
AuditServerConfig.getInstance().unset(AuditHeaderPreAuthFilter.PROP_SPIFFE_HEADER_NAME);
+    }
+
+    @Test
+    void testDoFilter_disabled_passesThrough() throws Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("false", USERNAME_HEADER, 
SPIFFE_HEADER);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(request, never()).getHeader(anyString());
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    void testDoFilter_enabledWithoutHeaderNames_isDisabled() throws Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("true", " ", " ");
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(request, never()).getHeader(anyString());
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    void testDoFilter_enabled_missingUsername_passesThrough() throws Exception 
{
+        AuditHeaderPreAuthFilter filter = newFilter("true", USERNAME_HEADER, 
null);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(request).getHeader(USERNAME_HEADER);
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    void testDoFilter_enabled_blankUsername_passesThrough() throws Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("true", USERNAME_HEADER, 
null);
+
+        when(request.getHeader(USERNAME_HEADER)).thenReturn("   ");
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    void testDoFilter_enabled_withUsername_setsAuthentication() throws 
Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("true", USERNAME_HEADER, 
null);
+
+        when(request.getHeader(USERNAME_HEADER)).thenReturn(" hdfs ");
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        assertAuthenticatedAs("hdfs");
+    }
+
+    @Test
+    void testDoFilter_enabled_withSpiffeHeader_setsSpiffeIdAuthentication() 
throws Exception {
+        AuditHeaderPreAuthFilter filter   = newFilter("true", USERNAME_HEADER, 
SPIFFE_HEADER);
+        String                   spiffeId = 
"spiffe://prod-cluster.k8s.example.com/ns/hadoop/sa/hdfs";
+
+        when(request.getHeader(SPIFFE_HEADER)).thenReturn(spiffeId);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        assertAuthenticatedAs(spiffeId);
+    }
+
+    @Test
+    void testDoFilter_enabled_spiffeOnlyConfig_setsSpiffeIdAuthentication() 
throws Exception {
+        AuditHeaderPreAuthFilter filter   = newFilter("true", null, 
SPIFFE_HEADER);
+        String                   spiffeId = 
"spiffe://example.org/workload/hive";
+
+        when(request.getHeader(SPIFFE_HEADER)).thenReturn(spiffeId);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(request, never()).getHeader(USERNAME_HEADER);
+        assertAuthenticatedAs(spiffeId);
+    }
+
+    @Test
+    void testDoFilter_enabled_usernameTakesPrecedenceOverSpiffe() throws 
Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("true", USERNAME_HEADER, 
SPIFFE_HEADER);
+
+        when(request.getHeader(USERNAME_HEADER)).thenReturn("hdfs");
+
+        filter.doFilter(request, response, chain);
+
+        verify(request, never()).getHeader(SPIFFE_HEADER);
+        assertAuthenticatedAs("hdfs");
+    }
+
+    @Test
+    void testDoFilter_enabled_multipleSpiffeHeaders_usesFirstValid() throws 
Exception {
+        AuditHeaderPreAuthFilter filter   = newFilter("true", null, 
SPIFFE_HEADER + ", x-awc-upstream-workload-id");
+        String                   spiffeId = 
"spiffe://my-cluster/ns/service-namespace/sa/service-sa";
+
+        when(request.getHeader(SPIFFE_HEADER)).thenReturn("not-a-spiffe-id");
+        
when(request.getHeader("x-awc-upstream-workload-id")).thenReturn(spiffeId);
+
+        filter.doFilter(request, response, chain);
+
+        assertAuthenticatedAs(spiffeId);
+    }
+
+    @Test
+    void testDoFilter_enabled_malformedSpiffeHeader_passesThrough() throws 
Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("true", USERNAME_HEADER, 
SPIFFE_HEADER);
+
+        // whitespace is not an allowed SPIFFE ID character
+        
when(request.getHeader(SPIFFE_HEADER)).thenReturn("spiffe://my-cluster/ns/prod/sa/service
 sa");
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        assertNull(SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    void 
testDoFilter_enabled_existingAuthenticatedContext_doesNotOverrideAuthentication()
 throws Exception {
+        AuditHeaderPreAuthFilter            filter       = newFilter("true", 
USERNAME_HEADER, SPIFFE_HEADER);
+        UsernamePasswordAuthenticationToken existingAuth = new 
UsernamePasswordAuthenticationToken("kerberos-user", "", 
Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")));
+
+        SecurityContextHolder.getContext().setAuthentication(existingAuth);
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        verify(request, never()).getHeader(anyString());
+        assertSame(existingAuth, 
SecurityContextHolder.getContext().getAuthentication());
+    }
+
+    @Test
+    void 
testDoFilter_enabled_existingUnauthenticatedContext_setsAuthentication() throws 
Exception {
+        AuditHeaderPreAuthFilter filter = newFilter("true", USERNAME_HEADER, 
null);
+
+        SecurityContextHolder.getContext().setAuthentication(new 
UsernamePasswordAuthenticationToken("unverified-user", ""));
+
+        when(request.getHeader(USERNAME_HEADER)).thenReturn("hive");
+
+        filter.doFilter(request, response, chain);
+
+        verify(chain).doFilter(request, response);
+        assertAuthenticatedAs("hive");
+    }
+
+    private static void assertAuthenticatedAs(String expectedUser) {
+        Authentication auth = 
SecurityContextHolder.getContext().getAuthentication();
+
+        assertNotNull(auth);
+        assertTrue(auth.isAuthenticated());
+        assertEquals(expectedUser, auth.getName());
+        assertEquals(1, auth.getAuthorities().size());
+        assertTrue(auth.getAuthorities().stream().anyMatch(a -> 
"ROLE_USER".equals(a.getAuthority())));
+    }
+
+    private static AuditHeaderPreAuthFilter newFilter(String enabled, String 
userNameHeaderName, String spiffeHeaderNames) {
+        AuditServerConfig config = AuditServerConfig.getInstance();
+
+        config.set(AuditHeaderPreAuthFilter.PROP_HEADER_AUTH_ENABLED, enabled);
+
+        if (userNameHeaderName != null) {
+            config.set(AuditHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME, 
userNameHeaderName);
+        } else {
+            config.unset(AuditHeaderPreAuthFilter.PROP_USERNAME_HEADER_NAME);
+        }
+
+        if (spiffeHeaderNames != null) {
+            config.set(AuditHeaderPreAuthFilter.PROP_SPIFFE_HEADER_NAME, 
spiffeHeaderNames);
+        } else {
+            config.unset(AuditHeaderPreAuthFilter.PROP_SPIFFE_HEADER_NAME);
+        }
+
+        AuditHeaderPreAuthFilter ret = new AuditHeaderPreAuthFilter();
+
+        ret.initialize();
+
+        return ret;
+    }
+}

Reply via email to