http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java deleted file mode 100644 index 961fef7..0000000 --- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java +++ /dev/null @@ -1,294 +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.identityasserter.common.filter; - -import org.apache.commons.io.IOUtils; -import org.apache.hadoop.gateway.SpiGatewayMessages; -import org.apache.hadoop.gateway.config.GatewayConfig; -import org.apache.hadoop.gateway.i18n.messages.MessagesFactory; -import org.apache.hadoop.gateway.security.PrimaryPrincipal; -import org.apache.hadoop.gateway.servlet.SynchronousServletInputStreamAdapter; -import org.apache.hadoop.gateway.util.HttpUtils; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.Charset; -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -public class IdentityAsserterHttpServletRequestWrapper extends HttpServletRequestWrapper { - -private static SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.class ); - - private static final String PRINCIPAL_PARAM = "user.name"; - private static final String DOAS_PRINCIPAL_PARAM = "doAs"; - - String username = null; - - public IdentityAsserterHttpServletRequestWrapper( HttpServletRequest request, String principal ) { - super(request); - username = principal; - } - - @Override - public Principal getUserPrincipal() { - return new PrimaryPrincipal(username); - } - - @Override - public String getParameter(String name) { - if (name.equals(PRINCIPAL_PARAM)) { - return username; - } - return super.getParameter(name); - } - - @SuppressWarnings("rawtypes") - @Override - public Map getParameterMap() { - Map map = null; - try { - map = getParams(); - } catch (UnsupportedEncodingException e) { - log.unableToGetParamsFromQueryString(e); - } - return map; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Enumeration getParameterNames() { - Enumeration<String> e = null; - Map<String, List<String>> params; - try { - params = getParams(); - if (params == null) { - params = new HashMap<>(); - } - e = Collections.enumeration((Collection<String>) params.keySet()); - } catch (UnsupportedEncodingException e1) { - log.unableToGetParamsFromQueryString(e1); - } - - return e; - } - - @Override - public String[] getParameterValues(String name) { - String[] p = null; - Map<String, List<String>> params; - try { - params = getParams(); - if (params == null) { - params = new HashMap<>(); - } - p = (String[]) params.get(name).toArray(); - } catch (UnsupportedEncodingException e) { - log.unableToGetParamsFromQueryString(e); - } - - return p; - } - - private Map<String, List<String>> getParams( String qString ) - throws UnsupportedEncodingException { - Map<String, List<String>> params = null; - if (getMethod().equals("GET")) { - if (qString != null && qString.length() > 0) { - params = HttpUtils.splitQuery( qString ); - } - else { - params = new HashMap<>(); - } - } - else { - if (qString == null || qString.length() == 0) { - return null; - } - else { - params = HttpUtils.splitQuery( qString ); - } - } - return params; - } - - private Map<String, List<String>> getParams() - throws UnsupportedEncodingException { - return getParams( super.getQueryString() ); - } - - @Override - public String getQueryString() { - String q = null; - Map<String, List<String>> params; - try { - params = getParams(); - if (params == null) { - params = new HashMap<>(); - } - ArrayList<String> al = new ArrayList<String>(); - al.add(username); - - List<String> principalParamNames = getImpersonationParamNames(); - params = scrubOfExistingPrincipalParams(params, principalParamNames); - - if ("true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED))) { - params.put(DOAS_PRINCIPAL_PARAM, al); - } else { - params.put(PRINCIPAL_PARAM, al); - } - - String encoding = getCharacterEncoding(); - if (encoding == null) { - encoding = Charset.defaultCharset().name(); - } - q = urlEncode(params, encoding); - } catch (UnsupportedEncodingException e) { - log.unableToGetParamsFromQueryString(e); - } - - return q; - } - - private List<String> getImpersonationParamNames() { - // TODO: let's have service definitions register their impersonation - // params in a future release and get this list from a central registry. - // This will provide better coverage of protection by removing any - // prepopulated impersonation params. - ArrayList<String> principalParamNames = new ArrayList<String>(); - principalParamNames.add(DOAS_PRINCIPAL_PARAM); - principalParamNames.add(PRINCIPAL_PARAM); - return principalParamNames; - } - - private Map<String, List<String>> scrubOfExistingPrincipalParams( - Map<String, List<String>> params, List<String> principalParamNames) { - HashSet<String> remove = new HashSet<>(); - for (String paramKey : params.keySet()) { - for (String p : principalParamNames) { - if (p.equalsIgnoreCase(paramKey)) { - remove.add(paramKey); - log.possibleIdentitySpoofingAttempt(paramKey); - } - } - } - params.keySet().removeAll(remove); - return params; - } - - @Override - public int getContentLength() { - int len; - String contentType = getContentType(); - // If the content type is a form we might rewrite the body so default it to -1. - if( contentType != null && contentType.startsWith( "application/x-www-form-urlencoded" ) ) { - len = -1; - } else { - len = super.getContentLength(); - } - return len; - } - - @Override - public ServletInputStream getInputStream() throws java.io.IOException { - String contentType = getContentType(); - if( contentType != null && contentType.startsWith( "application/x-www-form-urlencoded" ) ) { - String encoding = getCharacterEncoding(); - if( encoding == null ) { - encoding = Charset.defaultCharset().name(); - } - String body = IOUtils.toString( super.getInputStream(), encoding ); - Map<String, List<String>> params = getParams( body ); - if (params == null) { - params = new HashMap<>(); - } - body = urlEncode( params, encoding ); - // ASCII is OK here because the urlEncode about should have already escaped - return new ServletInputStreamWrapper( new ByteArrayInputStream( body.getBytes( "US-ASCII" ) ) ); - } else { - return super.getInputStream(); - } - } - - static String urlEncode( String string, String encoding ) { - try { - return URLEncoder.encode( string, encoding ); - } catch (UnsupportedEncodingException e) { - throw new UnsupportedOperationException(e); - } - } - - public static String urlEncode( Map<String, List<String>> map, String encoding ) { - StringBuilder sb = new StringBuilder(); - for( Map.Entry<String,List<String>> entry : map.entrySet() ) { - String name = entry.getKey(); - if( name != null && name.length() > 0 ) { - List<String> values = entry.getValue(); - if( values == null || values.size() == 0 ) { - sb.append( entry.getKey() ); - } else { - for( int i = 0; i < values.size(); i++ ) { - String value = values.get(i); - if( sb.length() > 0 ) { - sb.append( "&" ); - } - try { - sb.append( urlEncode( name, encoding ) ); - if( value != null ) { - sb.append("="); - sb.append(urlEncode(value, encoding)); - } - } catch( IllegalArgumentException e ) { - log.skippingUnencodableParameter( name, value, encoding, e ); - } - } - } - } - } - return sb.toString(); - } - - private static class ServletInputStreamWrapper extends SynchronousServletInputStreamAdapter { - - private InputStream stream; - - private ServletInputStreamWrapper( InputStream stream ) { - this.stream = stream; - } - - @Override - public int read() throws IOException { - return stream.read(); - } - - } - -}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java deleted file mode 100644 index f997de8..0000000 --- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java +++ /dev/null @@ -1,31 +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.identityasserter.common.function; - -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor; - -public class UsernameFunctionDescriptor implements UrlRewriteFunctionDescriptor<UsernameFunctionDescriptor> { - - public static final String FUNCTION_NAME = "username"; - - @Override - public String name() { - return FUNCTION_NAME; - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionProcessor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionProcessor.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionProcessor.java deleted file mode 100644 index cc5d39d..0000000 --- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/hadoop/gateway/identityasserter/common/function/UsernameFunctionProcessor.java +++ /dev/null @@ -1,74 +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.identityasserter.common.function; - -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment; -import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext; -import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; -import org.apache.hadoop.gateway.filter.security.AbstractIdentityAssertionBase; -import org.apache.hadoop.gateway.i18n.GatewaySpiMessages; -import org.apache.hadoop.gateway.i18n.messages.MessagesFactory; -import org.apache.hadoop.gateway.security.SubjectUtils; - -import javax.security.auth.Subject; -import java.security.AccessController; -import java.util.ArrayList; -import java.util.List; - -public class UsernameFunctionProcessor - implements UrlRewriteFunctionProcessor<UsernameFunctionDescriptor> { - - private static final GatewaySpiMessages LOG = MessagesFactory.get( GatewaySpiMessages.class ); -// private PrincipalMapper mapper = null; - - @Override - public String name() { - return UsernameFunctionDescriptor.FUNCTION_NAME; - } - - @Override - public void initialize( UrlRewriteEnvironment environment, UsernameFunctionDescriptor descriptor ) throws Exception { -// if( environment != null ) { -// GatewayServices services = environment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ); -// if( services != null ) { -// mapper = (PrincipalMapper)services.getService( "PrincipalMapperService" /*GatewayServices.PRINCIPAL_MAPPER_SERVICE*/ ); -// } -// } - } - - @Override - public void destroy() throws Exception { - } - - @Override - public List<String> resolve( UrlRewriteContext context, List<String> parameters ) throws Exception { - List<String> results = null; - Subject subject = SubjectUtils.getCurrentSubject( ); - if( subject != null ) { - results = new ArrayList<String>( 1 ); - String username = SubjectUtils.getEffectivePrincipalName(subject); - results.add( username ); - } else if( parameters != null && parameters.size() > 0 ) { - results = new ArrayList<String>( 1 ); - results.add( parameters.get( 0 ) ); - } - return results; - } - -} - http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/IdentityAsserterMessages.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/IdentityAsserterMessages.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/IdentityAsserterMessages.java new file mode 100644 index 0000000..e614c25 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/IdentityAsserterMessages.java @@ -0,0 +1,31 @@ +/** + * 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; + +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") +public interface IdentityAsserterMessages { + + @Message( level = MessageLevel.WARN, text = "Skipping unencodable parameter {0}={1}, {2}: {3}" ) + void skippingUnencodableParameter( String name, String value, String encoding, @StackTrace( level = MessageLevel.DEBUG ) Exception e ); + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAsserterDeploymentContributor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAsserterDeploymentContributor.java new file mode 100644 index 0000000..8f2adb8 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAsserterDeploymentContributor.java @@ -0,0 +1,61 @@ +/** + * 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.identityasserter.common.filter; + +import org.apache.knox.gateway.deploy.DeploymentContext; +import org.apache.knox.gateway.deploy.ProviderDeploymentContributorBase; +import org.apache.knox.gateway.descriptor.FilterParamDescriptor; +import org.apache.knox.gateway.descriptor.ResourceDescriptor; +import org.apache.knox.gateway.topology.Provider; +import org.apache.knox.gateway.topology.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public abstract class AbstractIdentityAsserterDeploymentContributor extends + ProviderDeploymentContributorBase { + + @Override + public String getRole() { + return "identity-assertion"; + } + + @Override + public void contributeFilter( DeploymentContext context, Provider provider, Service service, + ResourceDescriptor resource, List<FilterParamDescriptor> params ) { + params = buildFilterInitParms(provider, resource, params); + resource.addFilter().name(getName()).role(getRole()).impl(getFilterClassname()).params(params); + } + + public List<FilterParamDescriptor> buildFilterInitParms(Provider provider, + 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())); + } + return params; + } + + protected abstract String getFilterClassname(); +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java new file mode 100644 index 0000000..a007ab6 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java @@ -0,0 +1,198 @@ +/** + * 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.identityasserter.common.filter; + +import java.io.IOException; +import java.security.AccessController; +import java.security.Principal; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Arrays; +import java.util.Set; + +import javax.security.auth.Subject; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.apache.knox.gateway.audit.api.Action; +import org.apache.knox.gateway.audit.api.ActionOutcome; +import org.apache.knox.gateway.audit.api.AuditService; +import org.apache.knox.gateway.audit.api.AuditServiceFactory; +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.security.AbstractIdentityAssertionBase; +import org.apache.knox.gateway.i18n.GatewaySpiResources; +import org.apache.knox.gateway.i18n.resources.ResourcesFactory; +import org.apache.knox.gateway.security.GroupPrincipal; +import org.apache.knox.gateway.security.ImpersonatedPrincipal; +import org.apache.knox.gateway.security.PrimaryPrincipal; + +/** + * + */ +public abstract class AbstractIdentityAssertionFilter extends + AbstractIdentityAssertionBase implements Filter { + + private static final GatewaySpiResources RES = ResourcesFactory.get( GatewaySpiResources.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 ); + + /** + * + */ + public AbstractIdentityAssertionFilter() { + super(); + } + + /** + * This method returns a Stringp[] of new group principal names to use + * based on implementation specific mapping or lookup mechanisms. + * Returning null means that whatever set of GroupPrincipals is in the + * provided Subject is sufficient to use and no additional mapping is required. + * @param mappedPrincipalName username for the authenticated identity - post mapUserPrincipal mapping. + * @param subject the existing Subject from the authentication event which may or may not contain GroupPrincipals. + * @return String[] of new principal names to use as GroupPrincipals or null. + */ + public abstract String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject); + + /** + * This method is used to map the username of the authenticated identity to some other + * principal name based on an implementation specific mechanism. It will either return + * a new principal name or the provided principal name if there is no mapping required. + * @param principalName + * @return new username or the provided principalName + */ + public abstract String mapUserPrincipal(String principalName); + + /** + * @param wrapper + * @param response + * @param chain + * @param mappedPrincipalName + * @param groups + */ + protected void continueChainAsPrincipal(HttpServletRequestWrapper request, ServletResponse response, + FilterChain chain, String mappedPrincipalName, String[] groups) throws IOException, + ServletException { + Subject subject = null; + Principal impersonationPrincipal = null; + Principal primaryPrincipal = null; + + // get the current subject and determine whether we need another doAs with + // an impersonatedPrincipal and/or mapped group principals + boolean impersonationNeeded = false; + boolean groupsMapped = false; + + // look up the current Java Subject and assosciated group principals + Subject currentSubject = Subject.getSubject(AccessController.getContext()); + Set<?> currentGroups = currentSubject.getPrincipals(GroupPrincipal.class); + + primaryPrincipal = (PrimaryPrincipal) currentSubject.getPrincipals(PrimaryPrincipal.class).toArray()[0]; + if (primaryPrincipal != null) { + if (!primaryPrincipal.getName().equals(mappedPrincipalName)) { + impersonationNeeded = true; + auditService.getContext().setProxyUsername( mappedPrincipalName ); + auditor.audit( Action.IDENTITY_MAPPING, primaryPrincipal.getName(), + ResourceType.PRINCIPAL, ActionOutcome.SUCCESS, RES.effectiveUser(mappedPrincipalName) ); + } + } + else { + // something is amiss - authentication/federation providers should have run + // before identity assertion and should have ensured that the appropriate + // principals were added to the current subject + // TODO: log as appropriate + primaryPrincipal = new PrimaryPrincipal(((HttpServletRequest) request).getUserPrincipal().getName()); + } + + groupsMapped = groups != null || !currentGroups.isEmpty(); + + if (impersonationNeeded || groupsMapped) { + // gonna need a new subject and doAs + subject = new Subject(); + Set<Principal> principals = subject.getPrincipals(); + principals.add(primaryPrincipal); + + // map group principals from current Subject into newly created Subject + for (Object obj : currentGroups) { + principals.add((Principal)obj); + } + + if (impersonationNeeded) { + impersonationPrincipal = new ImpersonatedPrincipal(mappedPrincipalName); + subject.getPrincipals().add(impersonationPrincipal); + } + if (groupsMapped) { + addMappedGroupsToSubject(mappedPrincipalName, groups, subject); + } + doAs(request, response, chain, subject); + } + else { + doFilterInternal(request, response, chain); + } + } + + 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 { + doFilterInternal(request, response, chain); + 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); + } + } + } + + private void addMappedGroupsToSubject(String mappedPrincipalName, String[] groups, Subject subject) { + if (groups != null) { + auditor.audit( Action.IDENTITY_MAPPING, mappedPrincipalName, ResourceType.PRINCIPAL, + ActionOutcome.SUCCESS, RES.groupsList( Arrays.toString( groups ) ) ); + + for (int i = 0; i < groups.length; i++) { + subject.getPrincipals().add(new GroupPrincipal(groups[i])); + } + } + } + + private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + chain.doFilter(request, response); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java new file mode 100644 index 0000000..391aa9e --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java @@ -0,0 +1,143 @@ +/** + * 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.identityasserter.common.filter; + +import javax.security.auth.Subject; +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 javax.servlet.http.HttpServletRequestWrapper; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.knox.gateway.security.principal.PrincipalMappingException; +import org.apache.knox.gateway.security.principal.SimplePrincipalMapper; + +import java.io.IOException; +import java.security.AccessController; + +public class CommonIdentityAssertionFilter extends AbstractIdentityAssertionFilter { + private static final String GROUP_PRINCIPAL_MAPPING = "group.principal.mapping"; + private static final String PRINCIPAL_MAPPING = "principal.mapping"; + private SimplePrincipalMapper mapper = new SimplePrincipalMapper(); + + /* (non-Javadoc) + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ + @Override + public void init(FilterConfig filterConfig) throws ServletException { + String principalMapping = filterConfig.getInitParameter(PRINCIPAL_MAPPING); + if (principalMapping == null || principalMapping.isEmpty()) { + principalMapping = filterConfig.getServletContext().getInitParameter(PRINCIPAL_MAPPING); + } + String groupPrincipalMapping = filterConfig.getInitParameter(GROUP_PRINCIPAL_MAPPING); + if (groupPrincipalMapping == null || groupPrincipalMapping.isEmpty()) { + groupPrincipalMapping = filterConfig.getServletContext().getInitParameter(GROUP_PRINCIPAL_MAPPING); + } + if (principalMapping != null && !principalMapping.isEmpty() || groupPrincipalMapping != null && !groupPrincipalMapping.isEmpty()) { + try { + mapper.loadMappingTable(principalMapping, groupPrincipalMapping); + } catch (PrincipalMappingException e) { + throw new ServletException("Unable to load principal mapping table.", e); + } + } + } + + /* (non-Javadoc) + * @see javax.servlet.Filter#destroy() + */ + @Override + public void destroy() { + } + + /** + * Obtain the standard javax.security.auth.Subject, retrieve the caller principal, map + * to the identity to be asserted as appropriate and create the provider specific + * assertion token. Add the assertion token to the request. + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + Subject subject = Subject.getSubject(AccessController.getContext()); + + String principalName = getPrincipalName(subject); + + String mappedPrincipalName = mapUserPrincipalBase(principalName); + mappedPrincipalName = mapUserPrincipal(mappedPrincipalName); + String[] mappedGroups = mapGroupPrincipals(mappedPrincipalName, subject); + String[] groups = mapGroupPrincipals(mappedPrincipalName, subject); + groups = combineGroupMappings(mappedGroups, groups); + + HttpServletRequestWrapper wrapper = wrapHttpServletRequest( + request, mappedPrincipalName); + + continueChainAsPrincipal(wrapper, response, chain, mappedPrincipalName, groups); + } + + /** + * @param mappedGroups + * @param groups + * @return + */ + private String[] combineGroupMappings(String[] mappedGroups, String[] groups) { + if (mappedGroups != null && groups != null) { + return (String[])ArrayUtils.addAll(mappedGroups, groups); + } + else { + return groups != null ? groups : mappedGroups; + } + } + + public HttpServletRequestWrapper wrapHttpServletRequest( + ServletRequest request, String mappedPrincipalName) { + // wrap the request so that the proper principal is returned + // from request methods + IdentityAsserterHttpServletRequestWrapper wrapper = + new IdentityAsserterHttpServletRequestWrapper( + (HttpServletRequest)request, + mappedPrincipalName); + return wrapper; + } + + protected String[] mapGroupPrincipalsBase(String mappedPrincipalName, Subject subject) { + return mapper.mapGroupPrincipal(mappedPrincipalName); + } + + protected String mapUserPrincipalBase(String principalName) { + return mapper.mapUserPrincipal(principalName); + } + + /* (non-Javadoc) + * @see AbstractIdentityAssertionFilter#mapGroupPrincipals(java.lang.String, javax.security.auth.Subject) + */ + @Override + public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) { + // NOP + return null; + } + + /* (non-Javadoc) + * @see AbstractIdentityAssertionFilter#mapUserPrincipal(java.lang.String) + */ + @Override + public String mapUserPrincipal(String principalName) { + // NOP + return principalName; + } +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java new file mode 100644 index 0000000..a484d16 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java @@ -0,0 +1,295 @@ +/** + * 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.identityasserter.common.filter; + +import org.apache.commons.io.IOUtils; +import org.apache.knox.gateway.SpiGatewayMessages; +import org.apache.knox.gateway.config.GatewayConfig; +import org.apache.knox.gateway.i18n.messages.MessagesFactory; +import org.apache.knox.gateway.security.PrimaryPrincipal; +import org.apache.knox.gateway.servlet.SynchronousServletInputStreamAdapter; +import org.apache.knox.gateway.util.HttpUtils; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +public class IdentityAsserterHttpServletRequestWrapper extends HttpServletRequestWrapper { + +private static SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.class ); + + private static final String PRINCIPAL_PARAM = "user.name"; + private static final String DOAS_PRINCIPAL_PARAM = "doAs"; + + String username = null; + + public IdentityAsserterHttpServletRequestWrapper( HttpServletRequest request, String principal ) { + super(request); + username = principal; + } + + @Override + public Principal getUserPrincipal() { + return new PrimaryPrincipal(username); + } + + @Override + public String getParameter(String name) { + if (name.equals(PRINCIPAL_PARAM)) { + return username; + } + return super.getParameter(name); + } + + @SuppressWarnings("rawtypes") + @Override + public Map getParameterMap() { + Map map = null; + try { + map = getParams(); + } catch (UnsupportedEncodingException e) { + log.unableToGetParamsFromQueryString(e); + } + return map; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Enumeration getParameterNames() { + Enumeration<String> e = null; + Map<String, List<String>> params; + try { + params = getParams(); + if (params == null) { + params = new HashMap<>(); + } + e = Collections.enumeration((Collection<String>) params.keySet()); + } catch (UnsupportedEncodingException e1) { + log.unableToGetParamsFromQueryString(e1); + } + + return e; + } + + @Override + public String[] getParameterValues(String name) { + String[] p = null; + Map<String, List<String>> params; + try { + params = getParams(); + if (params == null) { + params = new HashMap<>(); + } + p = (String[]) params.get(name).toArray(); + } catch (UnsupportedEncodingException e) { + log.unableToGetParamsFromQueryString(e); + } + + return p; + } + + private Map<String, List<String>> getParams( String qString ) + throws UnsupportedEncodingException { + Map<String, List<String>> params = null; + if (getMethod().equals("GET")) { + if (qString != null && qString.length() > 0) { + params = HttpUtils.splitQuery( qString ); + } + else { + params = new HashMap<>(); + } + } + else { + if (qString == null || qString.length() == 0) { + return null; + } + else { + params = HttpUtils.splitQuery( qString ); + } + } + return params; + } + + private Map<String, List<String>> getParams() + throws UnsupportedEncodingException { + return getParams( super.getQueryString() ); + } + + @Override + public String getQueryString() { + String q = null; + Map<String, List<String>> params; + try { + params = getParams(); + if (params == null) { + params = new HashMap<>(); + } + ArrayList<String> al = new ArrayList<String>(); + al.add(username); + + List<String> principalParamNames = getImpersonationParamNames(); + params = scrubOfExistingPrincipalParams(params, principalParamNames); + + if ("true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED))) { + params.put(DOAS_PRINCIPAL_PARAM, al); + } else { + params.put(PRINCIPAL_PARAM, al); + } + + String encoding = getCharacterEncoding(); + if (encoding == null) { + encoding = Charset.defaultCharset().name(); + } + q = urlEncode(params, encoding); + } catch (UnsupportedEncodingException e) { + log.unableToGetParamsFromQueryString(e); + } + + return q; + } + + private List<String> getImpersonationParamNames() { + // TODO: let's have service definitions register their impersonation + // params in a future release and get this list from a central registry. + // This will provide better coverage of protection by removing any + // prepopulated impersonation params. + ArrayList<String> principalParamNames = new ArrayList<String>(); + principalParamNames.add(DOAS_PRINCIPAL_PARAM); + principalParamNames.add(PRINCIPAL_PARAM); + return principalParamNames; + } + + private Map<String, List<String>> scrubOfExistingPrincipalParams( + Map<String, List<String>> params, List<String> principalParamNames) { + HashSet<String> remove = new HashSet<>(); + for (String paramKey : params.keySet()) { + for (String p : principalParamNames) { + if (p.equalsIgnoreCase(paramKey)) { + remove.add(paramKey); + log.possibleIdentitySpoofingAttempt(paramKey); + } + } + } + params.keySet().removeAll(remove); + return params; + } + + @Override + public int getContentLength() { + int len; + String contentType = getContentType(); + // If the content type is a form we might rewrite the body so default it to -1. + if( contentType != null && contentType.startsWith( "application/x-www-form-urlencoded" ) ) { + len = -1; + } else { + len = super.getContentLength(); + } + return len; + } + + @Override + public ServletInputStream getInputStream() throws java.io.IOException { + String contentType = getContentType(); + if( contentType != null && contentType.startsWith( "application/x-www-form-urlencoded" ) ) { + String encoding = getCharacterEncoding(); + if( encoding == null ) { + encoding = Charset.defaultCharset().name(); + } + String body = IOUtils.toString( super.getInputStream(), encoding ); + Map<String, List<String>> params = getParams( body ); + if (params == null) { + params = new HashMap<>(); + } + body = urlEncode( params, encoding ); + // ASCII is OK here because the urlEncode about should have already escaped + return new ServletInputStreamWrapper( new ByteArrayInputStream( body.getBytes( "US-ASCII" ) ) ); + } else { + return super.getInputStream(); + } + } + + static String urlEncode( String string, String encoding ) { + try { + return URLEncoder.encode( string, encoding ); + } catch (UnsupportedEncodingException e) { + throw new UnsupportedOperationException(e); + } + } + + public static String urlEncode( Map<String, List<String>> map, String encoding ) { + StringBuilder sb = new StringBuilder(); + for( Map.Entry<String,List<String>> entry : map.entrySet() ) { + String name = entry.getKey(); + if( name != null && name.length() > 0 ) { + List<String> values = entry.getValue(); + if( values == null || values.size() == 0 ) { + sb.append( entry.getKey() ); + } else { + for( int i = 0; i < values.size(); i++ ) { + String value = values.get(i); + if( sb.length() > 0 ) { + sb.append( "&" ); + } + try { + sb.append( urlEncode( name, encoding ) ); + if( value != null ) { + sb.append("="); + sb.append(urlEncode(value, encoding)); + } + } catch( IllegalArgumentException e ) { + log.skippingUnencodableParameter( name, value, encoding, e ); + } + } + } + } + } + return sb.toString(); + } + + private static class ServletInputStreamWrapper extends + SynchronousServletInputStreamAdapter { + + private InputStream stream; + + private ServletInputStreamWrapper( InputStream stream ) { + this.stream = stream; + } + + @Override + public int read() throws IOException { + return stream.read(); + } + + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java new file mode 100644 index 0000000..37b0aaf --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionDescriptor.java @@ -0,0 +1,32 @@ +/** + * 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.identityasserter.common.function; + +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor; + +public class UsernameFunctionDescriptor implements + UrlRewriteFunctionDescriptor<UsernameFunctionDescriptor> { + + public static final String FUNCTION_NAME = "username"; + + @Override + public String name() { + return FUNCTION_NAME; + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionProcessor.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionProcessor.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionProcessor.java new file mode 100644 index 0000000..7d3c4d0 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/function/UsernameFunctionProcessor.java @@ -0,0 +1,72 @@ +/** + * 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.identityasserter.common.function; + +import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment; +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteContext; +import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; +import org.apache.knox.gateway.i18n.GatewaySpiMessages; +import org.apache.knox.gateway.i18n.messages.MessagesFactory; +import org.apache.knox.gateway.security.SubjectUtils; + +import javax.security.auth.Subject; +import java.util.ArrayList; +import java.util.List; + +public class UsernameFunctionProcessor + implements UrlRewriteFunctionProcessor<UsernameFunctionDescriptor> { + + private static final GatewaySpiMessages LOG = MessagesFactory.get( GatewaySpiMessages.class ); +// private PrincipalMapper mapper = null; + + @Override + public String name() { + return UsernameFunctionDescriptor.FUNCTION_NAME; + } + + @Override + public void initialize( UrlRewriteEnvironment environment, UsernameFunctionDescriptor descriptor ) throws Exception { +// if( environment != null ) { +// GatewayServices services = environment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ); +// if( services != null ) { +// mapper = (PrincipalMapper)services.getService( "PrincipalMapperService" /*GatewayServices.PRINCIPAL_MAPPER_SERVICE*/ ); +// } +// } + } + + @Override + public void destroy() throws Exception { + } + + @Override + public List<String> resolve( UrlRewriteContext context, List<String> parameters ) throws Exception { + List<String> results = null; + Subject subject = SubjectUtils.getCurrentSubject( ); + if( subject != null ) { + results = new ArrayList<String>( 1 ); + String username = SubjectUtils.getEffectivePrincipalName(subject); + results.add( username ); + } else if( parameters != null && parameters.size() > 0 ) { + results = new ArrayList<String>( 1 ); + results.add( parameters.get( 0 ) ); + } + return results; + } + +} + http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor deleted file mode 100644 index 2545fb6..0000000 --- a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor +++ /dev/null @@ -1,18 +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. -########################################################################## - http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor deleted file mode 100644 index 9671caf..0000000 --- a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor +++ /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.identityasserter.common.function.UsernameFunctionDescriptor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor deleted file mode 100644 index 5038d11..0000000 --- a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor +++ /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.identityasserter.common.function.UsernameFunctionProcessor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor new file mode 100644 index 0000000..2545fb6 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor @@ -0,0 +1,18 @@ +########################################################################## +# 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. +########################################################################## + http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor new file mode 100644 index 0000000..2f684f2 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor @@ -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.identityasserter.common.function.UsernameFunctionDescriptor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor new file mode 100644 index 0000000..6cf41b0 --- /dev/null +++ b/gateway-provider-identity-assertion-common/src/main/resources/META-INF/services/org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor @@ -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.identityasserter.common.function.UsernameFunctionProcessor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java deleted file mode 100644 index 4d53dbb..0000000 --- a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java +++ /dev/null @@ -1,130 +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.identityasserter.filter; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.URISyntaxException; -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 javax.servlet.http.HttpServletResponse; - -import org.apache.hadoop.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter; -import org.apache.hadoop.gateway.security.GroupPrincipal; -import org.apache.hadoop.gateway.security.PrimaryPrincipal; -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -/** - * @author larry - * - */ -public class CommonIdentityAssertionFilterTest { - - private String username = null; - private String[] mappedGroups = null; - private Filter filter = null; - - @Before - public void setup() { - filter = new CommonIdentityAssertionFilter() { - @Override - public String mapUserPrincipal(String principalName) { - username = principalName.toUpperCase(); - return principalName; - } - - @Override - public String[] mapGroupPrincipals(String principalName, Subject subject) { - String[] groups = new String[2]; - int i = 0; - for(GroupPrincipal p : subject.getPrincipals(GroupPrincipal.class)) { - groups[i] = p.getName().toUpperCase(); - i++; - } - mappedGroups = groups; - return groups; - } - }; - } - - @Test - public void testSimpleFilter() throws ServletException, IOException, - URISyntaxException { - - FilterConfig config = EasyMock.createNiceMock( FilterConfig.class ); - EasyMock.replay( config ); - - final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class ); - EasyMock.replay( request ); - - final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class ); - EasyMock.replay( response ); - - final FilterChain chain = new FilterChain() { - @Override - public void doFilter(ServletRequest request, ServletResponse response) - throws IOException, ServletException { - } - }; - - Subject subject = new Subject(); - subject.getPrincipals().add(new PrimaryPrincipal("larry")); - subject.getPrincipals().add(new GroupPrincipal("users")); - subject.getPrincipals().add(new GroupPrincipal("admin")); - try { - Subject.doAs( - subject, - new PrivilegedExceptionAction<Object>() { - public Object run() throws Exception { - filter.doFilter(request, response, chain); - 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); - } - } - assertEquals("LARRY", username); - assertEquals(mappedGroups.length, 2); - assertTrue(mappedGroups[0].equals("USERS") || mappedGroups[0].equals("ADMIN")); - assertTrue(mappedGroups[1], mappedGroups[1].equals("USERS") || mappedGroups[1].equals("ADMIN")); - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java deleted file mode 100644 index 709c6e4..0000000 --- a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java +++ /dev/null @@ -1,279 +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.identityasserter.filter; - -import org.apache.commons.io.IOUtils; -import org.apache.hadoop.gateway.config.GatewayConfig; -import org.apache.hadoop.gateway.identityasserter.common.filter.IdentityAsserterHttpServletRequestWrapper; -import org.apache.hadoop.test.category.FastTests; -import org.apache.hadoop.test.category.UnitTests; -import org.apache.hadoop.test.mock.MockHttpServletRequest; -import org.apache.hadoop.test.mock.MockServletInputStream; -import org.junit.Test; -import org.junit.After; -import org.junit.experimental.categories.Category; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - -@Category( { UnitTests.class, FastTests.class } ) -public class IdentityAssertionHttpServletRequestWrapperTest { - - @After - public void resetSystemProps() { - System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "false"); - } - - @Test - public void testInsertUserNameInPostMethod() throws IOException { - String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setCharacterEncoding( "UTF-8" ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInPostMethodWithoutEncoding() throws IOException { - String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInPostMethodWithIso88591Encoding() throws IOException { - String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setCharacterEncoding( "ISO-8859-1" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testOverwriteUserNameInPostMethod() throws IOException { - String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setCharacterEncoding( "UTF-8" ); - request.setContentType( "application/x-www-form-urlencoded" ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - String output = wrapper.getQueryString(); - assertThat( output, containsString( "user.name=output-user" ) ); - assertThat( output, not( containsString( "input-user" ) ) ); - } - - @Test - public void testIngoreNonFormBody() throws IOException { - String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) ); - request.setCharacterEncoding( "UTF-8" ); - request.setContentType( "text/plain" ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() ); - - assertThat( outputBody, containsString( "user.name=input-user" ) ); - assertThat( outputBody, not( containsString( "output-user" ) ) ); - } - - @Test - public void testInsertUserNameInQueryString() { - String input = "param=value"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertDoAsInQueryString() { - System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "true"); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString("op=LISTSTATUS&user.name=jack&User.Name=jill&DOas=admin&doas=root"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - assertThat(output, is("op=LISTSTATUS&doAs=output-user")); - } - - @Test - public void testInsertUserNameInNullQueryString() { - String input = null; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInNullQueryStringForGET() { - String input = null; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testInsertUserNameInQueryStringForPOST() { - String input = null; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - request.setMethod("POST"); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - } - - @Test - public void testOverwriteUserNameInQueryString() { - String input = "user.name=input-user"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - assertThat( output, not( containsString( "input-user" ) ) ); - } - - @Test - public void testParameterWithNullValueInQueryString() { - String input = "paramWithNullValue¶m2=abc"; - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setQueryString( input ); - - IdentityAsserterHttpServletRequestWrapper wrapper - = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" ); - - String output = wrapper.getQueryString(); - - assertThat( output, containsString( "user.name=output-user" ) ); - assertThat( output, containsString( "paramWithNullValue" ) ); - assertThat( output, containsString( "param2=abc" ) ); - } - - @Test - public void testUrlEncode() { - String s; - HashMap<String,List<String>> m; - - m = new HashMap<>(); - m.put( "null-values", null ); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "null-values" ) ); - - m = new HashMap<>(); - m.put( "no-values", new ArrayList<String>(0) ); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "no-values" ) ); - - m = new HashMap<>(); - List<String> lst = new ArrayList<String>(); - lst.add("value1"); - m.put( "one-value", lst); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "one-value=value1" ) ); - - m = new HashMap<>(); - lst = new ArrayList<String>(); - String[] a = {"value1", "value2"}; - lst.addAll(Arrays.asList(a)); - m.put( "two-values", lst); - s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" ); - assertThat( s, is( "two-values=value1&two-values=value2" ) ); - } - -} http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java ---------------------------------------------------------------------- diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java deleted file mode 100644 index 51f9d57..0000000 --- a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java +++ /dev/null @@ -1,52 +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.identityasserter.function; - -import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor; -import org.apache.hadoop.gateway.identityasserter.common.function.UsernameFunctionDescriptor; -import org.junit.Test; - -import java.util.Iterator; -import java.util.ServiceLoader; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.fail; - -public class UsernameFunctionDescriptorTest { - - @Test - public void testName() throws Exception { - UsernameFunctionDescriptor descriptor = new UsernameFunctionDescriptor(); - assertThat( descriptor.name(), is( "username" ) ); - } - - @Test - public void testServiceLoader() throws Exception { - ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionDescriptor.class ); - Iterator iterator = loader.iterator(); - while( iterator.hasNext() ) { - Object object = iterator.next(); - if( object instanceof UsernameFunctionDescriptor ) { - return; - } - } - fail( "Failed to find UsernameFunctionDescriptor via service loader." ); - } - -}