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

smolnar82 pushed a commit to branch knox_idf
in repository https://gitbox.apache.org/repos/asf/knox.git

commit 0aeacf732b8f788b6cea28590bbbc1c2a7d3c20a
Author: Sandor Molnar <[email protected]>
AuthorDate: Fri Jun 19 09:20:14 2026 +0200

    KNOX-3353: Eliminate K8sPreAuthFederationFilter and consolidate logic  in 
ServiceAccountValidator (#1269)
    
    * KNOX-3353: Refactor PreAuthService to use lazy, instance-based validator 
discovery
    
    This change replaces the static initializer in PreAuthService with lazy, 
instance-based loading to ensure ServiceLoader respects the Thread Context 
ClassLoader of the specific filter instance. This resolves discovery issues 
where providers in separate JARs (like the K8s validator) were missed due to 
premature static initialization.
    
    (cherry picked from commit 01fbedc790f3b35a7070f61eda84af396c9e15cf)
---
 .../preauth/k8s/K8sPreAuthFederationFilter.java    | 119 ----------
 .../preauth/k8s/K8sServiceAccountResolver.java     |   2 +-
 .../preauth/k8s/ServiceAccountValidator.java       |  65 +++++-
 .../preauth/k8s/deploy/K8sPreAuthContributor.java  |  66 ------
 ...ox.gateway.deploy.ProviderDeploymentContributor |  19 --
 .../k8s/K8sPreAuthFederationFilterTest.java        | 252 ---------------------
 .../preauth/k8s/ServiceAccountValidatorTest.java   |  34 +--
 .../filter/AbstractPreAuthFederationFilter.java    |  16 +-
 .../gateway/preauth/filter/DefaultValidator.java   |  10 +
 .../knox/gateway/preauth/filter/IPValidator.java   |  10 +
 .../preauth/filter/PreAuthFederationFilter.java    |   6 +-
 .../gateway/preauth/filter/PreAuthService.java     |  41 ++--
 .../gateway/preauth/filter/PreAuthValidator.java   |   5 +
 .../HeaderPreAuthFederationFilterTest.java         |  29 ++-
 .../provider/federation/PreAuthServiceTest.java    |  32 ++-
 15 files changed, 184 insertions(+), 522 deletions(-)

diff --git 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sPreAuthFederationFilter.java
 
b/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sPreAuthFederationFilter.java
deleted file mode 100644
index 975536d65..000000000
--- 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sPreAuthFederationFilter.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.knox.gateway.preauth.k8s;
-
-import org.apache.knox.gateway.preauth.filter.AbstractPreAuthFederationFilter;
-
-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.security.Principal;
-import java.time.Duration;
-import java.util.Set;
-
-public class K8sPreAuthFederationFilter extends 
AbstractPreAuthFederationFilter {
-    private String userHeader = ServiceAccountValidator.USER_HEADER_DEFAULT;
-    private K8sServiceAccountResolver resolver;
-
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-        super.init(filterConfig);
-        String configured = 
filterConfig.getInitParameter(ServiceAccountValidator.USER_HEADER_PARAM);
-        if (configured != null && !configured.isEmpty()) {
-            userHeader = configured;
-        }
-
-        long ttlSeconds = longParam(filterConfig,
-                ServiceAccountValidator.CACHE_TTL_SECONDS_PARAM,
-                ServiceAccountValidator.CACHE_TTL_SECONDS_DEFAULT);
-        long maxSize = longParam(filterConfig,
-                ServiceAccountValidator.CACHE_MAX_SIZE_PARAM,
-                ServiceAccountValidator.CACHE_MAX_SIZE_DEFAULT);
-        if (ttlSeconds <= 0) {
-            throw new 
ServletException(ServiceAccountValidator.CACHE_TTL_SECONDS_PARAM
-                    + " must be > 0 (got " + ttlSeconds + ")");
-        }
-        if (maxSize <= 0) {
-            throw new 
ServletException(ServiceAccountValidator.CACHE_MAX_SIZE_PARAM
-                    + " must be > 0 (got " + maxSize + ")");
-        }
-
-        if (resolver == null) {
-            resolver = createResolver(Duration.ofSeconds(ttlSeconds), maxSize);
-        }
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain)
-            throws IOException, ServletException {
-        request.setAttribute(ServiceAccountValidator.RESOLVER_REQUEST_ATTR, 
resolver);
-        try {
-            super.doFilter(request, response, chain);
-        } finally {
-            
request.removeAttribute(ServiceAccountValidator.RESOLVER_REQUEST_ATTR);
-        }
-    }
-
-    @Override
-    public void destroy() {
-        if (resolver != null) {
-            resolver.close();
-            resolver = null;
-        }
-        super.destroy();
-    }
-
-    @Override
-    protected String getPrimaryPrincipal(HttpServletRequest httpRequest) {
-        return httpRequest.getHeader(userHeader);
-    }
-
-    @Override
-    protected void addGroupPrincipals(HttpServletRequest request, 
Set<Principal> principals) {
-    }
-
-    @Override
-    protected String getValidationFailureMessage() {
-        return "Kubernetes pre-authentication failed: SPIFFE/ServiceAccount 
validation rejected the request.";
-    }
-
-    @Override
-    protected String getMissingPrincipalMessage() {
-        return "Missing required user header for Kubernetes 
pre-authentication.";
-    }
-
-    protected K8sServiceAccountResolver createResolver(Duration ttl, long 
maxSize) {
-        return new K8sServiceAccountResolver(ttl, maxSize);
-    }
-
-    private static long longParam(FilterConfig cfg, String name, long 
defaultValue) {
-        final String v = cfg.getInitParameter(name);
-        if (v == null || v.isEmpty()) {
-            return defaultValue;
-        }
-        try {
-            return Long.parseLong(v.trim());
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-}
diff --git 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sServiceAccountResolver.java
 
b/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sServiceAccountResolver.java
index 6218f1474..0dc133014 100644
--- 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sServiceAccountResolver.java
+++ 
b/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/K8sServiceAccountResolver.java
@@ -54,7 +54,7 @@ public class K8sServiceAccountResolver implements Closeable {
         .build();
   }
 
-  public Optional<String> getAnnotation(String namespace, String 
serviceAccount, String annotationKey) {
+  Optional<String> getAnnotation(String namespace, String serviceAccount, 
String annotationKey) {
     final Key key = new Key(namespace, serviceAccount);
     final Optional<Map<String, String>> annotations;
     try {
diff --git 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidator.java
 
b/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidator.java
index db9c8a6e6..0e353173a 100644
--- 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidator.java
+++ 
b/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidator.java
@@ -22,33 +22,65 @@ import 
org.apache.knox.gateway.preauth.filter.PreAuthValidationException;
 import org.apache.knox.gateway.preauth.filter.PreAuthValidator;
 
 import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
+import java.time.Duration;
 import java.util.Optional;
 
 public class ServiceAccountValidator implements PreAuthValidator {
     private static final K8sPreAuthMessages LOG = 
MessagesFactory.get(K8sPreAuthMessages.class);
 
-    public static final String VALIDATION_METHOD_VALUE = 
"preauth.spiffe.k8s.validation";
-    public static final String SPIFFE_HEADER_PARAM = "preauth.spiffe.header";
+    public static final String VALIDATION_METHOD_VALUE = 
"preauth.k8s.service.account.validation";
+    private static final String PARAM_PREFIX = "preauth.k8s.sa.";
+    public static final String SPIFFE_HEADER_PARAM = PARAM_PREFIX + 
"spiffe.header";
     public static final String SPIFFE_HEADER_DEFAULT = "x-spiffe-id";
-    public static final String USER_HEADER_PARAM = "preauth.custom.header";
+    public static final String USER_HEADER_PARAM = PARAM_PREFIX + 
"custom.header";
     public static final String USER_HEADER_DEFAULT = "x-knoxidf-obo.username";
-    public static final String USER_ANNOTATION_PARAM = 
"preauth.k8s.user.annotation";
+    public static final String USER_ANNOTATION_PARAM = PARAM_PREFIX + 
"user.annotation";
     public static final String USER_ANNOTATION_DEFAULT = 
"knox.apache.org/owner-username";
-    public static final String CACHE_TTL_SECONDS_PARAM = 
"preauth.k8s.cache.ttl.seconds";
+    public static final String CACHE_TTL_SECONDS_PARAM = PARAM_PREFIX + 
"cache.ttl.seconds";
     public static final long CACHE_TTL_SECONDS_DEFAULT = 60L;
-    public static final String CACHE_MAX_SIZE_PARAM = 
"preauth.k8s.cache.max.size";
+    public static final String CACHE_MAX_SIZE_PARAM = PARAM_PREFIX + 
"cache.max.size";
     public static final long CACHE_MAX_SIZE_DEFAULT = 1000L;
-    static final String RESOLVER_REQUEST_ATTR = 
"org.apache.knox.gateway.preauth.k8s.resolver";
+
+    private K8sServiceAccountResolver resolver;
 
     public ServiceAccountValidator() {
     }
 
+    @Override
+    public void init(FilterConfig filterConfig) throws Exception {
+        final long ttlSeconds = getAndVerifyParam(filterConfig, 
CACHE_TTL_SECONDS_PARAM, CACHE_TTL_SECONDS_DEFAULT);
+        final long maxSize =  getAndVerifyParam(filterConfig, 
CACHE_MAX_SIZE_PARAM, CACHE_MAX_SIZE_DEFAULT);
+
+        if (resolver == null) {
+            resolver = createResolver(Duration.ofSeconds(ttlSeconds), maxSize);
+        }
+    }
+
+    protected K8sServiceAccountResolver createResolver(Duration duration, long 
maxSize) {
+        return new K8sServiceAccountResolver(duration, maxSize);
+    }
+
+    private long getAndVerifyParam(final FilterConfig filterConfig, final 
String paramName, final long defaultValue) throws Exception {
+        final long paramValue = longParam(filterConfig, paramName, 
defaultValue);
+        if (paramValue <= 0) {
+            throw new ServletException(paramName + " must be > 0 (got " + 
paramValue + ")");
+        }
+        return paramValue;
+    }
+
+    @Override
+    public void destroy() {
+        if (resolver != null) {
+            resolver.close();
+            resolver = null;
+        }
+    }
+
     @Override
     public boolean validate(HttpServletRequest httpRequest, FilterConfig 
filterConfig)
             throws PreAuthValidationException {
-        final K8sServiceAccountResolver resolver =
-                (K8sServiceAccountResolver) 
httpRequest.getAttribute(RESOLVER_REQUEST_ATTR);
         final String spiffeHeader = paramOrDefault(filterConfig, 
SPIFFE_HEADER_PARAM, SPIFFE_HEADER_DEFAULT);
         final String userHeader = paramOrDefault(filterConfig, 
USER_HEADER_PARAM, USER_HEADER_DEFAULT);
         final String annotationKey = paramOrDefault(filterConfig, 
USER_ANNOTATION_PARAM, USER_ANNOTATION_DEFAULT);
@@ -72,8 +104,7 @@ public class ServiceAccountValidator implements 
PreAuthValidator {
         }
         final SpiffeId spiffe = parsed.get();
 
-        final Optional<String> ownerFromSa = resolver
-                .getAnnotation(spiffe.namespace(), spiffe.serviceAccount(), 
annotationKey);
+        final Optional<String> ownerFromSa = 
resolver.getAnnotation(spiffe.namespace(), spiffe.serviceAccount(), 
annotationKey);
         if (ownerFromSa.isEmpty()) {
             LOG.missingServiceAccountAnnotation(spiffe.namespace(), 
spiffe.serviceAccount(),
                     annotationKey, assertedUser, spiffeRaw);
@@ -97,4 +128,16 @@ public class ServiceAccountValidator implements 
PreAuthValidator {
         final String v = cfg.getInitParameter(name);
         return (v == null || v.isEmpty()) ? defaultValue : v;
     }
+
+    private long longParam(FilterConfig cfg, String name, long defaultValue) {
+        final String v = cfg.getInitParameter(name);
+        if (v == null || v.isEmpty()) {
+            return defaultValue;
+        }
+        try {
+            return Long.parseLong(v.trim());
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
 }
diff --git 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/deploy/K8sPreAuthContributor.java
 
b/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/deploy/K8sPreAuthContributor.java
deleted file mode 100644
index c88ec7b35..000000000
--- 
a/gateway-provider-security-k8s/src/main/java/org/apache/knox/gateway/preauth/k8s/deploy/K8sPreAuthContributor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.knox.gateway.preauth.k8s.deploy;
-
-import org.apache.knox.gateway.deploy.DeploymentContext;
-import org.apache.knox.gateway.deploy.ProviderDeploymentContributorBase;
-import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
-import org.apache.knox.gateway.descriptor.ResourceDescriptor;
-import org.apache.knox.gateway.preauth.filter.PreAuthService;
-import org.apache.knox.gateway.preauth.k8s.ServiceAccountValidator;
-import org.apache.knox.gateway.topology.Provider;
-import org.apache.knox.gateway.topology.Service;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class K8sPreAuthContributor extends ProviderDeploymentContributorBase {
-    private static final String ROLE = "federation";
-    private static final String NAME = "K8sPreAuth";
-    private static final String FILTER_CLASSNAME =
-            "org.apache.knox.gateway.preauth.k8s.K8sPreAuthFederationFilter";
-
-    @Override
-    public String getRole() {
-        return ROLE;
-    }
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public void contributeFilter(DeploymentContext context, Provider provider, 
Service service,
-                                 ResourceDescriptor resource, 
List<FilterParamDescriptor> params) {
-        if (params == null) {
-            params = new ArrayList<>();
-        }
-        Map<String, String> providerParams = provider.getParams();
-        for(Entry<String, String> entry : providerParams.entrySet()) {
-            params.add( resource.createFilterParam().name( 
entry.getKey().toLowerCase(Locale.ROOT) ).value( entry.getValue() ) );
-        }
-        params.add(resource.createFilterParam()
-                .name(PreAuthService.VALIDATION_METHOD_PARAM)
-                .value(ServiceAccountValidator.VALIDATION_METHOD_VALUE));
-        resource.addFilter().name( getName() ).role( getRole() ).impl( 
FILTER_CLASSNAME ).params( params );
-    }
-}
diff --git 
a/gateway-provider-security-k8s/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
 
b/gateway-provider-security-k8s/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
deleted file mode 100644
index 079f3044e..000000000
--- 
a/gateway-provider-security-k8s/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
+++ /dev/null
@@ -1,19 +0,0 @@
-##########################################################################
-# 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.
-##########################################################################
-
-org.apache.knox.gateway.preauth.k8s.deploy.K8sPreAuthContributor
diff --git 
a/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/K8sPreAuthFederationFilterTest.java
 
b/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/K8sPreAuthFederationFilterTest.java
deleted file mode 100644
index 9c2129a13..000000000
--- 
a/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/K8sPreAuthFederationFilterTest.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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.knox.gateway.preauth.k8s;
-
-import org.apache.knox.gateway.preauth.filter.PreAuthService;
-import org.apache.knox.gateway.preauth.filter.PreAuthValidator;
-import org.easymock.EasyMock;
-import org.junit.Test;
-
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.time.Duration;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class K8sPreAuthFederationFilterTest {
-
-    @Test
-    public void testInitResolvesK8sValidatorFromContributorInjectedParam() 
throws ServletException {
-        TestableFilter filter = new TestableFilter();
-        FilterConfig cfg = niceCfg();
-        filter.init(cfg);
-
-        List<PreAuthValidator> validators = filter.getValidators();
-        assertEquals(1, validators.size());
-        assertEquals(ServiceAccountValidator.VALIDATION_METHOD_VALUE, 
validators.get(0).getName());
-        assertNotNull("init must construct a resolver", 
filter.lastCreatedResolver);
-    }
-
-    @Test
-    public void testInitRejectsNonPositiveTtl() {
-        TestableFilter filter = new TestableFilter();
-        FilterConfig cfg = 
niceCfg(ServiceAccountValidator.CACHE_TTL_SECONDS_PARAM, "0");
-        try {
-            filter.init(cfg);
-            fail("expected ServletException for ttl=0");
-        } catch (ServletException expected) {
-            assertTrue(expected.getMessage().contains(
-                    ServiceAccountValidator.CACHE_TTL_SECONDS_PARAM));
-        }
-        assertNull("resolver must not be created on bad config", 
filter.lastCreatedResolver);
-    }
-
-    @Test
-    public void testInitRejectsNegativeMaxSize() {
-        TestableFilter filter = new TestableFilter();
-        FilterConfig cfg = 
niceCfg(ServiceAccountValidator.CACHE_MAX_SIZE_PARAM, "-1");
-        try {
-            filter.init(cfg);
-            fail("expected ServletException for maxSize=-1");
-        } catch (ServletException expected) {
-            assertTrue(expected.getMessage().contains(
-                    ServiceAccountValidator.CACHE_MAX_SIZE_PARAM));
-        }
-        assertNull("resolver must not be created on bad config", 
filter.lastCreatedResolver);
-    }
-
-    @Test
-    public void testGetPrimaryPrincipalUsesDefaultUserHeaderWhenUnset() throws 
ServletException {
-        TestableFilter filter = new TestableFilter();
-        filter.init(niceCfg());
-
-        HttpServletRequest req = 
EasyMock.createNiceMock(HttpServletRequest.class);
-        
EasyMock.expect(req.getHeader(ServiceAccountValidator.USER_HEADER_DEFAULT))
-                .andReturn("alice").anyTimes();
-        EasyMock.replay(req);
-
-        assertEquals("alice", filter.getPrimaryPrincipal(req));
-    }
-
-    @Test
-    public void testGetPrimaryPrincipalHonorsCustomUserHeader() throws 
ServletException {
-        TestableFilter filter = new TestableFilter();
-        filter.init(niceCfg(ServiceAccountValidator.USER_HEADER_PARAM, 
"X-My-User"));
-
-        HttpServletRequest req = 
EasyMock.createNiceMock(HttpServletRequest.class);
-        
EasyMock.expect(req.getHeader("X-My-User")).andReturn("bob").anyTimes();
-        EasyMock.replay(req);
-
-        assertEquals("bob", filter.getPrimaryPrincipal(req));
-    }
-
-    @Test
-    public void testEmptyCustomUserHeaderFallsBackToDefault() throws 
ServletException {
-        TestableFilter filter = new TestableFilter();
-        filter.init(niceCfg(ServiceAccountValidator.USER_HEADER_PARAM, ""));
-
-        HttpServletRequest req = 
EasyMock.createNiceMock(HttpServletRequest.class);
-        
EasyMock.expect(req.getHeader(ServiceAccountValidator.USER_HEADER_DEFAULT))
-                .andReturn("carol").anyTimes();
-        EasyMock.replay(req);
-
-        assertEquals("carol", filter.getPrimaryPrincipal(req));
-    }
-
-    @Test
-    public void testGetPrimaryPrincipalReturnsNullWhenHeaderAbsent() throws 
ServletException {
-        TestableFilter filter = new TestableFilter();
-        filter.init(niceCfg());
-
-        HttpServletRequest req = 
EasyMock.createNiceMock(HttpServletRequest.class);
-        
EasyMock.expect(req.getHeader(ServiceAccountValidator.USER_HEADER_DEFAULT))
-                .andReturn(null).anyTimes();
-        EasyMock.replay(req);
-
-        assertNull(filter.getPrimaryPrincipal(req));
-    }
-
-    @Test
-    public void testDoFilterBindsResolverAttributeAndRemovesItAfterChain() 
throws Exception {
-        TestableFilter filter = new TestableFilter();
-        filter.init(niceCfg());
-
-        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
-        
req.setAttribute(EasyMock.eq(ServiceAccountValidator.RESOLVER_REQUEST_ATTR),
-                EasyMock.same(filter.lastCreatedResolver));
-        EasyMock.expectLastCall();
-        
EasyMock.expect(req.getHeader(ServiceAccountValidator.USER_HEADER_DEFAULT))
-                .andReturn(null);
-        req.removeAttribute(ServiceAccountValidator.RESOLVER_REQUEST_ATTR);
-        EasyMock.expectLastCall();
-        EasyMock.replay(req);
-
-        HttpServletResponse resp = 
EasyMock.createMock(HttpServletResponse.class);
-        resp.sendError(EasyMock.eq(HttpServletResponse.SC_FORBIDDEN), 
EasyMock.anyString());
-        EasyMock.expectLastCall();
-        EasyMock.replay(resp);
-
-        FilterChain chain = EasyMock.createMock(FilterChain.class);
-        EasyMock.replay(chain);
-
-        filter.doFilter(req, resp, chain);
-
-        EasyMock.verify(req, resp, chain);
-    }
-
-    @Test
-    public void testDoFilterRemovesResolverAttributeEvenIfChainThrows() throws 
Exception {
-        TestableFilter filter = new TestableFilter();
-        filter.init(niceCfg());
-
-        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
-        
req.setAttribute(EasyMock.eq(ServiceAccountValidator.RESOLVER_REQUEST_ATTR),
-                EasyMock.same(filter.lastCreatedResolver));
-        EasyMock.expectLastCall();
-        
EasyMock.expect(req.getHeader(ServiceAccountValidator.USER_HEADER_DEFAULT))
-                .andThrow(new RuntimeException("boom"));
-        req.removeAttribute(ServiceAccountValidator.RESOLVER_REQUEST_ATTR);
-        EasyMock.expectLastCall();
-        EasyMock.replay(req);
-
-        HttpServletResponse resp = 
EasyMock.createMock(HttpServletResponse.class);
-        EasyMock.replay(resp);
-        FilterChain chain = EasyMock.createMock(FilterChain.class);
-        EasyMock.replay(chain);
-
-        try {
-            filter.doFilter(req, resp, chain);
-            fail("expected RuntimeException to propagate");
-        } catch (RuntimeException expected) {
-            assertEquals("boom", expected.getMessage());
-        }
-        EasyMock.verify(req, resp, chain);
-    }
-
-    @Test
-    public void testDestroyClosesResolverOnce() throws ServletException {
-        K8sServiceAccountResolver resolver = 
EasyMock.createMock(K8sServiceAccountResolver.class);
-        resolver.close();
-        EasyMock.expectLastCall().once();
-        EasyMock.replay(resolver);
-
-        TestableFilter filter = new TestableFilter(resolver);
-        filter.init(niceCfg());
-        assertSame(resolver, filter.lastCreatedResolver);
-
-        filter.destroy();
-        // Second destroy must not double-close.
-        filter.destroy();
-
-        EasyMock.verify(resolver);
-    }
-
-    @Test
-    public void testDestroyWithoutInitDoesNotThrow() {
-        K8sPreAuthFederationFilter filter = new K8sPreAuthFederationFilter();
-        filter.destroy();
-    }
-
-    private static FilterConfig niceCfg() {
-        FilterConfig cfg = EasyMock.createNiceMock(FilterConfig.class);
-        
EasyMock.expect(cfg.getInitParameter(PreAuthService.VALIDATION_METHOD_PARAM))
-                
.andReturn(ServiceAccountValidator.VALIDATION_METHOD_VALUE).anyTimes();
-        EasyMock.replay(cfg);
-        return cfg;
-    }
-
-    private static FilterConfig niceCfg(String paramName, String paramValue) {
-        FilterConfig cfg = EasyMock.createNiceMock(FilterConfig.class);
-        
EasyMock.expect(cfg.getInitParameter(PreAuthService.VALIDATION_METHOD_PARAM))
-                
.andReturn(ServiceAccountValidator.VALIDATION_METHOD_VALUE).anyTimes();
-        
EasyMock.expect(cfg.getInitParameter(paramName)).andReturn(paramValue).anyTimes();
-        EasyMock.replay(cfg);
-        return cfg;
-    }
-
-    private static final class TestableFilter extends 
K8sPreAuthFederationFilter {
-        private final K8sServiceAccountResolver fixed;
-        K8sServiceAccountResolver lastCreatedResolver;
-
-        TestableFilter() {
-            this(null);
-        }
-
-        TestableFilter(K8sServiceAccountResolver fixed) {
-            this.fixed = fixed;
-        }
-
-        @Override
-        protected K8sServiceAccountResolver createResolver(Duration ttl, long 
maxSize) {
-            K8sServiceAccountResolver r = fixed != null
-                    ? fixed
-                    : EasyMock.createNiceMock(K8sServiceAccountResolver.class);
-            lastCreatedResolver = r;
-            return r;
-        }
-    }
-}
diff --git 
a/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidatorTest.java
 
b/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidatorTest.java
index 3c23b22a8..d3b01195e 100644
--- 
a/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidatorTest.java
+++ 
b/gateway-provider-security-k8s/src/test/java/org/apache/knox/gateway/preauth/k8s/ServiceAccountValidatorTest.java
@@ -24,6 +24,7 @@ import org.junit.Test;
 
 import javax.servlet.FilterConfig;
 import javax.servlet.http.HttpServletRequest;
+import java.time.Duration;
 import java.util.Optional;
 
 import static org.junit.Assert.assertEquals;
@@ -40,9 +41,19 @@ public class ServiceAccountValidatorTest {
     private ServiceAccountValidator validator;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         resolver = EasyMock.createMock(K8sServiceAccountResolver.class);
-        validator = new ServiceAccountValidator();
+        validator = new ServiceAccountValidator() {
+            @Override
+            protected K8sServiceAccountResolver createResolver(Duration 
duration, long maxSize) {
+                return resolver;
+            }
+        };
+        final FilterConfig filterConfig = 
EasyMock.createMock(FilterConfig.class);
+        
EasyMock.expect(filterConfig.getInitParameter(ServiceAccountValidator.CACHE_TTL_SECONDS_PARAM)).andReturn("120").anyTimes();
+        
EasyMock.expect(filterConfig.getInitParameter(ServiceAccountValidator.CACHE_MAX_SIZE_PARAM)).andReturn("100").anyTimes();
+        EasyMock.replay(filterConfig);
+        validator.init(filterConfig);
     }
 
     @Test
@@ -55,7 +66,7 @@ public class ServiceAccountValidatorTest {
         EasyMock.expect(resolver.getAnnotation(NS, SA, 
ANNOTATION)).andReturn(Optional.of("bob"));
         EasyMock.replay(resolver);
 
-        assertTrue(validator.validate(request(SPIFFE, "bob", resolver), 
defaultConfig()));
+        assertTrue(validator.validate(request(SPIFFE, "bob"), 
defaultConfig()));
         EasyMock.verify(resolver);
     }
 
@@ -64,28 +75,28 @@ public class ServiceAccountValidatorTest {
         EasyMock.expect(resolver.getAnnotation(NS, SA, 
ANNOTATION)).andReturn(Optional.of("alice"));
         EasyMock.replay(resolver);
 
-        assertFalse(validator.validate(request(SPIFFE, "bob", resolver), 
defaultConfig()));
+        assertFalse(validator.validate(request(SPIFFE, "bob"), 
defaultConfig()));
         EasyMock.verify(resolver);
     }
 
     @Test
     public void testRejectWhenSpiffeHeaderMissing() throws 
PreAuthValidationException {
         EasyMock.replay(resolver);
-        assertFalse(validator.validate(request(null, "bob", resolver), 
defaultConfig()));
+        assertFalse(validator.validate(request(null, "bob"), defaultConfig()));
         EasyMock.verify(resolver);
     }
 
     @Test
     public void testRejectWhenUserHeaderMissing() throws 
PreAuthValidationException {
         EasyMock.replay(resolver);
-        assertFalse(validator.validate(request(SPIFFE, null, resolver), 
defaultConfig()));
+        assertFalse(validator.validate(request(SPIFFE, null), 
defaultConfig()));
         EasyMock.verify(resolver);
     }
 
     @Test
     public void testRejectWhenSpiffeUnparseable() throws 
PreAuthValidationException {
         EasyMock.replay(resolver);
-        assertFalse(validator.validate(request("not-a-spiffe-id", "bob", 
resolver), defaultConfig()));
+        assertFalse(validator.validate(request("not-a-spiffe-id", "bob"), 
defaultConfig()));
         EasyMock.verify(resolver);
     }
 
@@ -94,7 +105,7 @@ public class ServiceAccountValidatorTest {
         EasyMock.expect(resolver.getAnnotation(NS, SA, 
ANNOTATION)).andReturn(Optional.empty());
         EasyMock.replay(resolver);
 
-        assertFalse(validator.validate(request(SPIFFE, "bob", resolver), 
defaultConfig()));
+        assertFalse(validator.validate(request(SPIFFE, "bob"), 
defaultConfig()));
         EasyMock.verify(resolver);
     }
 
@@ -114,8 +125,6 @@ public class ServiceAccountValidatorTest {
         EasyMock.replay(cfg);
 
         final HttpServletRequest req = 
EasyMock.createMock(HttpServletRequest.class);
-        
EasyMock.expect(req.getAttribute(ServiceAccountValidator.RESOLVER_REQUEST_ATTR))
-                .andReturn(resolver).anyTimes();
         
EasyMock.expect(req.getHeader("X-Custom-Spiffe")).andReturn(SPIFFE).anyTimes();
         
EasyMock.expect(req.getHeader("x-custom-user")).andReturn("bob").anyTimes();
         EasyMock.replay(req);
@@ -136,11 +145,8 @@ public class ServiceAccountValidatorTest {
         return cfg;
     }
 
-    private static HttpServletRequest request(String spiffe, String user,
-                                              K8sServiceAccountResolver 
resolver) {
+    private static HttpServletRequest request(String spiffe, String user) {
         final HttpServletRequest req = 
EasyMock.createMock(HttpServletRequest.class);
-        
EasyMock.expect(req.getAttribute(ServiceAccountValidator.RESOLVER_REQUEST_ATTR))
-                .andReturn(resolver).anyTimes();
         
EasyMock.expect(req.getHeader(ServiceAccountValidator.SPIFFE_HEADER_DEFAULT))
                 .andReturn(spiffe).anyTimes();
         
EasyMock.expect(req.getHeader(ServiceAccountValidator.USER_HEADER_DEFAULT))
diff --git 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/AbstractPreAuthFederationFilter.java
 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/AbstractPreAuthFederationFilter.java
index d04a0d93c..ea0c0e76e 100644
--- 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/AbstractPreAuthFederationFilter.java
+++ 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/AbstractPreAuthFederationFilter.java
@@ -49,6 +49,7 @@ public abstract class AbstractPreAuthFederationFilter 
implements Filter {
 
   private List<PreAuthValidator> validators;
   private FilterConfig filterConfig;
+  private PreAuthService preAuthService;
   private static AuditService auditService = 
AuditServiceFactory.getAuditService();
   private static Auditor auditor = auditService.getAuditor(
       AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
@@ -56,12 +57,20 @@ public abstract class AbstractPreAuthFederationFilter 
implements Filter {
 
   public AbstractPreAuthFederationFilter() {
     super();
+    preAuthService = new PreAuthService();
   }
 
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
     this.filterConfig = filterConfig;
-    validators = PreAuthService.getValidators(filterConfig);
+    validators = preAuthService.getValidators(filterConfig);
+    for (PreAuthValidator validator : validators) {
+      try {
+        validator.init(filterConfig);
+      } catch (Exception e) {
+        throw new ServletException("Unable to initialize validator: " + 
validator.getName(), e);
+      }
+    }
   }
 
   // VisibleForTesting
@@ -75,7 +84,7 @@ public abstract class AbstractPreAuthFederationFilter 
implements Filter {
     HttpServletRequest httpRequest = (HttpServletRequest)request;
     String principal = getPrimaryPrincipal(httpRequest);
     if (principal != null) {
-      if (PreAuthService.validate(httpRequest, filterConfig, validators)) {
+      if (preAuthService.validate(httpRequest, filterConfig, validators)) {
         Subject subject = new Subject();
         subject.getPrincipals().add(new PrimaryPrincipal(principal));
         addGroupPrincipals(httpRequest, subject.getPrincipals());
@@ -104,6 +113,9 @@ public abstract class AbstractPreAuthFederationFilter 
implements Filter {
 
   @Override
   public void destroy() {
+    for (PreAuthValidator validator : validators) {
+      validator.destroy();
+    }
   }
 
   private void doAs(final ServletRequest request, final ServletResponse 
response, final FilterChain chain, Subject subject)
diff --git 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/DefaultValidator.java
 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/DefaultValidator.java
index 65665032e..b73f59f84 100644
--- 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/DefaultValidator.java
+++ 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/DefaultValidator.java
@@ -33,6 +33,16 @@ public class DefaultValidator implements PreAuthValidator {
   public DefaultValidator() {
   }
 
+  @Override
+  public void init(FilterConfig filterConfig) throws Exception{
+    //NOP
+  }
+
+  @Override
+  public void destroy() {
+    //NOP
+  }
+
   @Override
   public boolean validate(HttpServletRequest httpRequest, FilterConfig 
filterConfig) throws PreAuthValidationException {
     return true;
diff --git 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/IPValidator.java
 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/IPValidator.java
index 508618926..9a04682fb 100644
--- 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/IPValidator.java
+++ 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/IPValidator.java
@@ -29,6 +29,16 @@ public class IPValidator implements PreAuthValidator {
   public IPValidator() {
   }
 
+  @Override
+  public void init(FilterConfig filterConfig) throws Exception {
+    //NOP
+  }
+
+  @Override
+  public void destroy() {
+    //NOP
+  }
+
   @Override
   public boolean validate(HttpServletRequest httpRequest, FilterConfig 
filterConfig)
       throws PreAuthValidationException {
diff --git 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthFederationFilter.java
 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthFederationFilter.java
index 020004d4e..0f39ac64d 100644
--- 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthFederationFilter.java
+++ 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthFederationFilter.java
@@ -33,6 +33,7 @@ public class PreAuthFederationFilter implements Filter {
   private static final String CUSTOM_HEADER_PARAM = "preauth.customHeader";
   private List<PreAuthValidator> validators;
   private FilterConfig filterConfig;
+  private PreAuthService preAuthService;
   private String headerName = "SM_USER";
 
   @Override
@@ -42,7 +43,8 @@ public class PreAuthFederationFilter implements Filter {
       headerName = customHeader;
     }
     this.filterConfig = filterConfig;
-    validators = PreAuthService.getValidators(filterConfig);
+    preAuthService = new PreAuthService();
+    validators = preAuthService.getValidators(filterConfig);
   }
 
   @Override
@@ -50,7 +52,7 @@ public class PreAuthFederationFilter implements Filter {
                        FilterChain chain) throws IOException, ServletException 
{
     HttpServletRequest httpRequest = (HttpServletRequest) request;
     if (httpRequest.getHeader(headerName) != null) {
-      if (PreAuthService.validate(httpRequest, filterConfig, validators)) {
+      if (preAuthService.validate(httpRequest, filterConfig, validators)) {
         // TODO: continue as subject
         chain.doFilter(request, response);
       } else {
diff --git 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthService.java
 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthService.java
index 13b43af99..730c36836 100644
--- 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthService.java
+++ 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthService.java
@@ -31,31 +31,29 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * This class manages few utility methods used across different classes of 
pre-auth module
+ * This class manages utility methods used across different classes of 
pre-auth module.
+ * It is now instance-based to ensure proper ClassLoader-aware validator 
discovery.
  * @since 0.12
  */
 public class PreAuthService {
 
   public static final String VALIDATION_METHOD_PARAM = 
"preauth.validation.method";
-  private static ConcurrentHashMap<String, PreAuthValidator> validatorMap;
+  private final Map<String, PreAuthValidator> validatorMap = new 
ConcurrentHashMap<>();
+  private boolean initialized;
 
-  static {
-    initializeValidators();
+  public PreAuthService() {
   }
 
-  private static void initializeValidators() {
-    ServiceLoader<PreAuthValidator> servLoader = 
ServiceLoader.load(PreAuthValidator.class);
-    validatorMap = new ConcurrentHashMap<>();
-    for (PreAuthValidator validator : servLoader) {
-      validatorMap.put(validator.getName(), validator);
+  private synchronized void ensureInitialized() {
+    if (!initialized) {
+      ServiceLoader<PreAuthValidator> servLoader = 
ServiceLoader.load(PreAuthValidator.class);
+      for (PreAuthValidator validator : servLoader) {
+        validatorMap.put(validator.getName(), validator);
+      }
+      initialized = true;
     }
   }
 
-  // VisibleForTesting
-  public static Map<String, PreAuthValidator> getValidatorMap() {
-    return Collections.unmodifiableMap(validatorMap);
-  }
-
   /**
    * This method returns appropriate pre-auth Validator as defined in config
    *
@@ -64,7 +62,8 @@ public class PreAuthService {
    * @return a list of PreAuthValidator instances as defined in config
    * @throws ServletException unable to find validator
    */
-  public static List<PreAuthValidator> getValidators(FilterConfig 
filterConfig) throws ServletException {
+  public List<PreAuthValidator> getValidators(FilterConfig filterConfig) 
throws ServletException {
+    ensureInitialized();
     String validationMethods = 
filterConfig.getInitParameter(VALIDATION_METHOD_PARAM);
     List<PreAuthValidator> vList = new ArrayList<>();
     if (validationMethods == null || validationMethods.isEmpty()) {
@@ -76,26 +75,30 @@ public class PreAuthService {
       if (validatorMap.containsKey(vName)) {
         vList.add(validatorMap.get(vName));
       } else {
-        throw new ServletException(String.format(Locale.ROOT, "Unable to find 
validator with name '%s'", validationMethods));
+        throw new ServletException(String.format(Locale.ROOT, "Unable to find 
validator with name '%s'", vName));
       }
     }
     return vList;
   }
 
-  public static boolean validate(HttpServletRequest httpRequest, FilterConfig 
filterConfig, List<PreAuthValidator>
+  public boolean validate(HttpServletRequest httpRequest, FilterConfig 
filterConfig, List<PreAuthValidator>
       validators) {
     try {
       for (PreAuthValidator validator : validators) {
-        //Any one validator fails, it will fail the request. loginal AND 
behavior
+        // Any one validator fails, it will fail the request. Logical AND 
behavior.
         if (!validator.validate(httpRequest, filterConfig)) {
           return false;
         }
       }
     } catch (PreAuthValidationException e) {
-      // TODO log exception
       return false;
     }
     return true;
   }
 
+  // VisibleForTesting
+  public Map<String, PreAuthValidator> getValidatorMap() {
+    ensureInitialized();
+    return Collections.unmodifiableMap(validatorMap);
+  }
 }
diff --git 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthValidator.java
 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthValidator.java
index beb9e196f..b592542cd 100644
--- 
a/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthValidator.java
+++ 
b/gateway-provider-security-preauth/src/main/java/org/apache/knox/gateway/preauth/filter/PreAuthValidator.java
@@ -21,6 +21,11 @@ import javax.servlet.FilterConfig;
 import javax.servlet.http.HttpServletRequest;
 
 public interface PreAuthValidator {
+
+  void  init(FilterConfig filterConfig) throws Exception;
+
+  void destroy();
+
   boolean validate(HttpServletRequest httpRequest, FilterConfig filterConfig) 
throws
       PreAuthValidationException;
 
diff --git 
a/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/HeaderPreAuthFederationFilterTest.java
 
b/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/HeaderPreAuthFederationFilterTest.java
index 1f778f1bb..1414efc22 100644
--- 
a/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/HeaderPreAuthFederationFilterTest.java
+++ 
b/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/HeaderPreAuthFederationFilterTest.java
@@ -23,6 +23,7 @@ import org.apache.knox.gateway.preauth.filter.IPValidator;
 import org.apache.knox.gateway.preauth.filter.PreAuthService;
 import org.apache.knox.gateway.preauth.filter.PreAuthValidator;
 import org.easymock.EasyMock;
+import org.junit.Before;
 import org.junit.Test;
 
 import javax.servlet.FilterConfig;
@@ -36,6 +37,14 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 public class HeaderPreAuthFederationFilterTest {
+
+  private PreAuthService preAuthService;
+
+  @Before
+  public void setUp() {
+    preAuthService = new PreAuthService();
+  }
+
   @Test
   public void testDefaultValidator() throws ServletException {
     HeaderPreAuthFederationFilter hpaff = new HeaderPreAuthFederationFilter();
@@ -50,7 +59,7 @@ public class HeaderPreAuthFederationFilterTest {
     List<PreAuthValidator> validators = hpaff.getValidators();
     assertEquals(validators.size(), 1);
     assertEquals(validators.get(0).getName(), 
DefaultValidator.DEFAULT_VALIDATION_METHOD_VALUE);
-    assertTrue(PreAuthService.validate(request, filterConfig, validators));
+    assertTrue(preAuthService.validate(request, filterConfig, validators));
   }
 
   @Test
@@ -72,13 +81,13 @@ public class HeaderPreAuthFederationFilterTest {
     List<PreAuthValidator> validators = hpaff.getValidators();
     assertEquals(validators.size(), 1);
     assertEquals(validators.get(0).getName(), 
IPValidator.IP_VALIDATION_METHOD_VALUE);
-    assertTrue(PreAuthService.validate(request, filterConfig, validators));
+    assertTrue(preAuthService.validate(request, filterConfig, validators));
 
     //Negative testing
     EasyMock.reset(request);
     EasyMock.expect(request.getRemoteAddr()).andReturn("10.10.22.33");
     EasyMock.replay(request);
-    assertFalse(PreAuthService.validate(request, filterConfig, validators));
+    assertFalse(preAuthService.validate(request, filterConfig, validators));
   }
 
   @Test
@@ -99,7 +108,7 @@ public class HeaderPreAuthFederationFilterTest {
     EasyMock.reset(request);
     EasyMock.expect(request.getHeader("CUSTOM_TOKEN")).andReturn("HelloWorld");
     EasyMock.replay(request);
-    assertTrue(PreAuthService.validate(request, filterConfig, validators));
+    assertTrue(preAuthService.validate(request, filterConfig, validators));
 
   }
 
@@ -121,7 +130,7 @@ public class HeaderPreAuthFederationFilterTest {
     EasyMock.reset(request);
     
EasyMock.expect(request.getHeader("CUSTOM_TOKEN")).andReturn("NOTHelloWorld");
     EasyMock.replay(request);
-    assertFalse(PreAuthService.validate(request, filterConfig, validators));
+    assertFalse(preAuthService.validate(request, filterConfig, validators));
 
   }
 
@@ -131,6 +140,16 @@ public class HeaderPreAuthFederationFilterTest {
     public DummyValidator() {
     }
 
+    @Override
+    public void init(FilterConfig filterConfig) throws Exception {
+      //NOP
+    }
+
+    @Override
+    public void destroy() {
+      //NOP
+    }
+
     @Override
     public boolean validate(HttpServletRequest httpRequest, FilterConfig 
filterConfig) {
       String token = httpRequest.getHeader("CUSTOM_TOKEN");
diff --git 
a/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/PreAuthServiceTest.java
 
b/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/PreAuthServiceTest.java
index 1197130e6..6a1aef4ec 100644
--- 
a/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/PreAuthServiceTest.java
+++ 
b/gateway-provider-security-preauth/src/test/java/org/apache/knox/gateway/provider/federation/PreAuthServiceTest.java
@@ -22,6 +22,7 @@ import org.apache.knox.gateway.preauth.filter.IPValidator;
 import org.apache.knox.gateway.preauth.filter.PreAuthService;
 import org.apache.knox.gateway.preauth.filter.PreAuthValidator;
 import org.easymock.EasyMock;
+import org.junit.Before;
 import org.junit.Test;
 
 import javax.servlet.FilterConfig;
@@ -39,9 +40,17 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 public class PreAuthServiceTest {
+
+  private PreAuthService preAuthService;
+
+  @Before
+  public void setUp() throws Exception {
+    preAuthService = new PreAuthService();
+  }
+
   @Test
   public void testValidatorMap() {
-    Map<String, PreAuthValidator> valMap = PreAuthService.getValidatorMap();
+    Map<String, PreAuthValidator> valMap = preAuthService.getValidatorMap();
     assertNotNull(valMap.get(IPValidator.IP_VALIDATION_METHOD_VALUE));
     assertEquals(valMap.get(IPValidator.IP_VALIDATION_METHOD_VALUE).getName(), 
IPValidator.IP_VALIDATION_METHOD_VALUE);
     
assertNotNull(valMap.get(DefaultValidator.DEFAULT_VALIDATION_METHOD_VALUE));
@@ -61,10 +70,10 @@ public class PreAuthServiceTest {
     final HttpServletRequest request = 
EasyMock.createMock(HttpServletRequest.class);
     EasyMock.replay(request);
 
-    List<PreAuthValidator> validators = 
PreAuthService.getValidators(filterConfig);
+    List<PreAuthValidator> validators = 
preAuthService.getValidators(filterConfig);
     assertEquals(validators.size(), 1);
     assertEquals(validators.get(0).getName(), 
DefaultValidator.DEFAULT_VALIDATION_METHOD_VALUE);
-    assertTrue(PreAuthService.validate(request, filterConfig, validators));
+    assertTrue(preAuthService.validate(request, filterConfig, validators));
   }
 
   @Test
@@ -80,16 +89,16 @@ public class PreAuthServiceTest {
         .andReturn(IPValidator.IP_VALIDATION_METHOD_VALUE).anyTimes();
     EasyMock.replay(filterConfig);
 
-    List<PreAuthValidator> validators = 
PreAuthService.getValidators(filterConfig);
+    List<PreAuthValidator> validators = 
preAuthService.getValidators(filterConfig);
     assertEquals(validators.size(), 1);
     assertEquals(validators.get(0).getName(), 
IPValidator.IP_VALIDATION_METHOD_VALUE);
-    assertTrue(PreAuthService.validate(request, filterConfig, validators));
+    assertTrue(preAuthService.validate(request, filterConfig, validators));
 
     //Negative testing
     EasyMock.reset(request);
     EasyMock.expect(request.getRemoteAddr()).andReturn("10.10.22.33");
     EasyMock.replay(request);
-    assertFalse(PreAuthService.validate(request, filterConfig, validators));
+    assertFalse(preAuthService.validate(request, filterConfig, validators));
   }
 
   @Test
@@ -105,17 +114,17 @@ public class PreAuthServiceTest {
         .andReturn(DefaultValidator.DEFAULT_VALIDATION_METHOD_VALUE + "," + 
IPValidator.IP_VALIDATION_METHOD_VALUE).anyTimes();
     EasyMock.replay(filterConfig);
 
-    List<PreAuthValidator> validators = 
PreAuthService.getValidators(filterConfig);
+    List<PreAuthValidator> validators = 
preAuthService.getValidators(filterConfig);
     assertEquals(validators.size(), 2);
     assertEquals(validators.get(0).getName(), 
DefaultValidator.DEFAULT_VALIDATION_METHOD_VALUE);
     assertEquals(validators.get(1).getName(), 
IPValidator.IP_VALIDATION_METHOD_VALUE);
 
-    assertTrue(PreAuthService.validate(request, filterConfig, validators));
+    assertTrue(preAuthService.validate(request, filterConfig, validators));
     //Negative testing
     EasyMock.reset(request);
     EasyMock.expect(request.getRemoteAddr()).andReturn("10.10.22.33");
     EasyMock.replay(request);
-    assertFalse(PreAuthService.validate(request, filterConfig, validators));
+    assertFalse(preAuthService.validate(request, filterConfig, validators));
 
   }
 
@@ -126,12 +135,11 @@ public class PreAuthServiceTest {
         (DefaultValidator.DEFAULT_VALIDATION_METHOD_VALUE + ",  
NOT_EXISTED_VALIDATOR" );
     EasyMock.replay(filterConfig);
     try {
-      PreAuthService.getValidators(filterConfig);
+      preAuthService.getValidators(filterConfig);
       fail("Should throw exception due to invalid validator");
     } catch (Exception e) {
       //Expected
-      assertEquals("Unable to find validator with name 
'preauth.default.validation,  " +
-                       "NOT_EXISTED_VALIDATOR'", e.getMessage());
+      assertEquals("Unable to find validator with name 
'NOT_EXISTED_VALIDATOR'", e.getMessage());
     }
   }
 }

Reply via email to