Repository: knox Updated Branches: refs/heads/master e88632142 -> 62c759678
KNOX-655 - Pac4j Provider Client Selection from client_name Query Parameter (Jérôme Leleu via lmccay) Project: http://git-wip-us.apache.org/repos/asf/knox/repo Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/62c75967 Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/62c75967 Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/62c75967 Branch: refs/heads/master Commit: 62c759678df9852e92b0f54edd6ed8d2a99cf6ea Parents: e886321 Author: Larry McCay <lmc...@hortonworks.com> Authored: Tue Jan 26 13:03:16 2016 -0500 Committer: Larry McCay <lmc...@hortonworks.com> Committed: Tue Jan 26 13:03:16 2016 -0500 ---------------------------------------------------------------------- .../pac4j/filter/Pac4jDispatcherFilter.java | 11 +- .../hadoop/gateway/pac4j/Pac4jProviderTest.java | 7 +- .../home/templates/knoxsso-sandbox.xml | 103 +++++++++++++++++++ .../home/templates/pac4j-knoxsso.xml | 92 +++++++++++++++++ 4 files changed, 206 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/knox/blob/62c75967/gateway-provider-security-pac4j/src/main/java/org/apache/hadoop/gateway/pac4j/filter/Pac4jDispatcherFilter.java ---------------------------------------------------------------------- diff --git a/gateway-provider-security-pac4j/src/main/java/org/apache/hadoop/gateway/pac4j/filter/Pac4jDispatcherFilter.java b/gateway-provider-security-pac4j/src/main/java/org/apache/hadoop/gateway/pac4j/filter/Pac4jDispatcherFilter.java index a9506cf..65a42cc 100644 --- a/gateway-provider-security-pac4j/src/main/java/org/apache/hadoop/gateway/pac4j/filter/Pac4jDispatcherFilter.java +++ b/gateway-provider-security-pac4j/src/main/java/org/apache/hadoop/gateway/pac4j/filter/Pac4jDispatcherFilter.java @@ -26,7 +26,6 @@ import org.apache.hadoop.gateway.services.security.AliasServiceException; import org.apache.hadoop.gateway.services.security.CryptoService; import org.pac4j.config.client.PropertiesConfigFactory; import org.pac4j.core.client.Client; -import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; import org.pac4j.core.config.ConfigSingleton; import org.pac4j.core.context.J2EContext; @@ -67,6 +66,8 @@ public class Pac4jDispatcherFilter implements Filter { 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; @@ -101,11 +102,13 @@ public class Pac4jDispatcherFilter implements Filter { } // url to SSO authentication provider - final String pac4jCallbackUrl = filterConfig.getInitParameter(PAC4J_CALLBACK_URL); + 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; @@ -128,7 +131,7 @@ public class Pac4jDispatcherFilter implements Filter { final PropertiesConfigFactory propertiesConfigFactory = new PropertiesConfigFactory(pac4jCallbackUrl, properties); config = propertiesConfigFactory.build(); final List<Client> clients = config.getClients().getClients(); - if (clients == null || clients.size() ==0) { + if (clients == null || clients.size() == 0) { log.atLeastOnePac4jClientMustBeDefined(); throw new ServletException("At least one pac4j client must be defined."); } @@ -157,7 +160,7 @@ public class Pac4jDispatcherFilter implements Filter { final J2EContext context = new J2EContext(request, response, ConfigSingleton.getConfig().getSessionStore()); // it's a callback from an identity provider - if (request.getParameter(Clients.DEFAULT_CLIENT_NAME_PARAMETER) != null) { + if (request.getParameter(PAC4J_CALLBACK_PARAMETER) != null) { // apply CallbackFilter callbackFilter.doFilter(servletRequest, servletResponse, filterChain); } else { http://git-wip-us.apache.org/repos/asf/knox/blob/62c75967/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 index e2cee83..e0088d5 100644 --- 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 @@ -95,9 +95,9 @@ public class Pac4jProviderTest { MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain filterChain = mock(FilterChain.class); dispatcher.doFilter(request, response, filterChain); - // it should be a redirection to the identity provider + // it should be a redirection to the idp topology assertEquals(302, response.getStatus()); - assertEquals(PAC4J_CALLBACK_URL + "?" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS, response.getHeaders().get("Location")); + 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()); @@ -107,7 +107,8 @@ public class Pac4jProviderTest { // 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 + "?" + Clients.DEFAULT_CLIENT_NAME_PARAMETER + "=" + CLIENT_CLASS); + 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); http://git-wip-us.apache.org/repos/asf/knox/blob/62c75967/gateway-release/home/templates/knoxsso-sandbox.xml ---------------------------------------------------------------------- diff --git a/gateway-release/home/templates/knoxsso-sandbox.xml b/gateway-release/home/templates/knoxsso-sandbox.xml new file mode 100644 index 0000000..2cf509e --- /dev/null +++ b/gateway-release/home/templates/knoxsso-sandbox.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<topology> + + <gateway> + + <provider> + <role>federation</role> + <name>SSOCookieProvider</name> + <enabled>true</enabled> + <param> + <name>sso.authentication.provider.url</name> + <value>https://127.0.0.1:8443/gateway/knoxsso/api/v1/websso</value> + </param> + </provider> + + <provider> + <role>identity-assertion</role> + <name>Default</name> + <enabled>true</enabled> + </provider> + + <!-- + Defines rules for mapping host names internal to a Hadoop cluster to externally accessible host names. + For example, a hadoop service running in AWS may return a response that includes URLs containing the + some AWS internal host name. If the client needs to make a subsequent request to the host identified + in those URLs they need to be mapped to external host names that the client Knox can use to connect. + + If the external hostname and internal host names are same turn of this provider by setting the value of + enabled parameter as false. + + The name parameter specifies the external host names in a comma separated list. + The value parameter specifies corresponding internal host names in a comma separated list. + + Note that when you are using Sandbox, the external hostname needs to be localhost, as seen in out + of box sandbox.xml. This is because Sandbox uses port mapping to allow clients to connect to the + Hadoop services using localhost. In real clusters, external host names would almost never be localhost. + --> + <provider> + <role>hostmap</role> + <name>static</name> + <enabled>true</enabled> + <param><name>localhost</name><value>sandbox,sandbox.hortonworks.com</value></param> + </provider> + + </gateway> + + <service> + <role>NAMENODE</role> + <url>hdfs://localhost:8020</url> + </service> + + <service> + <role>JOBTRACKER</role> + <url>rpc://localhost:8050</url> + </service> + + <service> + <role>WEBHDFS</role> + <url>http://localhost:50070/webhdfs</url> + </service> + + <service> + <role>WEBHCAT</role> + <url>http://localhost:50111/templeton</url> + </service> + + <service> + <role>OOZIE</role> + <url>http://localhost:11000/oozie</url> + </service> + + <service> + <role>WEBHBASE</role> + <url>http://localhost:60080</url> + </service> + + <service> + <role>HIVE</role> + <url>http://localhost:10001/cliservice</url> + </service> + + <service> + <role>RESOURCEMANAGER</role> + <url>http://localhost:8088/ws</url> + </service> + +</topology> http://git-wip-us.apache.org/repos/asf/knox/blob/62c75967/gateway-release/home/templates/pac4j-knoxsso.xml ---------------------------------------------------------------------- diff --git a/gateway-release/home/templates/pac4j-knoxsso.xml b/gateway-release/home/templates/pac4j-knoxsso.xml new file mode 100644 index 0000000..95be8dc --- /dev/null +++ b/gateway-release/home/templates/pac4j-knoxsso.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<topology> + + <gateway> + + <provider> + <role>federation</role> + <name>pac4j</name> + <enabled>true</enabled> + <param> + <name>pac4j.callbackUrl</name> + <value>https://127.0.0.1:8443/gateway/knoxsso/api/v1/websso</value> + </param> + <!--param> + <name>clientName</name> + <value>testBasicAuth</value> + </param--> + <param> + <name>cas.loginUrl</name> + <value>https://casserverpac4j.herokuapp.com/login</value> + </param> + <!--param> + <name>saml.keystorePath</name> + <value>/tmp/samlKeystore.jks</value> + </param> + <param> + <name>saml.keystorePassword</name> + <value>pac4j-demo-passwd</value> + </param> + <param> + <name>saml.privateKeyPassword</name> + <value>pac4j-demo-passwd</value> + </param> + <param> + <name>saml.identityProviderMetadataPath</name> + <value>/tmp/metadata-okta.xml</value> + </param> + <param> + <name>saml.maximumAuthenticationLifetime</name> + <value>3600</value> + </param> + <param> + <name>saml.serviceProviderEntityId</name> + <value>https://127.0.0.1:8443/gateway/idp/api/v1/websso?client_name=SAML2Client</value> + </param> + <param> + <name>saml.serviceProviderMetadataPath</name> + <value>sp-metadata.xml</value> + </param--> + </provider> + + <provider> + <role>identity-assertion</role> + <name>Default</name> + <enabled>true</enabled> + </provider> + + </gateway> + + <service> + <role>KNOXSSO</role> + <param> + <name>knoxsso.cookie.secure.only</name> + <value>true</value> + </param> + <param> + <name>knoxsso.token.ttl</name> + <value>100000</value> + </param> + <param> + <name>knoxsso.redirect.whitelist.regex</name> + <value>^https?:\/\/(localhost|127\.0\.0\.1|0:0:0:0:0:0:0:1|::1):[0-9].*$</value> + </param> + </service> + +</topology>