You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/09/01 13:17:07 UTC

[09/64] [partial] knox git commit: KNOX-998 - Refactoring save 1

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..a87c8d0
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
@@ -0,0 +1,215 @@
+/**
+ * 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.pac4j.filter;
+
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.pac4j.Pac4jMessages;
+import org.apache.knox.gateway.pac4j.session.KnoxSessionStore;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.AliasServiceException;
+import org.apache.knox.gateway.services.security.CryptoService;
+import org.pac4j.config.client.PropertiesConfigFactory;
+import org.pac4j.core.client.Client;
+import org.pac4j.core.config.Config;
+import org.pac4j.core.config.ConfigSingleton;
+import org.pac4j.core.context.J2EContext;
+import org.pac4j.core.context.Pac4jConstants;
+import org.pac4j.core.util.CommonHelper;
+import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
+import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
+import org.pac4j.j2e.filter.CallbackFilter;
+import org.pac4j.j2e.filter.RequiresAuthenticationFilter;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>This is the main filter for the pac4j provider. The pac4j provider module heavily relies on the j2e-pac4j library (https://github.com/pac4j/j2e-pac4j).</p>
+ * <p>This filter dispatches the HTTP calls between the j2e-pac4j filters:</p>
+ * <ul>
+ *     <li>to the {@link CallbackFilter} if the <code>client_name</code> parameter exists: it finishes the authentication process</li>
+ *     <li>to the {@link RequiresAuthenticationFilter} otherwise: it starts the authentication process (redirection to the identity provider) if the user is not authenticated</li>
+ * </ul>
+ * <p>It uses the {@link KnoxSessionStore} to manage session data. The generated cookies are defined on a domain name
+ * which can be configured via the domain suffix parameter: <code>pac4j.cookie.domain.suffix</code>.</p>
+ * <p>The callback url must be defined to the current protected url (KnoxSSO service for example) via the parameter: <code>pac4j.callbackUrl</code>.</p>
+ *
+ * @since 0.8.0
+ */
+public class Pac4jDispatcherFilter implements Filter {
+
+  private static Pac4jMessages log = MessagesFactory.get(Pac4jMessages.class);
+
+  public static final String TEST_BASIC_AUTH = "testBasicAuth";
+
+  public static final String PAC4J_CALLBACK_URL = "pac4j.callbackUrl";
+
+  public static final String PAC4J_CALLBACK_PARAMETER = "pac4jCallback";
+
+  private static final String PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM = "pac4j.cookie.domain.suffix";
+
+  private CallbackFilter callbackFilter;
+
+  private RequiresAuthenticationFilter requiresAuthenticationFilter;
+  private MasterService masterService = null;
+  private KeystoreService keystoreService = null;
+  private AliasService aliasService = null;
+
+  @Override
+  public void init( FilterConfig filterConfig ) throws ServletException {
+    // JWT service
+    final ServletContext context = filterConfig.getServletContext();
+    CryptoService cryptoService = null;
+    String clusterName = null;
+    if (context != null) {
+      GatewayServices services = (GatewayServices) context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+      clusterName = (String) context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE);
+      if (services != null) {
+        keystoreService = (KeystoreService) services.getService(GatewayServices.KEYSTORE_SERVICE);
+        cryptoService = (CryptoService) services.getService(GatewayServices.CRYPTO_SERVICE);
+        aliasService = (AliasService) services.getService(GatewayServices.ALIAS_SERVICE);
+        masterService = (MasterService) services.getService("MasterService");
+      }
+    }
+    // crypto service, alias service and cluster name are mandatory
+    if (cryptoService == null || aliasService == null || clusterName == null) {
+      log.cryptoServiceAndAliasServiceAndClusterNameRequired();
+      throw new ServletException("The crypto service, alias service and cluster name are required.");
+    }
+    try {
+      aliasService.getPasswordFromAliasForCluster(clusterName, KnoxSessionStore.PAC4J_PASSWORD, true);
+    } catch (AliasServiceException e) {
+      log.unableToGenerateAPasswordForEncryption(e);
+      throw new ServletException("Unable to generate a password for encryption.");
+    }
+
+    // url to SSO authentication provider
+    String pac4jCallbackUrl = filterConfig.getInitParameter(PAC4J_CALLBACK_URL);
+    if (pac4jCallbackUrl == null) {
+      log.ssoAuthenticationProviderUrlRequired();
+      throw new ServletException("Required pac4j callback URL is missing.");
+    }
+    // add the callback parameter to know it's a callback
+    pac4jCallbackUrl = CommonHelper.addParameter(pac4jCallbackUrl, PAC4J_CALLBACK_PARAMETER, "true");
+
+    final Config config;
+    final String clientName;
+    // client name from servlet parameter (mandatory)
+    final String clientNameParameter = filterConfig.getInitParameter(Pac4jConstants.CLIENT_NAME);
+    if (clientNameParameter == null) {
+      log.clientNameParameterRequired();
+      throw new ServletException("Required pac4j clientName parameter is missing.");
+    }
+    if (TEST_BASIC_AUTH.equalsIgnoreCase(clientNameParameter)) {
+      // test configuration
+      final IndirectBasicAuthClient indirectBasicAuthClient = new IndirectBasicAuthClient(new SimpleTestUsernamePasswordAuthenticator());
+      indirectBasicAuthClient.setRealmName("Knox TEST");
+      config = new Config(pac4jCallbackUrl, indirectBasicAuthClient);
+      clientName = "IndirectBasicAuthClient";
+    } else {
+      // get clients from the init parameters
+      final Map<String, String> properties = new HashMap<>();
+      final Enumeration<String> names = filterConfig.getInitParameterNames();
+      addDefaultConfig(clientNameParameter, properties);
+      while (names.hasMoreElements()) {
+        final String key = names.nextElement();
+        properties.put(key, filterConfig.getInitParameter(key));
+      }
+      final PropertiesConfigFactory propertiesConfigFactory = new PropertiesConfigFactory(pac4jCallbackUrl, properties);
+      config = propertiesConfigFactory.build();
+      final List<Client> clients = config.getClients().getClients();
+      if (clients == null || clients.size() == 0) {
+        log.atLeastOnePac4jClientMustBeDefined();
+        throw new ServletException("At least one pac4j client must be defined.");
+      }
+      if (CommonHelper.isBlank(clientNameParameter)) {
+        clientName = clients.get(0).getName();
+      } else {
+        clientName = clientNameParameter;
+      }
+    }
+
+    callbackFilter = new CallbackFilter();
+    requiresAuthenticationFilter = new RequiresAuthenticationFilter();
+    requiresAuthenticationFilter.setClientName(clientName);
+    requiresAuthenticationFilter.setConfig(config);
+
+    final String domainSuffix = filterConfig.getInitParameter(PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM);
+    config.setSessionStore(new KnoxSessionStore(cryptoService, clusterName, domainSuffix));
+    ConfigSingleton.setConfig(config);
+  }
+
+  private void addDefaultConfig(String clientNameParameter, Map<String, String> properties) {
+    // add default saml params
+    if (clientNameParameter.contains("SAML2Client")) {
+      properties.put(PropertiesConfigFactory.SAML_KEYSTORE_PATH,
+          keystoreService.getKeystorePath());
+
+      properties.put(PropertiesConfigFactory.SAML_KEYSTORE_PASSWORD,
+          new String(masterService.getMasterSecret()));
+
+      // check for provisioned alias for private key
+      char[] gip = null;
+      try {
+        gip = aliasService.getGatewayIdentityPassphrase();
+      }
+      catch(AliasServiceException ase) {
+        log.noPrivateKeyPasshraseProvisioned(ase);
+      }
+      if (gip != null) {
+        properties.put(PropertiesConfigFactory.SAML_PRIVATE_KEY_PASSWORD,
+            new String(gip));
+      }
+      else {
+        // no alias provisioned then use the master
+        properties.put(PropertiesConfigFactory.SAML_PRIVATE_KEY_PASSWORD,
+            new String(masterService.getMasterSecret()));
+      }
+    }
+  }
+
+  @Override
+  public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+
+    final HttpServletRequest request = (HttpServletRequest) servletRequest;
+    final HttpServletResponse response = (HttpServletResponse) servletResponse;
+    final J2EContext context = new J2EContext(request, response, ConfigSingleton.getConfig().getSessionStore());
+
+    // it's a callback from an identity provider
+    if (request.getParameter(PAC4J_CALLBACK_PARAMETER) != null) {
+      // apply CallbackFilter
+      callbackFilter.doFilter(servletRequest, servletResponse, filterChain);
+    } else {
+      // otherwise just apply security and requires authentication
+      // apply RequiresAuthenticationFilter
+      requiresAuthenticationFilter.doFilter(servletRequest, servletResponse, filterChain);
+    }
+  }
+
+  @Override
+  public void destroy() { }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
new file mode 100644
index 0000000..87d0e8e
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
@@ -0,0 +1,138 @@
+/**
+ * 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.pac4j.filter;
+
+import org.apache.hadoop.gateway.audit.api.*;
+import org.apache.knox.gateway.audit.api.Action;
+import org.apache.knox.gateway.audit.api.ActionOutcome;
+import org.apache.knox.gateway.audit.api.Auditor;
+import org.apache.knox.gateway.audit.api.ResourceType;
+import org.apache.knox.gateway.audit.log4j.audit.AuditConstants;
+import org.apache.knox.gateway.filter.AbstractGatewayFilter;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.apache.knox.gateway.audit.api.AuditService;
+import org.apache.knox.gateway.audit.api.AuditServiceFactory;
+import org.pac4j.core.config.ConfigSingleton;
+import org.pac4j.core.context.J2EContext;
+import org.pac4j.core.profile.ProfileManager;
+import org.pac4j.core.profile.UserProfile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.Subject;
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * <p>This filter retrieves the authenticated user saved by the pac4j provider and injects it into the J2E HTTP request.</p>
+ *
+ * @since 0.8.0
+ */
+public class Pac4jIdentityAdapter implements Filter {
+
+  private static final Logger logger = LoggerFactory.getLogger(Pac4jIdentityAdapter.class);
+
+  private static AuditService auditService = AuditServiceFactory.getAuditService();
+  private static Auditor auditor = auditService.getAuditor(
+      AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
+      AuditConstants.KNOX_COMPONENT_NAME );
+
+  private String testIdentifier;
+
+  @Override
+  public void init( FilterConfig filterConfig ) throws ServletException {
+  }
+
+  public void destroy() {
+  }
+
+  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
+      throws IOException, ServletException {
+
+    final HttpServletRequest request = (HttpServletRequest) servletRequest;
+    final HttpServletResponse response = (HttpServletResponse) servletResponse;
+    final J2EContext context = new J2EContext(request, response, ConfigSingleton.getConfig().getSessionStore());
+    final ProfileManager manager = new ProfileManager(context);
+    final UserProfile profile = manager.get(true);
+    logger.debug("User authenticated as: {}", profile);
+    manager.remove(true);
+    final String id = profile.getId();
+    testIdentifier = id;
+    PrimaryPrincipal pp = new PrimaryPrincipal(id);
+    Subject subject = new Subject();
+    subject.getPrincipals().add(pp);
+    auditService.getContext().setUsername(id);
+    String sourceUri = (String)request.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
+    auditor.audit(Action.AUTHENTICATION, sourceUri, ResourceType.URI, ActionOutcome.SUCCESS);
+    
+    doAs(request, response, chain, subject);
+  }
+  
+  private void doAs(final ServletRequest request,
+      final ServletResponse response, final FilterChain chain, Subject subject)
+      throws IOException, ServletException {
+    try {
+      Subject.doAs(
+          subject,
+          new PrivilegedExceptionAction<Object>() {
+            public Object run() throws Exception {
+              chain.doFilter(request, response);
+              return null;
+            }
+          }
+          );
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+  }
+
+  /**
+   * For tests only.
+   */
+  public static void setAuditService(AuditService auditService) {
+    Pac4jIdentityAdapter.auditService = auditService;
+  }
+
+  /**
+   * For tests only.
+   */
+  public static void setAuditor(Auditor auditor) {
+    Pac4jIdentityAdapter.auditor = auditor;
+  }
+
+  /**
+   * For tests only.
+     */
+  public String getTestIdentifier() {
+    return testIdentifier;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
new file mode 100644
index 0000000..6ce002c
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/session/KnoxSessionStore.java
@@ -0,0 +1,120 @@
+/**
+ * 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.pac4j.session;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.knox.gateway.services.security.CryptoService;
+import org.apache.knox.gateway.services.security.EncryptionResult;
+import org.apache.knox.gateway.util.Urls;
+import org.pac4j.core.context.ContextHelper;
+import org.pac4j.core.context.Cookie;
+import org.pac4j.core.context.WebContext;
+import org.pac4j.core.context.session.SessionStore;
+import org.pac4j.core.exception.TechnicalException;
+import org.pac4j.core.util.JavaSerializationHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+
+/**
+ * Specific session store where data are saved into cookies (and not in memory).
+ * Each data is encrypted and base64 encoded before being saved as a cookie (for security reasons).
+ *
+ * @since 0.8.0
+ */
+public class KnoxSessionStore implements SessionStore {
+
+    private static final Logger logger = LoggerFactory.getLogger(KnoxSessionStore.class);
+
+    public static final String PAC4J_PASSWORD = "pac4j.password";
+
+    public static final String PAC4J_SESSION_PREFIX = "pac4j.session.";
+
+    private final JavaSerializationHelper javaSerializationHelper;
+
+    private final CryptoService cryptoService;
+
+    private final String clusterName;
+
+    private final String domainSuffix;
+
+    public KnoxSessionStore(final CryptoService cryptoService, final String clusterName, final String domainSuffix) {
+        javaSerializationHelper = new JavaSerializationHelper();
+        this.cryptoService = cryptoService;
+        this.clusterName = clusterName;
+        this.domainSuffix = domainSuffix;
+    }
+
+    public String getOrCreateSessionId(WebContext context) {
+        return null;
+    }
+
+    private Serializable decryptBase64(final String v) {
+        if (v != null && v.length() > 0) {
+            byte[] bytes = Base64.decodeBase64(v);
+            EncryptionResult result = EncryptionResult.fromByteArray(bytes);
+            byte[] clear = cryptoService.decryptForCluster(this.clusterName,
+                    PAC4J_PASSWORD,
+                    result.cipher,
+                    result.iv,
+                    result.salt);
+            if (clear != null) {
+                return javaSerializationHelper.unserializeFromBytes(clear);
+            }
+        }
+        return null;
+    }
+
+    public Object get(WebContext context, String key) {
+        final Cookie cookie = ContextHelper.getCookie(context, PAC4J_SESSION_PREFIX + key);
+        Object value = null;
+        if (cookie != null) {
+            value = decryptBase64(cookie.getValue());
+        }
+        logger.debug("Get from session: {} = {}", key, value);
+        return value;
+    }
+
+    private String encryptBase64(final Object o) {
+        if (o == null || o.equals("")) {
+            return null;
+        } else {
+            final byte[] bytes = javaSerializationHelper.serializeToBytes((Serializable) o);
+            EncryptionResult result = cryptoService.encryptForCluster(this.clusterName, PAC4J_PASSWORD, bytes);
+            return Base64.encodeBase64String(result.toByteAray());
+        }
+    }
+
+    public void set(WebContext context, String key, Object value) {
+        logger.debug("Save in session: {} = {}", key, value);
+        final Cookie cookie = new Cookie(PAC4J_SESSION_PREFIX + key, encryptBase64(value));
+        try {
+            String domain = Urls.getDomainName(context.getFullRequestURL(), this.domainSuffix);
+            if (domain == null) {
+                domain = context.getServerName();
+            }
+            cookie.setDomain(domain);
+        } catch (final Exception e) {
+            throw new TechnicalException(e);
+        }
+        cookie.setHttpOnly(true);
+        cookie.setSecure(ContextHelper.isHttpsOrSecure(context));
+        context.addResponseCookie(cookie);
+    }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
deleted file mode 100644
index 8cde74f..0000000
--- a/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.hadoop.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.hadoop.gateway.pac4j.deploy.Pac4jFederationProviderContributor

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..a195d77
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# 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.pac4j.deploy.Pac4jFederationProviderContributor

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletRequest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletRequest.java b/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletRequest.java
deleted file mode 100644
index b09adc9..0000000
--- a/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletRequest.java
+++ /dev/null
@@ -1,88 +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.hadoop.gateway.pac4j;
-
-import javax.servlet.http.*;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.mockito.Mockito.*;
-
-public class MockHttpServletRequest extends HttpServletRequestWrapper {
-
-    private String requestUrl;
-    private Cookie[] cookies;
-    private String serverName;
-    private Map<String, String> parameters = new HashMap<>();
-    private Map<String, String> headers = new HashMap<>();
-
-    public MockHttpServletRequest() {
-        super(mock(HttpServletRequest.class));
-    }
-
-    @Override
-    public Cookie[] getCookies() {
-        return cookies;
-    }
-
-    public void setCookies(final Cookie[] cookies) {
-        this.cookies = cookies;
-    }
-
-    @Override
-    public StringBuffer getRequestURL() {
-        return new StringBuffer(requestUrl);
-    }
-
-    public void setRequestURL(final String requestUrl) {
-        this.requestUrl = requestUrl;
-    }
-
-    @Override
-    public String getServerName() {
-        return serverName;
-    }
-
-    public void setServerName(final String serverName) {
-        this.serverName = serverName;
-    }
-
-    @Override
-    public String getParameter(String name) {
-        return parameters.get(name);
-    }
-
-    public void addParameter(String key, String value) {
-        parameters.put(key, value);
-    }
-
-    @Override
-    public String getHeader(String name) {
-        return headers.get(name);
-    }
-
-    public void addHeader(String key, String value) {
-        headers.put(key, value);
-    }
-
-    @Override
-    public Object getAttribute(String name) {
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletResponse.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletResponse.java b/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletResponse.java
deleted file mode 100644
index 11d104c..0000000
--- a/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/MockHttpServletResponse.java
+++ /dev/null
@@ -1,82 +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.hadoop.gateway.pac4j;
-
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.mockito.Mockito.*;
-
-public class MockHttpServletResponse extends HttpServletResponseWrapper {
-
-    private List<Cookie> cookies = new ArrayList<>();
-    private String location;
-    private int status = 0;
-    private Map<String, String> headers = new HashMap<>();
-
-    public MockHttpServletResponse() {
-        super(mock(HttpServletResponse.class));
-    }
-
-    @Override
-    public void setHeader(String name, String value) {
-        headers.put(name, value);
-    }
-
-    @Override
-    public void addHeader(String name, String value) {
-        headers.put(name, value);
-    }
-
-    public Map<String, String> getHeaders() {
-        return headers;
-    }
-
-    @Override
-    public void addCookie(Cookie cookie) {
-        cookies.add(cookie);
-    }
-
-    public List<Cookie> getCookies() {
-        return cookies;
-    }
-
-    @Override
-    public void sendRedirect(String location) throws IOException {
-        setStatus(302);
-        setHeader("Location", location);
-    }
-
-    @Override
-    public void setStatus(int sc) {
-        status = sc;
-    }
-
-    @Override
-    public int getStatus() {
-        return status;
-    }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/Pac4jProviderTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/Pac4jProviderTest.java b/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/Pac4jProviderTest.java
deleted file mode 100644
index 60bf6f8..0000000
--- a/gateway-provider-security-pac4j/src/test/java/org/apache/hadoop/gateway/pac4j/Pac4jProviderTest.java
+++ /dev/null
@@ -1,150 +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.hadoop.gateway.pac4j;
-
-import org.apache.hadoop.gateway.audit.api.AuditContext;
-import org.apache.hadoop.gateway.audit.api.AuditService;
-import org.apache.hadoop.gateway.audit.api.Auditor;
-import org.apache.hadoop.gateway.pac4j.filter.Pac4jDispatcherFilter;
-import org.apache.hadoop.gateway.pac4j.filter.Pac4jIdentityAdapter;
-import org.apache.hadoop.gateway.pac4j.session.KnoxSessionStore;
-import org.apache.hadoop.gateway.services.GatewayServices;
-import org.apache.hadoop.gateway.services.security.AliasService;
-import org.apache.hadoop.gateway.services.security.impl.DefaultCryptoService;
-import org.junit.Test;
-import org.pac4j.core.client.Clients;
-import org.pac4j.core.context.Pac4jConstants;
-import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.mockito.Mockito.*;
-import static org.junit.Assert.*;
-
-/**
- * This class simulates a full authentication process using pac4j.
- */
-public class Pac4jProviderTest {
-
-    private static final String LOCALHOST = "127.0.0.1";
-    private static final String HADOOP_SERVICE_URL = "https://" + LOCALHOST + ":8443/gateway/sandox/webhdfs/v1/tmp?op=LISTSTATUS";
-    private static final String KNOXSSO_SERVICE_URL = "https://" + LOCALHOST + ":8443/gateway/idp/api/v1/websso";
-    private static final String PAC4J_CALLBACK_URL = KNOXSSO_SERVICE_URL;
-    private static final String ORIGINAL_URL = "originalUrl";
-    private static final String CLUSTER_NAME = "knox";
-    private static final String PAC4J_PASSWORD = "pwdfortest";
-    private static final String CLIENT_CLASS = IndirectBasicAuthClient.class.getSimpleName();
-    private static final String USERNAME = "jleleu";
-
-    @Test
-    public void test() throws Exception {
-        final AliasService aliasService = mock(AliasService.class);
-        when(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, KnoxSessionStore.PAC4J_PASSWORD, true)).thenReturn(PAC4J_PASSWORD.toCharArray());
-        when(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, KnoxSessionStore.PAC4J_PASSWORD)).thenReturn(PAC4J_PASSWORD.toCharArray());
-
-        final DefaultCryptoService cryptoService = new DefaultCryptoService();
-        cryptoService.setAliasService(aliasService);
-
-        final GatewayServices services = mock(GatewayServices.class);
-        when(services.getService(GatewayServices.CRYPTO_SERVICE)).thenReturn(cryptoService);
-        when(services.getService(GatewayServices.ALIAS_SERVICE)).thenReturn(aliasService);
-
-        final ServletContext context = mock(ServletContext.class);
-        when(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).thenReturn(services);
-        when(context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE)).thenReturn(CLUSTER_NAME);
-
-        final FilterConfig config = mock(FilterConfig.class);
-        when(config.getServletContext()).thenReturn(context);
-        when(config.getInitParameter(Pac4jDispatcherFilter.PAC4J_CALLBACK_URL)).thenReturn(PAC4J_CALLBACK_URL);
-        when(config.getInitParameter(Pac4jConstants.CLIENT_NAME)).thenReturn(Pac4jDispatcherFilter.TEST_BASIC_AUTH);
-
-        final Pac4jDispatcherFilter dispatcher = new Pac4jDispatcherFilter();
-        dispatcher.init(config);
-        final Pac4jIdentityAdapter adapter = new Pac4jIdentityAdapter();
-        adapter.init(config);
-        adapter.setAuditor(mock(Auditor.class));
-        final AuditService auditService = mock(AuditService.class);
-        when(auditService.getContext()).thenReturn(mock(AuditContext.class));
-        adapter.setAuditService(auditService);
-
-        // step 1: call the KnoxSSO service with an original url pointing to an Hadoop service (redirected by the SSOCookieProvider)
-        MockHttpServletRequest request = new MockHttpServletRequest();
-        request.setRequestURL(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL);
-        request.setCookies(new Cookie[0]);
-        request.setServerName(LOCALHOST);
-        MockHttpServletResponse response = new MockHttpServletResponse();
-        FilterChain filterChain = mock(FilterChain.class);
-        dispatcher.doFilter(request, response, filterChain);
-        // it should be a redirection to the idp topology
-        assertEquals(302, response.getStatus());
-        assertEquals(PAC4J_CALLBACK_URL + "?" + Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER + "=true&" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS, response.getHeaders().get("Location"));
-        // we should have one cookie for the saved requested url
-        List<Cookie> cookies = response.getCookies();
-        assertEquals(1, cookies.size());
-        final Cookie requestedUrlCookie = cookies.get(0);
-        assertEquals(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.REQUESTED_URL, requestedUrlCookie.getName());
-
-        // step 2: send credentials to the callback url (callback from the identity provider)
-        request = new MockHttpServletRequest();
-        request.setCookies(new Cookie[]{requestedUrlCookie});
-        request.setRequestURL(PAC4J_CALLBACK_URL + "?" + Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER + "=true&" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS);
-        request.addParameter(Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER, "true");
-        request.addParameter(Clients.DEFAULT_CLIENT_NAME_PARAMETER, CLIENT_CLASS);
-        request.addHeader("Authorization", "Basic amxlbGV1OmpsZWxldQ==");
-        request.setServerName(LOCALHOST);
-        response = new MockHttpServletResponse();
-        filterChain = mock(FilterChain.class);
-        dispatcher.doFilter(request, response, filterChain);
-        // it should be a redirection to the original url
-        assertEquals(302, response.getStatus());
-        assertEquals(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL, response.getHeaders().get("Location"));
-        // we should have 3 cookies among with the user profile
-        cookies = response.getCookies();
-        Map<String, String> mapCookies = new HashMap<>();
-        assertEquals(3, cookies.size());
-        for (final Cookie cookie : cookies) {
-            mapCookies.put(cookie.getName(), cookie.getValue());
-        }
-        assertNull(mapCookies.get(KnoxSessionStore.PAC4J_SESSION_PREFIX + CLIENT_CLASS + "$attemptedAuthentication"));
-        assertNotNull(mapCookies.get(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.USER_PROFILE));
-        assertNull(mapCookies.get(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.REQUESTED_URL));
-
-        // step 3: turn pac4j identity into KnoxSSO identity
-        request = new MockHttpServletRequest();
-        request.setCookies(cookies.toArray(new Cookie[cookies.size()]));
-        request.setRequestURL(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL);
-        request.setServerName(LOCALHOST);
-        response = new MockHttpServletResponse();
-        filterChain = mock(FilterChain.class);
-        dispatcher.doFilter(request, response, filterChain);
-        assertEquals(0, response.getStatus());
-        adapter.doFilter(request, response, filterChain);
-        cookies = response.getCookies();
-        assertEquals(1, cookies.size());
-        final Cookie userProfileCookie = cookies.get(0);
-        // the user profile has been cleaned
-        assertEquals(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.USER_PROFILE, userProfileCookie.getName());
-        assertNull(userProfileCookie.getValue());
-        assertEquals(USERNAME, adapter.getTestIdentifier());
-    }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
new file mode 100644
index 0000000..7a3a833
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
@@ -0,0 +1,88 @@
+/**
+ * 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.pac4j;
+
+import javax.servlet.http.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.Mockito.*;
+
+public class MockHttpServletRequest extends HttpServletRequestWrapper {
+
+    private String requestUrl;
+    private Cookie[] cookies;
+    private String serverName;
+    private Map<String, String> parameters = new HashMap<>();
+    private Map<String, String> headers = new HashMap<>();
+
+    public MockHttpServletRequest() {
+        super(mock(HttpServletRequest.class));
+    }
+
+    @Override
+    public Cookie[] getCookies() {
+        return cookies;
+    }
+
+    public void setCookies(final Cookie[] cookies) {
+        this.cookies = cookies;
+    }
+
+    @Override
+    public StringBuffer getRequestURL() {
+        return new StringBuffer(requestUrl);
+    }
+
+    public void setRequestURL(final String requestUrl) {
+        this.requestUrl = requestUrl;
+    }
+
+    @Override
+    public String getServerName() {
+        return serverName;
+    }
+
+    public void setServerName(final String serverName) {
+        this.serverName = serverName;
+    }
+
+    @Override
+    public String getParameter(String name) {
+        return parameters.get(name);
+    }
+
+    public void addParameter(String key, String value) {
+        parameters.put(key, value);
+    }
+
+    @Override
+    public String getHeader(String name) {
+        return headers.get(name);
+    }
+
+    public void addHeader(String key, String value) {
+        headers.put(key, value);
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletResponse.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletResponse.java b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletResponse.java
new file mode 100644
index 0000000..07dd255
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletResponse.java
@@ -0,0 +1,82 @@
+/**
+ * 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.pac4j;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.*;
+
+public class MockHttpServletResponse extends HttpServletResponseWrapper {
+
+    private List<Cookie> cookies = new ArrayList<>();
+    private String location;
+    private int status = 0;
+    private Map<String, String> headers = new HashMap<>();
+
+    public MockHttpServletResponse() {
+        super(mock(HttpServletResponse.class));
+    }
+
+    @Override
+    public void setHeader(String name, String value) {
+        headers.put(name, value);
+    }
+
+    @Override
+    public void addHeader(String name, String value) {
+        headers.put(name, value);
+    }
+
+    public Map<String, String> getHeaders() {
+        return headers;
+    }
+
+    @Override
+    public void addCookie(Cookie cookie) {
+        cookies.add(cookie);
+    }
+
+    public List<Cookie> getCookies() {
+        return cookies;
+    }
+
+    @Override
+    public void sendRedirect(String location) throws IOException {
+        setStatus(302);
+        setHeader("Location", location);
+    }
+
+    @Override
+    public void setStatus(int sc) {
+        status = sc;
+    }
+
+    @Override
+    public int getStatus() {
+        return status;
+    }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..606d042
--- /dev/null
+++ b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/Pac4jProviderTest.java
@@ -0,0 +1,150 @@
+/**
+ * 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.pac4j;
+
+import org.apache.knox.gateway.audit.api.AuditContext;
+import org.apache.knox.gateway.audit.api.AuditService;
+import org.apache.knox.gateway.audit.api.Auditor;
+import org.apache.knox.gateway.pac4j.filter.Pac4jDispatcherFilter;
+import org.apache.knox.gateway.pac4j.filter.Pac4jIdentityAdapter;
+import org.apache.knox.gateway.pac4j.session.KnoxSessionStore;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
+import org.junit.Test;
+import org.pac4j.core.client.Clients;
+import org.pac4j.core.context.Pac4jConstants;
+import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.*;
+import static org.junit.Assert.*;
+
+/**
+ * This class simulates a full authentication process using pac4j.
+ */
+public class Pac4jProviderTest {
+
+    private static final String LOCALHOST = "127.0.0.1";
+    private static final String HADOOP_SERVICE_URL = "https://" + LOCALHOST + ":8443/gateway/sandox/webhdfs/v1/tmp?op=LISTSTATUS";
+    private static final String KNOXSSO_SERVICE_URL = "https://" + LOCALHOST + ":8443/gateway/idp/api/v1/websso";
+    private static final String PAC4J_CALLBACK_URL = KNOXSSO_SERVICE_URL;
+    private static final String ORIGINAL_URL = "originalUrl";
+    private static final String CLUSTER_NAME = "knox";
+    private static final String PAC4J_PASSWORD = "pwdfortest";
+    private static final String CLIENT_CLASS = IndirectBasicAuthClient.class.getSimpleName();
+    private static final String USERNAME = "jleleu";
+
+    @Test
+    public void test() throws Exception {
+        final AliasService aliasService = mock(AliasService.class);
+        when(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, KnoxSessionStore.PAC4J_PASSWORD, true)).thenReturn(PAC4J_PASSWORD.toCharArray());
+        when(aliasService.getPasswordFromAliasForCluster(CLUSTER_NAME, KnoxSessionStore.PAC4J_PASSWORD)).thenReturn(PAC4J_PASSWORD.toCharArray());
+
+        final DefaultCryptoService cryptoService = new DefaultCryptoService();
+        cryptoService.setAliasService(aliasService);
+
+        final GatewayServices services = mock(GatewayServices.class);
+        when(services.getService(GatewayServices.CRYPTO_SERVICE)).thenReturn(cryptoService);
+        when(services.getService(GatewayServices.ALIAS_SERVICE)).thenReturn(aliasService);
+
+        final ServletContext context = mock(ServletContext.class);
+        when(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).thenReturn(services);
+        when(context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE)).thenReturn(CLUSTER_NAME);
+
+        final FilterConfig config = mock(FilterConfig.class);
+        when(config.getServletContext()).thenReturn(context);
+        when(config.getInitParameter(Pac4jDispatcherFilter.PAC4J_CALLBACK_URL)).thenReturn(PAC4J_CALLBACK_URL);
+        when(config.getInitParameter(Pac4jConstants.CLIENT_NAME)).thenReturn(Pac4jDispatcherFilter.TEST_BASIC_AUTH);
+
+        final Pac4jDispatcherFilter dispatcher = new Pac4jDispatcherFilter();
+        dispatcher.init(config);
+        final Pac4jIdentityAdapter adapter = new Pac4jIdentityAdapter();
+        adapter.init(config);
+        adapter.setAuditor(mock(Auditor.class));
+        final AuditService auditService = mock(AuditService.class);
+        when(auditService.getContext()).thenReturn(mock(AuditContext.class));
+        adapter.setAuditService(auditService);
+
+        // step 1: call the KnoxSSO service with an original url pointing to an Hadoop service (redirected by the SSOCookieProvider)
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setRequestURL(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL);
+        request.setCookies(new Cookie[0]);
+        request.setServerName(LOCALHOST);
+        MockHttpServletResponse response = new MockHttpServletResponse();
+        FilterChain filterChain = mock(FilterChain.class);
+        dispatcher.doFilter(request, response, filterChain);
+        // it should be a redirection to the idp topology
+        assertEquals(302, response.getStatus());
+        assertEquals(PAC4J_CALLBACK_URL + "?" + Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER + "=true&" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS, response.getHeaders().get("Location"));
+        // we should have one cookie for the saved requested url
+        List<Cookie> cookies = response.getCookies();
+        assertEquals(1, cookies.size());
+        final Cookie requestedUrlCookie = cookies.get(0);
+        assertEquals(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.REQUESTED_URL, requestedUrlCookie.getName());
+
+        // step 2: send credentials to the callback url (callback from the identity provider)
+        request = new MockHttpServletRequest();
+        request.setCookies(new Cookie[]{requestedUrlCookie});
+        request.setRequestURL(PAC4J_CALLBACK_URL + "?" + Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER + "=true&" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS);
+        request.addParameter(Pac4jDispatcherFilter.PAC4J_CALLBACK_PARAMETER, "true");
+        request.addParameter(Clients.DEFAULT_CLIENT_NAME_PARAMETER, CLIENT_CLASS);
+        request.addHeader("Authorization", "Basic amxlbGV1OmpsZWxldQ==");
+        request.setServerName(LOCALHOST);
+        response = new MockHttpServletResponse();
+        filterChain = mock(FilterChain.class);
+        dispatcher.doFilter(request, response, filterChain);
+        // it should be a redirection to the original url
+        assertEquals(302, response.getStatus());
+        assertEquals(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL, response.getHeaders().get("Location"));
+        // we should have 3 cookies among with the user profile
+        cookies = response.getCookies();
+        Map<String, String> mapCookies = new HashMap<>();
+        assertEquals(3, cookies.size());
+        for (final Cookie cookie : cookies) {
+            mapCookies.put(cookie.getName(), cookie.getValue());
+        }
+        assertNull(mapCookies.get(KnoxSessionStore.PAC4J_SESSION_PREFIX + CLIENT_CLASS + "$attemptedAuthentication"));
+        assertNotNull(mapCookies.get(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.USER_PROFILE));
+        assertNull(mapCookies.get(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.REQUESTED_URL));
+
+        // step 3: turn pac4j identity into KnoxSSO identity
+        request = new MockHttpServletRequest();
+        request.setCookies(cookies.toArray(new Cookie[cookies.size()]));
+        request.setRequestURL(KNOXSSO_SERVICE_URL + "?" + ORIGINAL_URL + "=" + HADOOP_SERVICE_URL);
+        request.setServerName(LOCALHOST);
+        response = new MockHttpServletResponse();
+        filterChain = mock(FilterChain.class);
+        dispatcher.doFilter(request, response, filterChain);
+        assertEquals(0, response.getStatus());
+        adapter.doFilter(request, response, filterChain);
+        cookies = response.getCookies();
+        assertEquals(1, cookies.size());
+        final Cookie userProfileCookie = cookies.get(0);
+        // the user profile has been cleaned
+        assertEquals(KnoxSessionStore.PAC4J_SESSION_PREFIX + Pac4jConstants.USER_PROFILE, userProfileCookie.getName());
+        assertNull(userProfileCookie.getValue());
+        assertEquals(USERNAME, adapter.getTestIdentifier());
+    }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/PicketlinkMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/PicketlinkMessages.java b/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/PicketlinkMessages.java
deleted file mode 100644
index c49030f..0000000
--- a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/PicketlinkMessages.java
+++ /dev/null
@@ -1,40 +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.hadoop.gateway.picketlink;
-
-import org.apache.hadoop.gateway.i18n.messages.Message;
-import org.apache.hadoop.gateway.i18n.messages.MessageLevel;
-import org.apache.hadoop.gateway.i18n.messages.Messages;
-import org.apache.hadoop.gateway.i18n.messages.StackTrace;
-
-@Messages(logger="org.apache.hadoop.gateway.picketlink")
-public interface PicketlinkMessages {
-
-  @Message( level = MessageLevel.DEBUG, text = "Found Original URL in reequest: {0}")
-  public void foundOriginalURLInRequest(String url);
-
-  @Message( level = MessageLevel.DEBUG, text = "setting cookie for original-url")
-  public void settingCookieForOriginalURL();
-
-  @Message( level = MessageLevel.DEBUG, text = "Secure Flag is set to False for cookie")
-  public void secureFlagFalseForCookie();
-
-  @Message( level = MessageLevel.ERROR, text = "Unable to get the gateway identity passphrase: {0}")
-  public void unableToGetGatewayIdentityPassphrase(@StackTrace( level = MessageLevel.DEBUG) Exception e);
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkConf.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkConf.java b/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkConf.java
deleted file mode 100644
index 59203c6..0000000
--- a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkConf.java
+++ /dev/null
@@ -1,194 +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.hadoop.gateway.picketlink.deploy;
-
-/**
- * Provides a serializable configuration file for adding to
- * the webapp as an XML string for picketlink.xml
- *
- */
-public class PicketlinkConf {
-  public static final String INDENT = "    ";
-  public static final String LT_OPEN = "<";
-  public static final String LT_CLOSE = "</";
-  public static final String GT = ">";
-  public static final String GT_CLOSE = "/>";
-  public static final String NL = "\n";
-  public static final String PICKETLINK_XMLNS = "urn:picketlink:identity-federation:config:2.1";
-  public static final String PICKETLINK_SP_XMLNS = "urn:picketlink:identity-federation:config:1.0";
-  public static final String C14N_METHOD = "http://www.w3.org/2001/10/xml-exc-c14n#";
-  public static final String KEYPROVIDER_ELEMENT = "KeyProvider";
-  public static final String KEYPROVIDER_CLASSNAME = "org.picketlink.identity.federation.core.impl.KeyStoreKeyManager";
-  public static final String AUTH_HANDLER_CLASSNAME = "org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler";
-  public static final String ROLE_GEN_HANDLER_CLASSNAME = "org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler";
-  public static final String PICKETLINK_ELEMENT = "PicketLink";
-  public static final String PICKETLINKSP_ELEMENT = "PicketLinkSP";
-  public static final String HANDLERS_ELEMENT = "Handlers";
-  public static final String HANDLER_ELEMENT = "Handler";
-  public static final String OPTION_ELEMENT = "Option";
-  public static final String VAL_ALIAS_ELEMENT = "ValidatingAlias";
-  public static final String AUTH_ELEMENT = "Auth";
-
-  private String serverEnvironment = "jetty";
-  private String bindingType = "POST";
-  private String idpUsesPostingBinding = "true";
-  private String supportsSignatures = "true";
-  private String identityURL = null;
-  private String serviceURL = null;
-  private String keystoreURL = null;
-  private String keystorePass = null;
-  private String signingKeyAlias = null;
-  private String signingKeyPass = null;
-  private String validatingKeyAlias = null;
-  private String validatingKeyValue = null;
-  private String nameIDFormat = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent";
-  private String clockSkewMilis = null;
-  private String assertionSessionAttributeName = "org.picketlink.sp.assertion";
-  
-  public String getServerEnvironment() {
-    return serverEnvironment;
-  }
-  public void setServerEnvironment(String serverEnvironment) {
-    this.serverEnvironment = serverEnvironment;
-  }
-  public String getBindingType() {
-    return bindingType;
-  }
-  public void setBindingType(String bindingType) {
-    this.bindingType = bindingType;
-  }
-  public String getIdpUsesPostingBinding() {
-    return idpUsesPostingBinding;
-  }
-  public void setIdpUsesPostingBinding(String idpUsesPostingBinding) {
-    this.idpUsesPostingBinding = idpUsesPostingBinding;
-  }
-  public String getSupportsSignatures() {
-    return supportsSignatures;
-  }
-  public void setSupportsSignatures(String supportsSignatures) {
-    this.supportsSignatures = supportsSignatures;
-  }
-  public String getIdentityURL() {
-    return identityURL;
-  }
-  public void setIdentityURL(String identityURL) {
-    this.identityURL = identityURL;
-  }
-  public String getServiceURL() {
-    return serviceURL;
-  }
-  public void setServiceURL(String serviceURL) {
-    this.serviceURL = serviceURL;
-  }
-  public String getKeystoreURL() {
-    return keystoreURL;
-  }
-  public void setKeystoreURL(String keystoreURL) {
-    this.keystoreURL = keystoreURL;
-  }
-  public String getKeystorePass() {
-    return keystorePass;
-  }
-  public void setKeystorePass(String keystorePass) {
-    this.keystorePass = keystorePass;
-  }
-  public String getSigningKeyAlias() {
-    return signingKeyAlias;
-  }
-  public void setSigningKeyAlias(String signingKeyAlias) {
-    this.signingKeyAlias = signingKeyAlias;
-  }
-  public String getSigningKeyPass() {
-    return signingKeyPass;
-  }
-  public void setSigningKeyPass(String signingKeyPass) {
-    this.signingKeyPass = signingKeyPass;
-  }
-  public String getValidatingKeyAlias() {
-    return validatingKeyAlias;
-  }
-  public void setValidatingAliasKey(String validatingKeyAlias) {
-    this.validatingKeyAlias = validatingKeyAlias;
-  }
-  public String getValidatingKeyValue() {
-    return validatingKeyValue;
-  }
-  public void setValidatingAliasValue(String validatingKeyValue) {
-    this.validatingKeyValue = validatingKeyValue;
-  }
-  public String getNameIDFormat() {
-    return nameIDFormat;
-  }
-  public void setNameIDFormat(String nameIDFormat) {
-    this.nameIDFormat = nameIDFormat;
-  }
-  public String getClockSkewMilis() {
-    return clockSkewMilis;
-  }
-  public void setClockSkewMilis(String clockSkewMilis) {
-    this.clockSkewMilis = clockSkewMilis;
-  }
-  public String getAssertionSessionAttributeName() {
-    return assertionSessionAttributeName;
-  }
-  public void setAssertionSessionAttributeName(
-      String assertionSessionAttributeName) {
-    this.assertionSessionAttributeName = assertionSessionAttributeName;
-  }
-  @Override
-  public String toString() {
-    // THIS IS HORRID REPLACE WITH DOM+TRANSFORM
-    StringBuffer xml = new StringBuffer();
-    xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>").append(NL)
-    .append(LT_OPEN).append(PICKETLINK_ELEMENT).append(" xmlns=\"").append(PICKETLINK_XMLNS).append("\"" + GT).append(NL)
-      .append(INDENT).append(LT_OPEN).append(PICKETLINKSP_ELEMENT).append(" xmlns=\"").append(PICKETLINK_SP_XMLNS + "\"").append(NL)
-      .append(INDENT).append(INDENT).append("ServerEnvironment").append("=\"").append(serverEnvironment).append("\"").append(NL)
-      .append(INDENT).append(INDENT).append("BindingType").append("=\"").append(bindingType).append("\"").append(NL)
-      .append(INDENT).append(INDENT).append("IDPUsesPostBinding").append("=\"").append(idpUsesPostingBinding).append("\"").append(NL)
-      .append(INDENT).append(INDENT).append("SupportsSignatures").append("=\"").append(supportsSignatures).append("\"").append(NL)
-      .append(INDENT).append(INDENT).append("CanonicalizationMethod").append("=\"").append(C14N_METHOD).append("\"").append(GT).append(NL).append(NL)
-      .append(INDENT).append(INDENT).append(LT_OPEN).append("IdentityURL").append(GT).append(identityURL).append(LT_CLOSE).append("IdentityURL").append(GT).append(NL)
-      .append(INDENT).append(INDENT).append(LT_OPEN).append("ServiceURL").append(GT).append(serviceURL).append(LT_CLOSE).append("ServiceURL").append(GT).append(NL)
-      .append(INDENT).append(INDENT).append(LT_OPEN).append(KEYPROVIDER_ELEMENT).append(" ").append("ClassName=\"").append(KEYPROVIDER_CLASSNAME + "\"" + GT).append(NL)
-        .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(AUTH_ELEMENT).append(" Key=\"KeyStoreURL\" Value=\"").append(keystoreURL).append("\"").append(GT_CLOSE).append(NL)
-        .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(AUTH_ELEMENT).append(" Key=\"KeyStorePass\" Value=\"").append(keystorePass).append("\"").append(GT_CLOSE).append(NL)
-        .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(AUTH_ELEMENT).append(" Key=\"SigningKeyAlias\" Value=\"").append(signingKeyAlias).append("\"").append(GT_CLOSE).append(NL)
-        .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(AUTH_ELEMENT).append(" Key=\"SigningKeyPass\" Value=\"").append(signingKeyPass).append("\"").append(GT_CLOSE).append(NL)
-        .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(VAL_ALIAS_ELEMENT).append(" Key=\"").append(validatingKeyAlias).append("\" Value=\"").append(validatingKeyValue).append("\"").append(GT_CLOSE).append(NL)
-      .append(INDENT).append(INDENT).append(LT_CLOSE).append(KEYPROVIDER_ELEMENT).append(GT).append(NL)
-      .append(INDENT).append(LT_CLOSE).append(PICKETLINKSP_ELEMENT).append(GT).append(NL)
-      .append(INDENT).append(LT_OPEN).append(HANDLERS_ELEMENT).append(GT).append(NL)
-        .append(INDENT).append(INDENT).append(LT_OPEN).append(HANDLER_ELEMENT).append(" class=\"").append(AUTH_HANDLER_CLASSNAME).append("\">").append(NL)
-          .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(OPTION_ELEMENT).append(" Key=\"NAMEID_FORMAT\" Value=\"").append(nameIDFormat).append("\"").append(GT_CLOSE).append(NL)
-          .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(OPTION_ELEMENT).append(" Key=\"CLOCK_SKEW_MILIS\" Value=\"").append(clockSkewMilis).append("\"").append(GT_CLOSE).append(NL)
-          .append(INDENT).append(INDENT).append(INDENT).append(LT_OPEN).append(OPTION_ELEMENT).append(" Key=\"ASSERTION_SESSION_ATTRIBUTE_NAME\" Value=\"").append(assertionSessionAttributeName).append("\"").append(GT_CLOSE).append(NL)
-        .append(INDENT).append(INDENT).append(LT_CLOSE).append(HANDLER_ELEMENT).append(GT).append(NL)
-        .append(INDENT).append(INDENT).append(LT_OPEN).append(HANDLER_ELEMENT).append(" class=\"").append(ROLE_GEN_HANDLER_CLASSNAME).append("\"/>").append(NL)
-      .append(INDENT).append(LT_CLOSE).append(HANDLERS_ELEMENT).append(GT).append(NL)
-    .append(LT_CLOSE).append(PICKETLINK_ELEMENT).append(GT).append(NL);
-     
-    return xml.toString();
-  }
-  
-  public static void main(String[] args) {
-    PicketlinkConf conf = new PicketlinkConf();
-    System.out.println(conf.toString());
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkFederationProviderContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkFederationProviderContributor.java b/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkFederationProviderContributor.java
deleted file mode 100644
index 4f90a41..0000000
--- a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/deploy/PicketlinkFederationProviderContributor.java
+++ /dev/null
@@ -1,132 +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.hadoop.gateway.picketlink.deploy;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.hadoop.gateway.deploy.DeploymentContext;
-import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase;
-import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
-import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
-import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
-import org.apache.hadoop.gateway.picketlink.PicketlinkMessages;
-import org.apache.hadoop.gateway.services.security.AliasService;
-import org.apache.hadoop.gateway.services.security.AliasServiceException;
-import org.apache.hadoop.gateway.services.security.MasterService;
-import org.apache.hadoop.gateway.topology.Provider;
-import org.apache.hadoop.gateway.topology.Service;
-import org.jboss.shrinkwrap.api.asset.StringAsset;
-import org.picketlink.identity.federation.web.filters.ServiceProviderContextInitializer;
-
-public class PicketlinkFederationProviderContributor extends
-    ProviderDeploymentContributorBase {
-  private static final String ROLE = "federation";
-  private static final String NAME = "Picketlink";
-  private static final String PICKETLINK_FILTER_CLASSNAME = "org.picketlink.identity.federation.web.filters.SPFilter";
-  private static final String CAPTURE_URL_FILTER_CLASSNAME = "org.apache.hadoop.gateway.picketlink.filter.CaptureOriginalURLFilter";
-  private static final String IDENTITY_ADAPTER_CLASSNAME = "org.apache.hadoop.gateway.picketlink.filter.PicketlinkIdentityAdapter";
-  private static final String IDENTITY_URL_PARAM = "identity.url";
-  private static final String SERVICE_URL_PARAM = "service.url";
-  private static final String KEYSTORE_URL_PARAM = "keystore.url";
-  private static final String SIGNINGKEY_ALIAS = "gateway-identity";
-  private static final String VALIDATING_ALIAS_KEY = "validating.alias.key";
-  private static final String VALIDATING_ALIAS_VALUE = "validating.alias.value";
-  private static final String CLOCK_SKEW_MILIS = "clock.skew.milis";
-  private static PicketlinkMessages log = MessagesFactory.get( PicketlinkMessages.class );
-
-  private MasterService ms = null;
-  private AliasService as = null;
-
-  @Override
-  public String getRole() {
-    return ROLE;
-  }
-
-  @Override
-  public String getName() {
-    return NAME;
-  }
-  
-  public void setMasterService(MasterService ms) {
-    this.ms = ms;
-  }
-
-  public void setAliasService(AliasService as) {
-    this.as = as;
-  }
-
-  @Override
-  public void initializeContribution(DeploymentContext context) {
-    super.initializeContribution(context);
-  }
-
-  @Override
-  public void contributeProvider(DeploymentContext context, Provider provider) {
-    // LJM TODO: consider creating a picketlink configuration provider to
-    // handle the keystore secrets without putting them in a config file directly.
-    // Once that is done then we can remove the unneeded gateway services from those
-    // that are available to providers.
-    context.getWebAppDescriptor().createListener().listenerClass( ServiceProviderContextInitializer.class.getName());
-
-    PicketlinkConf config = new PicketlinkConf( );
-    Map<String,String> params = provider.getParams();
-    config.setIdentityURL(params.get(IDENTITY_URL_PARAM));
-    config.setServiceURL(params.get(SERVICE_URL_PARAM));
-    config.setKeystoreURL(params.get(KEYSTORE_URL_PARAM));
-    if (ms != null) {
-      config.setKeystorePass(new String(ms.getMasterSecret()));
-    }
-    config.setSigningKeyAlias(SIGNINGKEY_ALIAS);
-    if (as != null) {
-      char[] passphrase = null;
-      try {
-        passphrase = as.getGatewayIdentityPassphrase();
-        config.setSigningKeyPass(new String(passphrase));
-      } catch (AliasServiceException e) {
-        log.unableToGetGatewayIdentityPassphrase(e);
-      }
-    }
-    config.setValidatingAliasKey(params.get(VALIDATING_ALIAS_KEY));
-    config.setValidatingAliasValue(params.get(VALIDATING_ALIAS_VALUE));
-    config.setClockSkewMilis(params.get(CLOCK_SKEW_MILIS));
-    String configStr = config.toString();
-    if( config != null ) {
-      context.getWebArchive().addAsWebInfResource( new StringAsset( configStr ), "picketlink.xml" );
-    }
-  }
-
-  @Override
-  public void contributeFilter(DeploymentContext context, Provider provider, Service service, 
-      ResourceDescriptor resource, List<FilterParamDescriptor> params) {
-    // blindly add all the provider params as filter init params
-    if (params == null) {
-      params = new ArrayList<FilterParamDescriptor>();
-    }
-    Map<String, String> providerParams = provider.getParams();
-    for(Entry<String, String> entry : providerParams.entrySet()) {
-      params.add( resource.createFilterParam().name( entry.getKey().toLowerCase() ).value( entry.getValue() ) );
-    }
-    resource.addFilter().name( getName() ).role( getRole() ).impl( CAPTURE_URL_FILTER_CLASSNAME ).params( params );
-    resource.addFilter().name( getName() ).role( getRole() ).impl( PICKETLINK_FILTER_CLASSNAME ).params( params );
-    resource.addFilter().name( getName() ).role( getRole() ).impl( IDENTITY_ADAPTER_CLASSNAME ).params( params );
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/CaptureOriginalURLFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/CaptureOriginalURLFilter.java b/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/CaptureOriginalURLFilter.java
deleted file mode 100644
index 66da6c4..0000000
--- a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/CaptureOriginalURLFilter.java
+++ /dev/null
@@ -1,89 +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.hadoop.gateway.picketlink.filter;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
-import org.apache.hadoop.gateway.picketlink.PicketlinkMessages;
-
-import java.io.IOException;
-
-public class CaptureOriginalURLFilter implements Filter {
-  private static PicketlinkMessages log = MessagesFactory.get( PicketlinkMessages.class );
-  private static final String COOKIE_PATH = "cookie.path";
-  private static final String COOKIE_SECURE = "cookie.secure";
-  private String cookiePath = null;
-  private String cookieSecure = null;
-
-  @Override
-  public void init( FilterConfig filterConfig ) throws ServletException {
-    cookiePath = filterConfig.getInitParameter(COOKIE_PATH);
-    if (cookiePath == null) {
-      cookiePath = "/gateway/idp/knoxsso/api/v1/websso";
-    }
-    cookieSecure = filterConfig.getInitParameter(COOKIE_SECURE);
-    if (cookieSecure == null) {
-      cookieSecure = "true";
-    }
-  }
-
-  @Override
-  public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain ) throws IOException, ServletException {
-    String original = null;
-    HttpServletRequest request = (HttpServletRequest)servletRequest;
-    String url = request.getParameter("originalUrl");
-    if (url != null) {
-      log.foundOriginalURLInRequest(url);
-      original = request.getParameter("originalUrl");
-      log.settingCookieForOriginalURL();
-      addCookie(servletResponse, original);
-    }
-    filterChain.doFilter(request, servletResponse);
-  }
-
-  @Override
-  public void destroy() {
-
-  }
-
-  private void addCookie(ServletResponse servletResponse, String original) {
-    Cookie c = new Cookie("original-url", original);
-    c.setPath(cookiePath);
-    c.setHttpOnly(true);
-    boolean secureOnly = true;
-    if (cookieSecure != null) {
-      secureOnly = ("false".equals(cookieSecure) ? false : true);
-      if (!secureOnly) {
-        log.secureFlagFalseForCookie();
-      }
-    }
-    c.setSecure(secureOnly);
-    c.setMaxAge(60);
-    ((HttpServletResponse)servletResponse).addCookie(c);
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/PicketlinkIdentityAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/PicketlinkIdentityAdapter.java b/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/PicketlinkIdentityAdapter.java
deleted file mode 100644
index 333f91d..0000000
--- a/gateway-provider-security-picketlink/src/main/java/org/apache/hadoop/gateway/picketlink/filter/PicketlinkIdentityAdapter.java
+++ /dev/null
@@ -1,102 +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.hadoop.gateway.picketlink.filter;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import javax.security.auth.Subject;
-import javax.servlet.Filter;
-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 org.apache.hadoop.gateway.audit.api.Action;
-import org.apache.hadoop.gateway.audit.api.ActionOutcome;
-import org.apache.hadoop.gateway.audit.api.AuditService;
-import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
-import org.apache.hadoop.gateway.audit.api.Auditor;
-import org.apache.hadoop.gateway.audit.api.ResourceType;
-import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
-import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
-import org.apache.hadoop.gateway.security.PrimaryPrincipal;
-
-public class PicketlinkIdentityAdapter implements Filter {
-  
-  private static AuditService auditService = AuditServiceFactory.getAuditService();
-  private static Auditor auditor = auditService.getAuditor(
-      AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
-      AuditConstants.KNOX_COMPONENT_NAME );
-  
-
-  @Override
-  public void init( FilterConfig filterConfig ) throws ServletException {
-  }
-
-  public void destroy() {
-  }
-
-  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
-      throws IOException, ServletException {
-    
-    HttpServletRequest httpRequest = (HttpServletRequest) request;
-    String username = httpRequest.getUserPrincipal().getName();
-    PrimaryPrincipal pp = new PrimaryPrincipal(username);
-    Subject subject = new Subject();
-    subject.getPrincipals().add(pp);
-    
-    Principal principal = (Principal) subject.getPrincipals(PrimaryPrincipal.class);
-    auditService.getContext().setUsername( principal.getName() );
-    String sourceUri = (String)request.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
-    auditor.audit( Action.AUTHENTICATION , sourceUri, ResourceType.URI, ActionOutcome.SUCCESS );
-
-    doAs(request, response, chain, subject);
-  }
-  
-  private void doAs(final ServletRequest request,
-      final ServletResponse response, final FilterChain chain, Subject subject)
-      throws IOException, ServletException {
-    try {
-      Subject.doAs(
-          subject,
-          new PrivilegedExceptionAction<Object>() {
-            public Object run() throws Exception {
-              chain.doFilter(request, response);
-              return null;
-            }
-          }
-          );
-    }
-    catch (PrivilegedActionException e) {
-      Throwable t = e.getCause();
-      if (t instanceof IOException) {
-        throw (IOException) t;
-      }
-      else if (t instanceof ServletException) {
-        throw (ServletException) t;
-      }
-      else {
-        throw new ServletException(t);
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-security-picketlink/src/main/java/org/apache/knox/gateway/picketlink/PicketlinkMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/src/main/java/org/apache/knox/gateway/picketlink/PicketlinkMessages.java b/gateway-provider-security-picketlink/src/main/java/org/apache/knox/gateway/picketlink/PicketlinkMessages.java
new file mode 100644
index 0000000..bcb347c
--- /dev/null
+++ b/gateway-provider-security-picketlink/src/main/java/org/apache/knox/gateway/picketlink/PicketlinkMessages.java
@@ -0,0 +1,40 @@
+/**
+ * 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.picketlink;
+
+import org.apache.knox.gateway.i18n.messages.Message;
+import org.apache.knox.gateway.i18n.messages.MessageLevel;
+import org.apache.knox.gateway.i18n.messages.Messages;
+import org.apache.knox.gateway.i18n.messages.StackTrace;
+
+@Messages(logger="org.apache.hadoop.gateway.picketlink")
+public interface PicketlinkMessages {
+
+  @Message( level = MessageLevel.DEBUG, text = "Found Original URL in reequest: {0}")
+  public void foundOriginalURLInRequest(String url);
+
+  @Message( level = MessageLevel.DEBUG, text = "setting cookie for original-url")
+  public void settingCookieForOriginalURL();
+
+  @Message( level = MessageLevel.DEBUG, text = "Secure Flag is set to False for cookie")
+  public void secureFlagFalseForCookie();
+
+  @Message( level = MessageLevel.ERROR, text = "Unable to get the gateway identity passphrase: {0}")
+  public void unableToGetGatewayIdentityPassphrase(@StackTrace( level = MessageLevel.DEBUG) Exception e);
+
+}