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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9b7c4b7c5 KNOX-3107 - Alias Support for the RemoteAuthProvider 
truststore password (#1002)
9b7c4b7c5 is described below

commit 9b7c4b7c51bc4ffc1e49702604c1f0b841dd6994
Author: lmccay <[email protected]>
AuthorDate: Sat Mar 8 10:38:08 2025 -0500

    KNOX-3107 - Alias Support for the RemoteAuthProvider truststore password 
(#1002)
---
 .../knox/gateway/filter/RemoteAuthFilter.java      | 121 +++++++++-----
 .../knox/gateway/filter/RemoteAuthFilterTest.java  | 177 ++++++++++++---------
 2 files changed, 179 insertions(+), 119 deletions(-)

diff --git 
a/gateway-provider-security-authc-remote/src/main/java/org/apache/knox/gateway/filter/RemoteAuthFilter.java
 
b/gateway-provider-security-authc-remote/src/main/java/org/apache/knox/gateway/filter/RemoteAuthFilter.java
index bbf5d17aa..29536d35c 100755
--- 
a/gateway-provider-security-authc-remote/src/main/java/org/apache/knox/gateway/filter/RemoteAuthFilter.java
+++ 
b/gateway-provider-security-authc-remote/src/main/java/org/apache/knox/gateway/filter/RemoteAuthFilter.java
@@ -33,6 +33,8 @@ import org.apache.knox.gateway.security.GroupPrincipal;
 import org.apache.knox.gateway.security.PrimaryPrincipal;
 import org.apache.knox.gateway.services.GatewayServices;
 import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.AliasServiceException;
 import org.apache.knox.gateway.services.security.KeystoreService;
 import org.apache.knox.gateway.services.security.KeystoreServiceException;
 import org.apache.logging.log4j.ThreadContext;
@@ -80,6 +82,7 @@ public class RemoteAuthFilter implements Filter {
   static final String WILDCARD = "*";
   static final String TRACE_ID = "trace_id";
   static final String REQUEST_ID_HEADER_NAME = "X-Request-Id";
+  static final String 
TRUSTSTORE_CONFIGURATION_CANNOT_BE_RESOLVED_INTO_A_VALID_TRUSTSTORE = 
"Truststore configuration cannot be resolved into a valid truststore";
 
   private String remoteAuthUrl;
   private List<String> includeHeaders;
@@ -98,9 +101,7 @@ public class RemoteAuthFilter implements Filter {
           AuditConstants.DEFAULT_AUDITOR_NAME, 
AuditConstants.KNOX_SERVICE_NAME, AuditConstants.KNOX_COMPONENT_NAME );
   private final RemoteAuthMessages LOGGER = MessagesFactory.get( 
RemoteAuthMessages.class );
 
-  private String truststorePath;
-  private String truststorePassword;
-  private String truststoreType;
+  private KeyStore trustStore;
 
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
@@ -112,9 +113,9 @@ public class RemoteAuthFilter implements Filter {
     includeHeaders = 
Arrays.asList(filterConfig.getInitParameter(CONFIG_INCLUDE_HEADERS).split(","));
     cacheKeyHeader = filterConfig.getInitParameter(CONFIG_CACHE_KEY_HEADER) != 
null ? filterConfig
             .getInitParameter(CONFIG_CACHE_KEY_HEADER) : 
DEFAULT_CACHE_KEY_HEADER;
-    String cachetime = filterConfig.getInitParameter(CONFIG_EXPIRE_AFTER);
-    if (cachetime != null) {
-      int expireAfterMinutes = Integer.parseInt(cachetime);
+    String cacheTime = filterConfig.getInitParameter(CONFIG_EXPIRE_AFTER);
+    if (cacheTime != null) {
+      int expireAfterMinutes = Integer.parseInt(cacheTime);
       authenticationCache = CacheBuilder.newBuilder()
               .expireAfterWrite(expireAfterMinutes, TimeUnit.MINUTES)
               .build();
@@ -132,12 +133,74 @@ public class RemoteAuthFilter implements Filter {
       groupHeaders = Arrays.asList(groupHeaderParam.split("\\s*,\\s*"));
     }
 
-    truststorePath = filterConfig.getInitParameter(CONFIG_TRUSTSTORE_PATH);
-    truststorePassword = 
filterConfig.getInitParameter(CONFIG_TRUSTSTORE_PASSWORD);
-    truststoreType = filterConfig.getInitParameter(CONFIG_TRUSTSTORE_TYPE);
+    buildTrustStore(filterConfig);
+  }
+
+  private void buildTrustStore(FilterConfig filterConfig) throws 
ServletException {
+    String truststorePath = 
filterConfig.getInitParameter(CONFIG_TRUSTSTORE_PATH);
+    String truststorePassword = 
filterConfig.getInitParameter(CONFIG_TRUSTSTORE_PASSWORD);
+    String truststoreType = 
filterConfig.getInitParameter(CONFIG_TRUSTSTORE_TYPE);
     if (truststoreType == null || truststoreType.isEmpty()) {
       truststoreType = DEFAULT_TRUSTSTORE_TYPE;
     }
+
+    ServletContext context = filterConfig.getServletContext();
+    if (context != null) {
+      String topologyName = (String) 
context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE);
+      GatewayServices services = (GatewayServices) 
context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+      if (services != null) {
+        try {
+          final AliasService aliasService =  
services.getService(ServiceType.ALIAS_SERVICE);
+          if (truststorePath != null && !truststorePath.isEmpty()) {
+            if (truststorePassword == null || truststorePassword.isEmpty()) {
+              // let's check for an alias given the intent to specify a 
truststore path
+              char[] passChars = 
aliasService.getPasswordFromAliasForCluster(topologyName,
+                      CONFIG_TRUSTSTORE_PASSWORD, false);
+              if (passChars != null) {
+                truststorePassword = new String(passChars);
+              }
+              if (truststorePassword == null || truststorePassword.isEmpty()) {
+                truststorePassword = new 
String(aliasService.getPasswordFromAliasForGateway(CONFIG_TRUSTSTORE_PASSWORD));
+              }
+            }
+          }
+          KeystoreService keystoreService = 
services.getService(ServiceType.KEYSTORE_SERVICE);
+          trustStore = getTrustStore(truststorePath, truststoreType, 
truststorePassword, keystoreService);
+        } catch (AliasServiceException | IOException e) {
+          throw new ServletException("Error while initializing 
RemoteAuthProvider", e);
+        }
+      }
+    }
+    if (trustStore == null) {
+      // truststore details were explicitly configured but there is no servlet 
context available for gateway services
+      throw new 
ServletException(TRUSTSTORE_CONFIGURATION_CANNOT_BE_RESOLVED_INTO_A_VALID_TRUSTSTORE);
+    }
+  }
+
+  private KeyStore getTrustStore(String truststorePath, String truststoreType, 
String truststorePassword,
+                                 KeystoreService keystoreService) throws 
IOException {
+    KeyStore truststore = null;
+    try {
+      // Try topology-specific truststore first if configured
+      if (truststorePath != null && !truststorePath.isEmpty()) {
+        truststore = keystoreService.loadTruststore(truststorePath, 
truststoreType, truststorePassword);
+        if (truststore == null) {
+          // truststore details were explicitly configured but there is no 
truststore realized by that config
+          throw new 
IOException(TRUSTSTORE_CONFIGURATION_CANNOT_BE_RESOLVED_INTO_A_VALID_TRUSTSTORE);
+        }
+      }
+      // Fall back to gateway-level truststore
+      if (truststore == null) {
+        truststore = keystoreService.getTruststoreForHttpClient();
+        if (truststore == null) {
+          truststore = keystoreService.getKeystoreForGateway();
+        }
+      }
+    } catch (KeystoreServiceException e) {
+      LOGGER.failedToLoadTruststore(e.getMessage(), e);
+      throw new IOException("Failed to load truststore: ", e);
+    }
+    return truststore;
   }
 
   public SSLSocketFactory createSSLSocketFactory(KeyStore trustStore) throws 
Exception {
@@ -164,7 +227,7 @@ public class RemoteAuthFilter implements Filter {
     }
 
     try {
-      HttpURLConnection connection = 
getHttpURLConnection(request.getServletContext());
+      HttpURLConnection connection = getHttpURLConnection();
       for (String header : includeHeaders) {
         String headerValue = httpRequest.getHeader(header);
         if (headerValue != null) {
@@ -211,22 +274,14 @@ public class RemoteAuthFilter implements Filter {
     }
   }
 
-  private HttpURLConnection getHttpURLConnection(ServletContext 
servletContext) throws IOException {
-    KeyStore truststore = null;
-    GatewayServices services = (GatewayServices) 
servletContext.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
-    if (services != null) {
-      KeystoreService keystoreService = 
services.getService(ServiceType.KEYSTORE_SERVICE);
-      if (keystoreService != null) {
-        truststore = getTrustStore(truststore, keystoreService);
-      }
-    }
+  private HttpURLConnection getHttpURLConnection() throws IOException {
     HttpURLConnection connection;
     if (httpURLConnection == null) {
       URL url = new URL(remoteAuthUrl);
       connection = (HttpURLConnection) url.openConnection();
-      if (truststore != null) {
+      if (trustStore != null) {
         try {
-          ((HttpsURLConnection) 
connection).setSSLSocketFactory(createSSLSocketFactory(truststore));
+          ((HttpsURLConnection) 
connection).setSSLSocketFactory(createSSLSocketFactory(trustStore));
         } catch (Exception e) {
           throw new RuntimeException(e);
         }
@@ -237,27 +292,9 @@ public class RemoteAuthFilter implements Filter {
     return connection;
   }
 
-  private KeyStore getTrustStore(KeyStore truststore, KeystoreService 
keystoreService) throws IOException {
-    try {
-      // Try topology-specific truststore first if configured
-      if (truststorePath != null && !truststorePath.isEmpty()) {
-        truststore = keystoreService.loadTruststore(truststorePath, 
truststoreType, truststorePassword);
-      }
-      // Fall back to gateway-level truststore
-      if (truststore == null) {
-        truststore = keystoreService.getTruststoreForHttpClient();
-        if (truststore == null) {
-          truststore = keystoreService.getKeystoreForGateway();
-        }
-      }
-    } catch (KeystoreServiceException e) {
-      LOGGER.failedToLoadTruststore(e.getMessage(), e);
-      throw new IOException("Failed to load truststore: ", e);
-    }
-    return truststore;
-  }
-
-  private void continueWithEstablishedSecurityContext(Subject subject, final 
HttpServletRequest request, final HttpServletResponse response, final 
FilterChain chain) throws IOException, ServletException {
+  private void continueWithEstablishedSecurityContext(Subject subject, final 
HttpServletRequest request,
+                                                      final 
HttpServletResponse response, final FilterChain chain)
+          throws IOException, ServletException {
     try {
       Subject.doAs(
               subject,
diff --git 
a/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java
 
b/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java
index f81af57e5..0c269a380 100644
--- 
a/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java
+++ 
b/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java
@@ -21,8 +21,8 @@ import org.apache.knox.gateway.security.GroupPrincipal;
 import org.apache.knox.gateway.security.PrimaryPrincipal;
 import org.apache.knox.gateway.services.GatewayServices;
 import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
 import org.apache.knox.gateway.services.security.KeystoreService;
-import org.apache.knox.gateway.services.security.KeystoreServiceException;
 import org.apache.knox.test.mock.MockServletContext;
 import org.easymock.EasyMock;
 import org.junit.Before;
@@ -51,14 +51,24 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+/**
+ * Tests for RemoteAuthFilter focusing on:
+ * - Initialization flow and error handling
+ * - Truststore configuration processing during init (not per-request)
+ * - Fast failure with invalid truststore configuration
+ * - Integration between the filter and KeystoreService
+ *
+ * Note: These tests use mocks for the KeystoreService and don't test actual 
SSL/TLS
+ * connections or certificate validation.
+ */
 @SuppressWarnings("PMD.JUnit4TestShouldUseBeforeAnnotation")
 public class RemoteAuthFilterTest {
-
     public static final String BEARER_INVALID_TOKEN = "Bearer invalid-token";
     public static final String BEARER_VALID_TOKEN = "Bearer valid-token";
     public static final String URL_SUCCESS = "https://example.com/auth";;
@@ -75,35 +85,70 @@ public class RemoteAuthFilterTest {
     private GatewayServices gatewayServicesMock;
     private KeystoreService keystoreServiceMock;
     private ServletContext servletContextMock;
+    private AliasService aliasServiceMock;
+    private FilterConfig filterConfigMock;
 
     @Before
     public void createMocks() {
         requestMock = EasyMock.createMock(HttpServletRequest.class);
         responseMock = EasyMock.createMock(HttpServletResponse.class);
+        filterConfigMock = EasyMock.createNiceMock(FilterConfig.class);
+        keystoreServiceMock = EasyMock.createNiceMock(KeystoreService.class);
+        aliasServiceMock = EasyMock.createNiceMock(AliasService.class);
+        servletContextMock = EasyMock.createNiceMock(ServletContext.class);
+        gatewayServicesMock = EasyMock.createNiceMock(GatewayServices.class);
     }
 
-    private void setUp(String trustStorePath, String trustStorePass, String 
trustStoreType) {
-        // Reset existing mocks
-        EasyMock.reset(requestMock, responseMock);
+    private void setUp(String trustStorePath, String trustStorePass, String 
trustStoreType) throws Exception {
+        // Reset ALL mocks
+        EasyMock.reset(requestMock, responseMock, filterConfigMock, 
gatewayServicesMock,
+                      servletContextMock, keystoreServiceMock, 
aliasServiceMock);
 
-        FilterConfig filterConfigMock = 
EasyMock.createNiceMock(FilterConfig.class);
         chainMock = new TestFilterChain();
 
-        // Create and configure Gateway Services mocks
-        gatewayServicesMock = EasyMock.createNiceMock(GatewayServices.class);
-        keystoreServiceMock = EasyMock.createNiceMock(KeystoreService.class);
-        servletContextMock = EasyMock.createNiceMock(ServletContext.class);
+        // Set up FilterConfig's ServletContext association FIRST
+        EasyMock.expect(filterConfigMock.getServletContext())
+               .andReturn(servletContextMock)
+               .anyTimes();
+
+        // Now set up ServletContext expectations
+        
EasyMock.expect(servletContextMock.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE))
+               .andReturn("test-topology")
+               .anyTimes();
+        
EasyMock.expect(servletContextMock.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE))
+               .andReturn(gatewayServicesMock)
+               .anyTimes();
 
         // Set up Gateway Services expectations
         
EasyMock.expect(gatewayServicesMock.getService(ServiceType.KEYSTORE_SERVICE))
                .andReturn(keystoreServiceMock)
                .anyTimes();
-        
EasyMock.expect(servletContextMock.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE))
-               .andReturn(gatewayServicesMock)
+        
EasyMock.expect(gatewayServicesMock.getService(ServiceType.ALIAS_SERVICE))
+               .andReturn(aliasServiceMock)
                .anyTimes();
 
+        try {
+            // Set up default truststore expectation for when no explicit 
truststore is configured
+            KeyStore defaultTruststore = KeyStore.getInstance("JKS");
+            EasyMock.expect(keystoreServiceMock.getTruststoreForHttpClient())
+                   .andReturn(defaultTruststore)
+                   .anyTimes();
+        } catch (KeyStoreException e) {
+            throw new RuntimeException(e);
+        }
+
+        
EasyMock.expect(aliasServiceMock.getPasswordFromAliasForCluster("test-topology",
+                        "remote.auth.truststore.password", false))
+                .andReturn("password".toCharArray())
+                .anyTimes();
+        
EasyMock.expect(aliasServiceMock.getPasswordFromAliasForGateway("remote.auth.truststore.password"))
+                .andReturn("password".toCharArray())
+                .anyTimes();
+
         // Basic config
-        
EasyMock.expect(filterConfigMock.getInitParameter(RemoteAuthFilter.CONFIG_REMOTE_AUTH_URL)).andReturn("https://example.com/auth";).anyTimes();
+        
EasyMock.expect(filterConfigMock.getInitParameter(RemoteAuthFilter.CONFIG_REMOTE_AUTH_URL))
+               .andReturn("https://example.com/auth";)
+               .anyTimes();
         
EasyMock.expect(filterConfigMock.getInitParameter(RemoteAuthFilter.CONFIG_INCLUDE_HEADERS)).andReturn("Authorization").anyTimes();
         
EasyMock.expect(filterConfigMock.getInitParameter(RemoteAuthFilter.DEFAULT_CACHE_KEY_HEADER)).andReturn("Authorization").anyTimes();
         
EasyMock.expect(filterConfigMock.getInitParameter(RemoteAuthFilter.CONFIG_EXPIRE_AFTER)).andReturn("5").anyTimes();
@@ -117,18 +162,21 @@ public class RemoteAuthFilterTest {
         
EasyMock.expect(filterConfigMock.getInitParameter(RemoteAuthFilter.CONFIG_TRUSTSTORE_TYPE)).andReturn(trustStoreType).anyTimes();
 
         // Only replay the mocks that won't need additional expectations
-        EasyMock.replay(filterConfigMock, gatewayServicesMock, 
servletContextMock);
+        EasyMock.replay(filterConfigMock, gatewayServicesMock, 
servletContextMock, keystoreServiceMock, aliasServiceMock);
 
         filter = new RemoteAuthFilter();
         try {
             filter.init(filterConfigMock);
         } catch (ServletException e) {
-            throw new RuntimeException(e);
+            if 
(!RemoteAuthFilter.TRUSTSTORE_CONFIGURATION_CANNOT_BE_RESOLVED_INTO_A_VALID_TRUSTSTORE.equals(
+                    e.getCause().getMessage())) {
+                throw new RuntimeException(e);
+            }
         }
     }
 
     // Default setup method for backward compatibility
-    private void setUp() {
+    private void setUp() throws Exception {
         setUp(null, null, null);
     }
 
@@ -339,44 +387,40 @@ public class RemoteAuthFilterTest {
 
     @Test
     public void testSuccessfulHttpsRequestWithTrustStore() throws Exception {
-        // Setup with valid trust store configuration
-        setUp("/path/to/truststore.jks", "trustpass", "JKS");
-
-        KeyStore testTruststore = KeyStore.getInstance("JKS");
-        
EasyMock.expect(keystoreServiceMock.loadTruststore("/path/to/truststore.jks", 
"JKS", "trustpass"))
-               .andReturn(testTruststore)
+        // Set up ServletContext expectations
+        
EasyMock.expect(servletContextMock.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE))
+               .andReturn("test-topology")
                .anyTimes();
-
-        EasyMock.expect(requestMock.getServletContext())
-               .andReturn(servletContextMock)
+        
EasyMock.expect(servletContextMock.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE))
+               .andReturn(gatewayServicesMock)
                .anyTimes();
-        EasyMock.expect(requestMock.getHeader("Authorization"))
-               .andReturn(BEARER_VALID_TOKEN)
+
+        // Set up GatewayServices expectations
+        
EasyMock.expect(gatewayServicesMock.getService(ServiceType.ALIAS_SERVICE))
+               .andReturn(aliasServiceMock)
                .anyTimes();
-        EasyMock.expect(responseMock.getStatus())
-               .andReturn(200)
+        
EasyMock.expect(gatewayServicesMock.getService(ServiceType.KEYSTORE_SERVICE))
+               .andReturn(keystoreServiceMock)
                .anyTimes();
-        
responseMock.sendError(EasyMock.eq(HttpServletResponse.SC_UNAUTHORIZED), 
EasyMock.anyString());
-        EasyMock.expectLastCall().andThrow(new AssertionError("Authentication 
should be successful, but was not.")).anyTimes();
-
-        EasyMock.replay(requestMock, responseMock, keystoreServiceMock);
 
-        setupURLConnection("https://example.com/auth";);
-        filter.doFilter(requestMock, responseMock, chainMock);
+        // Set up keystoreService expectations before filter initialization
+        KeyStore testTruststore = KeyStore.getInstance("JKS");
+        
EasyMock.expect(keystoreServiceMock.loadTruststore("/path/to/truststore.jks", 
"JKS", "trustpass"))
+               .andReturn(testTruststore)
+               .anyTimes();
 
-        assertTrue("Filter chain should have been called", 
chainMock.doFilterCalled);
-    }
+        // Set up aliasService expectations for password resolution
+        
EasyMock.expect(aliasServiceMock.getPasswordFromAliasForCluster("test-topology",
+                RemoteAuthFilter.CONFIG_TRUSTSTORE_PASSWORD, false))
+                .andReturn("trustpass".toCharArray())
+                .anyTimes();
 
-    @Test
-    public void testHttpsRequestWithoutTrustStore() throws Exception {
-        // Setup without trust store configuration
-        setUp(null, null, null);
+        EasyMock.replay(servletContextMock, gatewayServicesMock, 
keystoreServiceMock, aliasServiceMock);
 
-        KeyStore defaultTruststore = KeyStore.getInstance("JKS");
-        EasyMock.expect(keystoreServiceMock.getTruststoreForHttpClient())
-               .andReturn(defaultTruststore)
-               .anyTimes();
+        // Setup with valid trust store configuration - this will now trigger 
truststore loading
+        setUp("/path/to/truststore.jks", null, "JKS");  // null password to 
test alias resolution
 
+        // Regular request expectations
         EasyMock.expect(requestMock.getServletContext())
                .andReturn(servletContextMock)
                .anyTimes();
@@ -386,44 +430,23 @@ public class RemoteAuthFilterTest {
         EasyMock.expect(responseMock.getStatus())
                .andReturn(200)
                .anyTimes();
-        
responseMock.sendError(EasyMock.eq(HttpServletResponse.SC_UNAUTHORIZED), 
EasyMock.anyString());
-        EasyMock.expectLastCall().andThrow(new AssertionError("Authentication 
should be successful, but was not.")).anyTimes();
 
-        EasyMock.replay(requestMock, responseMock, keystoreServiceMock);
+        EasyMock.replay(requestMock, responseMock);
 
-        setupURLConnection("https://example.com/auth";);
+        setupURLConnection(URL_SUCCESS);
         filter.doFilter(requestMock, responseMock, chainMock);
 
-        assertTrue("Filter chain should have been called with default trust 
store", chainMock.doFilterCalled);
-    }
-
-    @Test
-    public void testHttpsRequestWithInvalidTrustStoreConfig() throws Exception 
{
-        // Setup with invalid trust store configuration
-        setUp("/nonexistent/path/truststore.jks", "password", "JKS");
-
-        
EasyMock.expect(keystoreServiceMock.loadTruststore("/nonexistent/path/truststore.jks",
 "JKS", "password"))
-               .andThrow(new KeystoreServiceException("Failed to load 
truststore"))
-               .anyTimes();
-
-        EasyMock.expect(requestMock.getServletContext())
-               .andReturn(servletContextMock)
-               .anyTimes();
-        EasyMock.expect(requestMock.getHeader("Authorization"))
-               .andReturn(BEARER_VALID_TOKEN)
-               .anyTimes();
-        EasyMock.expect(responseMock.getStatus())
-               .andReturn(500)
-               .anyTimes();
-        responseMock.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
"Error processing authentication request");
-        EasyMock.expectLastCall().once();
-
-        EasyMock.replay(requestMock, responseMock, keystoreServiceMock);
+        assertTrue("Filter chain should have been called", 
chainMock.doFilterCalled);
+        EasyMock.verify(keystoreServiceMock, aliasServiceMock);
 
-        filter.doFilter(requestMock, responseMock, chainMock);
+        // Verify the subject was properly set with expected principals
+        Set<PrimaryPrincipal> primaryPrincipals = 
chainMock.subject.getPrincipals(PrimaryPrincipal.class);
+        assertEquals("lmccay", 
((Principal)primaryPrincipals.toArray()[0]).getName());
 
-        assertFalse("Filter chain should not have been called", 
chainMock.doFilterCalled);
-        EasyMock.verify(responseMock);
+        Set<GroupPrincipal> groupPrincipals = 
chainMock.subject.getPrincipals(GroupPrincipal.class);
+        assertEquals(2, groupPrincipals.size());
+        assertTrue(groupPrincipals.stream().anyMatch(p -> 
p.getName().equals("admin")));
+        assertTrue(groupPrincipals.stream().anyMatch(p -> 
p.getName().equals("engineers")));
     }
 
     public static class MockHttpURLConnection extends HttpURLConnection {

Reply via email to