KNOX-2534. Allow alias to be used in pac4j topology block (#473)
diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
index bfea7ab..8abd2a3 100644
--- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
@@ -23,8 +23,8 @@
import org.apache.knox.gateway.pac4j.config.ClientConfigurationDecorator;
import org.apache.knox.gateway.pac4j.config.Pac4jClientConfigurationDecorator;
import org.apache.knox.gateway.pac4j.session.KnoxSessionStore;
-import org.apache.knox.gateway.services.ServiceType;
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.CryptoService;
@@ -72,7 +72,7 @@
* @since 0.8.0
*/
public class Pac4jDispatcherFilter implements Filter {
-
+ private static final String ALIAS_PREFIX = "${ALIAS=";
private static Pac4jMessages log = MessagesFactory.get(Pac4jMessages.class);
private static final ClientConfigurationDecorator PAC4J_CLIENT_CONFIGURATION_DECORATOR = new Pac4jClientConfigurationDecorator();
@@ -175,7 +175,7 @@
addDefaultConfig(clientNameParameter, properties);
while (names.hasMoreElements()) {
final String key = names.nextElement();
- properties.put(key, filterConfig.getInitParameter(key));
+ properties.put(key, resolveAlias(clusterName, key, filterConfig.getInitParameter(key)));
}
final PropertiesConfigFactory propertiesConfigFactory = new PropertiesConfigFactory(pac4jCallbackUrl, properties);
config = propertiesConfigFactory.build();
@@ -214,6 +214,18 @@
}
+ private String resolveAlias(String clusterName, String key, String value) throws ServletException {
+ if (value.startsWith(ALIAS_PREFIX) && value.endsWith("}")) {
+ String alias = value.substring(ALIAS_PREFIX.length(), value.length() - 1);
+ try {
+ return new String(aliasService.getPasswordFromAliasForCluster(clusterName, alias));
+ } catch (AliasServiceException e) {
+ throw new ServletException("Unable to retrieve alias for config: " + key, e);
+ }
+ }
+ return value;
+ }
+
private void addDefaultConfig(String clientNameParameter, Map<String, String> properties) {
// add default saml params
if (clientNameParameter.contains(SAML2Client.class.getSimpleName())) {
diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java
index 6671554..e73d8fe 100644
--- a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java
+++ b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java
@@ -36,9 +36,11 @@
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
@@ -367,4 +369,68 @@
assertEquals(USERNAME, adapter.getTestIdentifier());
}
+ @Test
+ public void testResolvesAlias() throws Exception {
+ final AliasService aliasService = EasyMock.createNiceMock(AliasService.class);
+ EasyMock.expect(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, KnoxSessionStore.PAC4J_PASSWORD, true))
+ .andReturn(PAC4J_PASSWORD.toCharArray()).anyTimes();
+ EasyMock.expect(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, KnoxSessionStore.PAC4J_PASSWORD))
+ .andReturn(PAC4J_PASSWORD.toCharArray()).anyTimes();
+ EasyMock.expect(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, "my-secret-alias"))
+ .andReturn("my-oidc-secret".toCharArray()).atLeastOnce();
+ EasyMock.replay(aliasService);
+
+ GatewayServices services = EasyMock.createNiceMock(GatewayServices.class);
+ EasyMock.expect(services.getService(ServiceType.CRYPTO_SERVICE)).andReturn(new DefaultCryptoService());
+ EasyMock.expect(services.getService(ServiceType.ALIAS_SERVICE)).andReturn(aliasService);
+ EasyMock.replay(services);
+
+ ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+ EasyMock.expect(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).andReturn(services);
+ EasyMock.expect(context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE)).andReturn(CLUSTER_NAME);
+ EasyMock.replay(context);
+
+ new Pac4jDispatcherFilter().init(
+ new FilterConfigStub(context)
+ .addInitParam(Pac4jDispatcherFilter.PAC4J_CALLBACK_URL, PAC4J_CALLBACK_URL)
+ .addInitParam("clientName", "OidcClient")
+ .addInitParam("oidc.secret", "${ALIAS=my-secret-alias}")
+ .addInitParam("oidc.id", "test-id")
+ );
+ EasyMock.verify(aliasService);
+ }
+
+ private class FilterConfigStub implements FilterConfig {
+ private ServletContext context;
+ private Properties properties = new Properties();
+
+ FilterConfigStub(ServletContext context) {
+ this.context = context;
+ }
+
+ public FilterConfigStub addInitParam(String name, String value) {
+ properties.setProperty(name, value);
+ return this;
+ }
+
+ @Override
+ public String getFilterName() {
+ return null;
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ return context;
+ }
+
+ @Override
+ public String getInitParameter(String s) {
+ return properties.getProperty(s, null);
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ return (Enumeration<String>) properties.propertyNames();
+ }
+ }
}