Repository: knox
Updated Branches:
refs/heads/master a492c678a -> ce52a5542
[KNOX-694] - Enhance LDAP user search configurability
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/ce52a554
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/ce52a554
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/ce52a554
Branch: refs/heads/master
Commit: ce52a55429535eeb034d7dae2a7d01f54c57be2f
Parents: a492c67
Author: Kevin Minder <kminder@apache.org>
Authored: Wed Mar 16 20:30:39 2016 -0400
Committer: Kevin Minder <kminder@apache.org>
Committed: Wed Mar 16 20:30:39 2016 -0400
----------------------------------------------------------------------
CHANGES | 1 +
.../gateway/shirorealm/KnoxLdapRealm.java | 149 ++++++++++++++++---
.../apache/hadoop/gateway/GatewayMessages.java | 3 +
.../hadoop/gateway/GatewayMultiFuncTest.java | 144 ++++++++++++++++++
...knox694-principal-regex-search-attribute.xml | 81 ++++++++++
...st-knox694-principal-regex-search-filter.xml | 77 ++++++++++
...x694-principal-regex-search-scope-object.xml | 77 ++++++++++
...pal-regex-search-scope-onelevel-negative.xml | 81 ++++++++++
...pal-regex-search-scope-onelevel-positive.xml | 81 ++++++++++
...knox694-principal-regex-user-dn-template.xml | 65 ++++++++
.../gateway/GatewayMultiFuncTest/users.ldif | 12 ++
11 files changed, 754 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 4e39f65..5963fca 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,7 @@ Release Notes - Apache Knox - Version 0.9.0
* [KNOX-675] - Upgrade Knox's Jetty dependency to latest 9.x
* [KNOX-678] - Malformed UTF-8 characters in JSON Response
* [KNOX-680] - Update Knox's HttpClient dependency to latest version
+ * [KNOX-694] - Enhance LDAP user search configurability
** Bug
* [KNOX-681] - A PUT with Content-Type application/xml but no body causes NullPointerException
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
index 888b6a9..eb1e862 100644
--- a/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
+++ b/gateway-provider-security-shiro/src/main/java/org/apache/hadoop/gateway/shirorealm/KnoxLdapRealm.java
@@ -29,6 +29,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.naming.AuthenticationException;
import javax.naming.NamingEnumeration;
@@ -124,10 +126,14 @@ public class KnoxLdapRealm extends JndiLdapRealm {
AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
AuditConstants.KNOX_COMPONENT_NAME );
+ private static Pattern TEMPLATE_PATTERN = Pattern.compile( "\\{(\\d+?)\\}" );
+ private static String DEFAULT_PRINCIPAL_REGEX = "(.*)";
private static final String MEMBER_SUBSTITUTION_TOKEN = "{0}";
+
private final static SearchControls SUBTREE_SCOPE = new SearchControls();
private final static SearchControls ONELEVEL_SCOPE = new SearchControls();
-
+ private final static SearchControls OBJECT_SCOPE = new SearchControls();
+
private final static String SUBJECT_USER_ROLES = "subject.userRoles";
private final static String SUBJECT_USER_GROUPS = "subject.userGroups";
@@ -140,11 +146,19 @@ public class KnoxLdapRealm extends JndiLdapRealm {
static {
SUBTREE_SCOPE.setSearchScope(SearchControls.SUBTREE_SCOPE);
ONELEVEL_SCOPE.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+ OBJECT_SCOPE.setSearchScope( SearchControls.OBJECT_SCOPE );
}
private String searchBase;
private String userSearchBase;
+ private String principalRegex = DEFAULT_PRINCIPAL_REGEX;
+ private Pattern principalPattern = Pattern.compile( DEFAULT_PRINCIPAL_REGEX );
+ private String userDnTemplate = "{0}";
+ private String userSearchFilter = null;
+ private String userSearchAttributeTemplate = "{0}";
+ private String userSearchScope = "subtree";
+
private String groupSearchBase;
private String groupObjectClass = "groupOfNames";
@@ -537,8 +551,71 @@ public class KnoxLdapRealm extends JndiLdapRealm {
}
return member;
}
-
- /**
+
+ public String getPrincipalRegex() {
+ return principalRegex;
+ }
+
+ public void setPrincipalRegex( String regex ) {
+ if( regex == null || regex.trim().isEmpty() ) {
+ principalPattern = Pattern.compile( DEFAULT_PRINCIPAL_REGEX );
+ principalRegex = DEFAULT_PRINCIPAL_REGEX;
+ } else {
+ regex = regex.trim();
+ Pattern pattern = Pattern.compile( regex );
+ principalPattern = pattern;
+ principalRegex = regex;
+ }
+ }
+
+ public String getUserSearchAttributeTemplate() {
+ return userSearchAttributeTemplate;
+ }
+
+ public void setUserSearchAttributeTemplate( final String template ) {
+ this.userSearchAttributeTemplate = ( template == null ? null : template.trim() );
+ }
+
+ public String getUserSearchFilter() {
+ return userSearchFilter;
+ }
+
+ public void setUserSearchFilter( final String filter ) {
+ this.userSearchFilter = ( filter == null ? null : filter.trim() );
+ }
+
+ public String getUserSearchScope() {
+ return userSearchScope;
+ }
+
+ public void setUserSearchScope( final String scope ) {
+ this.userSearchScope = ( scope == null ? null : scope.trim().toLowerCase() );
+ }
+
+ private SearchControls getUserSearchControls() {
+ SearchControls searchControls = SUBTREE_SCOPE;
+ if ( "onelevel".equalsIgnoreCase( userSearchScope ) ) {
+ searchControls = ONELEVEL_SCOPE;
+ } else if ( "object".equalsIgnoreCase( userSearchScope ) ) {
+ searchControls = OBJECT_SCOPE;
+ }
+ return searchControls;
+ }
+
+ @Override
+ public void setUserDnTemplate( final String template ) throws IllegalArgumentException
{
+ userDnTemplate = template;
+ }
+
+ private Matcher matchPrincipal( final String principal ) {
+ Matcher matchedPrincipal = principalPattern.matcher( principal );
+ if( !matchedPrincipal.matches() ) {
+ throw new IllegalArgumentException( "Principal " + principal + " does not match " +
principalRegex );
+ }
+ return matchedPrincipal;
+ }
+
+ /**
* Returns the LDAP User Distinguished Name (DN) to use when acquiring an
* {@link javax.naming.ldap.LdapContext LdapContext} from the {@link LdapContextFactory}.
* <p/>
@@ -554,27 +631,50 @@ public class KnoxLdapRealm extends JndiLdapRealm {
* @see LdapContextFactory#getLdapContext(Object, Object)
*/
@Override
- protected String getUserDn(String principal) throws IllegalArgumentException, IllegalStateException
{
- String userDn = null;
- if (userSearchAttributeName == null || userSearchAttributeName.isEmpty()) {
- userDn = super.getUserDn(principal);
- LOG.computedUserDn(userDn, principal);
+ protected String getUserDn( final String principal ) throws IllegalArgumentException,
IllegalStateException {
+ String userDn;
+ Matcher matchedPrincipal = matchPrincipal( principal );
+ String userSearchBase = getUserSearchBase();
+ String userSearchAttributeName = getUserSearchAttributeName();
+
+ // If not searching use the userDnTemplate and return.
+ if ( ( userSearchBase == null || userSearchBase.isEmpty() ) ||
+ ( userSearchAttributeName == null &&
+ userSearchFilter == null &&
+ !"object".equalsIgnoreCase( userSearchScope ) ) ) {
+ userDn = expandTemplate( userDnTemplate, matchedPrincipal );
+ LOG.computedUserDn( userDn, principal );
return userDn;
}
- // search for userDn and return
+ // Create the searchBase and searchFilter from config.
+ String searchBase = expandTemplate( getUserSearchBase(), matchedPrincipal );
+ String searchFilter = null;
+ if ( userSearchFilter == null ) {
+ if ( userSearchAttributeName == null ) {
+ searchFilter = String.format( "(objectclass=%1$s)", getUserObjectClass() );
+ } else {
+ searchFilter = String.format(
+ "(&(objectclass=%1$s)(%2$s=%3$s))",
+ getUserObjectClass(),
+ userSearchAttributeName,
+ expandTemplate( getUserSearchAttributeTemplate(), matchedPrincipal ) );
+ }
+ } else {
+ searchFilter = expandTemplate( userSearchFilter, matchedPrincipal );
+ }
+ SearchControls searchControls = getUserSearchControls();
+
+ // Search for userDn and return.
LdapContext systemLdapCtx = null;
NamingEnumeration<SearchResult> searchResultEnum = null;
try {
systemLdapCtx = getContextFactory().getSystemLdapContext();
- String searchFilter = String.format("(&(objectclass=%1$s)(%2$s=%3$s))",
- userObjectClass, userSearchAttributeName, principal);
- searchResultEnum = systemLdapCtx.search(
- getUserSearchBase(),
- searchFilter,
- SUBTREE_SCOPE);
- if (searchResultEnum.hasMore()) { // searchResults contains all the groups in search
scope
- SearchResult searchResult = searchResultEnum.next();
+ LOG.searchBaseFilterScope(searchBase, searchFilter, userSearchScope);
+ searchResultEnum = systemLdapCtx.search( searchBase, searchFilter, searchControls
);
+ // SearchResults contains all the entries in search scope
+ if (searchResultEnum.hasMore()) {
+ SearchResult searchResult = searchResultEnum.next();
userDn = searchResult.getNameInNamespace();
LOG.searchedAndFoundUserDn(userDn, principal);
return userDn;
@@ -592,6 +692,7 @@ public class KnoxLdapRealm extends JndiLdapRealm {
searchResultEnum.close();
}
} catch (NamingException e) {
+ // Ignore exception on close.
}
finally {
LdapUtils.closeContext(systemLdapCtx);
@@ -605,4 +706,18 @@ public class KnoxLdapRealm extends JndiLdapRealm {
Hash credentialsHash = hashService.computeHash(builder.setSource(token.getCredentials()).setAlgorithmName(HASHING_ALGORITHM).build());
return new SimpleAuthenticationInfo(token.getPrincipal(), credentialsHash.toHex(),
credentialsHash.getSalt(), getName());
}
+
+ private static final String expandTemplate( final String template, final Matcher input
) {
+ String output = template;
+ Matcher matcher = TEMPLATE_PATTERN.matcher( output );
+ while( matcher.find() ) {
+ String lookupStr = matcher.group( 1 );
+ int lookupIndex = Integer.parseInt( lookupStr );
+ String lookupValue = input.group( lookupIndex );
+ output = matcher.replaceFirst( lookupValue == null ? "" : lookupValue );
+ matcher = TEMPLATE_PATTERN.matcher( output );
+ }
+ return output;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
index 8ac83b2..c9dc3b2 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
@@ -344,6 +344,9 @@ public interface GatewayMessages {
@Message( level = MessageLevel.INFO, text = "Computed userDn: {0} using dnTemplate for
principal: {1}" )
void computedUserDn(String userDn, String principal);
+ @Message( level = MessageLevel.DEBUG, text = "Searching from {0} where {1} scope {2}" )
+ void searchBaseFilterScope( String searchBase, String searchFilter, String searchScope
);
+
@Message( level = MessageLevel.INFO, text = "Computed userDn: {0} using ldapSearch for
principal: {1}" )
void searchedAndFoundUserDn(String userDn, String principal);
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayMultiFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayMultiFuncTest.java
b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayMultiFuncTest.java
index ca6fd43..97c266f 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayMultiFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayMultiFuncTest.java
@@ -303,6 +303,150 @@ public class GatewayMultiFuncTest {
LOG_EXIT();
}
+ @Test( timeout = TestUtils.MEDIUM_TIMEOUT )
+ public void testLdapSearchConfigEnhancementsKnox694() throws Exception {
+ LOG_ENTER();
+
+ String topoStr;
+ File topoFile;
+
+ String adminUName = "uid=admin,ou=people,dc=hadoop,dc=apache,dc=org";
+ String adminPWord = "admin-password";
+ String uname = "people\\guest";
+ String pword = "guest-password";
+ String invalidPword = "invalid-guest-password";
+
+ params = new Properties();
+ params.put( "LDAP_URL", "ldap://localhost:" + ldapTransport.getAcceptor().getLocalAddress().getPort()
);
+ params.put( "LDAP_SYSTEM_USERNAME", adminUName );
+ params.put( "LDAP_SYSTEM_PASSWORD", adminPWord );
+
+ topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-user-dn-template.xml",
params );
+ topoFile = new File( config.getGatewayTopologyDir(), "knox694-1.xml" );
+ FileUtils.writeStringToFile( topoFile, topoStr );
+ topos.reloadTopologies();
+
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, pword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_OK )
+ .contentType( "text/plain" )
+ .body( is( "test-service-response" ) )
+ .when().log().ifError().get( gatewayUrl + "/knox694-1/test-service-path/test-resource-path"
);
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, invalidPword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_UNAUTHORIZED )
+ .when().get( gatewayUrl + "/knox694-1/test-service-path/test-resource-path" );
+
+ topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-attribute.xml",
params );
+ topoFile = new File( config.getGatewayTopologyDir(), "knox694-2.xml" );
+ FileUtils.writeStringToFile( topoFile, topoStr );
+ topos.reloadTopologies();
+
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, pword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_OK )
+ .contentType( "text/plain" )
+ .body( is( "test-service-response" ) )
+ .when().log().ifError().get( gatewayUrl + "/knox694-2/test-service-path/test-resource-path"
);
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, invalidPword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_UNAUTHORIZED )
+ .when().get( gatewayUrl + "/knox694-2/test-service-path/test-resource-path" );
+
+ topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-filter.xml",
params );
+ topoFile = new File( config.getGatewayTopologyDir(), "knox694-3.xml" );
+ FileUtils.writeStringToFile( topoFile, topoStr );
+ topos.reloadTopologies();
+
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, pword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_OK )
+ .contentType( "text/plain" )
+ .body( is( "test-service-response" ) )
+ .when().log().ifError().get( gatewayUrl + "/knox694-3/test-service-path/test-resource-path"
);
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, invalidPword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_UNAUTHORIZED )
+ .when().get( gatewayUrl + "/knox694-3/test-service-path/test-resource-path" );
+
+ topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-scope-object.xml",
params );
+ topoFile = new File( config.getGatewayTopologyDir(), "knox694-4.xml" );
+ FileUtils.writeStringToFile( topoFile, topoStr );
+ topos.reloadTopologies();
+
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, pword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_OK )
+ .contentType( "text/plain" )
+ .body( is( "test-service-response" ) )
+ .when().log().ifError().get( gatewayUrl + "/knox694-4/test-service-path/test-resource-path"
);
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, invalidPword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_UNAUTHORIZED )
+ .when().get( gatewayUrl + "/knox694-4/test-service-path/test-resource-path" );
+
+ topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-scope-onelevel-positive.xml",
params );
+ topoFile = new File( config.getGatewayTopologyDir(), "knox694-5.xml" );
+ FileUtils.writeStringToFile( topoFile, topoStr );
+ topos.reloadTopologies();
+
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, pword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_OK )
+ .contentType( "text/plain" )
+ .body( is( "test-service-response" ) )
+ .when().log().ifError().get( gatewayUrl + "/knox694-5/test-service-path/test-resource-path"
);
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, invalidPword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_UNAUTHORIZED )
+ .when().get( gatewayUrl + "/knox694-5/test-service-path/test-resource-path" );
+
+ topoStr = TestUtils.merge( DAT, "topologies/test-knox694-principal-regex-search-scope-onelevel-negative.xml",
params );
+ topoFile = new File( config.getGatewayTopologyDir(), "knox694-6.xml" );
+ FileUtils.writeStringToFile( topoFile, topoStr );
+ topos.reloadTopologies();
+
+ given()
+ //.log().all()
+ .auth().preemptive().basic( uname, pword )
+ .expect()
+ //.log().all()
+ .statusCode( HttpStatus.SC_UNAUTHORIZED )
+ .when().get( gatewayUrl + "/knox694-6/test-service-path/test-resource-path" );
+
+ LOG_EXIT();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-attribute.xml
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-attribute.xml
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-attribute.xml
new file mode 100644
index 0000000..538f820
--- /dev/null
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-attribute.xml
@@ -0,0 +1,81 @@
+<!--
+ 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>authentication</role>
+ <name>ShiroProvider</name>
+ <enabled>true</enabled>
+ <param>
+ <name>main.ldapRealm</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+ </param>
+ <param>
+ <name>main.ldapContextFactory</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory</name>
+ <value>$ldapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.url</name>
+ <value>$LDAP_URL</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+ <value>simple</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemUsername</name>
+ <value>$LDAP_SYSTEM_USERNAME</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemPassword</name>
+ <value>$LDAP_SYSTEM_PASSWORD</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.principalRegex</name>
+ <value>(.*?)\\(.*)</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchBase</name>
+ <value>ou={1},dc=hadoop,dc=apache,dc=org</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchAttributeName</name>
+ <value>uid</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchAttributeTemplate</name>
+ <value>{2}</value>
+ </param>
+ <param>
+ <name>urls./**</name>
+ <value>authcBasic</value>
+ </param>
+ </provider>
+ <provider>
+ <role>identity-assertion</role>
+ <name>Default</name>
+ <enabled>true</enabled>
+ </provider>
+ </gateway>
+ <service>
+ <role>test-service-role</role>
+ </service>
+</topology>
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-filter.xml
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-filter.xml
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-filter.xml
new file mode 100644
index 0000000..31c9d5f
--- /dev/null
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-filter.xml
@@ -0,0 +1,77 @@
+<!--
+ 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>authentication</role>
+ <name>ShiroProvider</name>
+ <enabled>true</enabled>
+ <param>
+ <name>main.ldapRealm</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+ </param>
+ <param>
+ <name>main.ldapContextFactory</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory</name>
+ <value>$ldapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.url</name>
+ <value>$LDAP_URL</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+ <value>simple</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemUsername</name>
+ <value>$LDAP_SYSTEM_USERNAME</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemPassword</name>
+ <value>$LDAP_SYSTEM_PASSWORD</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.principalRegex</name>
+ <value>(.*?)\\(.*)</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchBase</name>
+ <value>ou={1},dc=hadoop,dc=apache,dc=org</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchFilter</name>
+ <value>(&(objectclass=person)(uid={2}))</value>
+ </param>
+ <param>
+ <name>urls./**</name>
+ <value>authcBasic</value>
+ </param>
+ </provider>
+ <provider>
+ <role>identity-assertion</role>
+ <name>Default</name>
+ <enabled>true</enabled>
+ </provider>
+ </gateway>
+ <service>
+ <role>test-service-role</role>
+ </service>
+</topology>
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-object.xml
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-object.xml
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-object.xml
new file mode 100644
index 0000000..c52bcc3
--- /dev/null
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-object.xml
@@ -0,0 +1,77 @@
+<!--
+ 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>authentication</role>
+ <name>ShiroProvider</name>
+ <enabled>true</enabled>
+ <param>
+ <name>main.ldapRealm</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+ </param>
+ <param>
+ <name>main.ldapContextFactory</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory</name>
+ <value>$ldapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.url</name>
+ <value>$LDAP_URL</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+ <value>simple</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemUsername</name>
+ <value>$LDAP_SYSTEM_USERNAME</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemPassword</name>
+ <value>$LDAP_SYSTEM_PASSWORD</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.principalRegex</name>
+ <value>(.*?)\\(.*)</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchBase</name>
+ <value>uid={2},ou={1},dc=hadoop,dc=apache,dc=org</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchScope</name>
+ <value>object</value>
+ </param>
+ <param>
+ <name>urls./**</name>
+ <value>authcBasic</value>
+ </param>
+ </provider>
+ <provider>
+ <role>identity-assertion</role>
+ <name>Default</name>
+ <enabled>true</enabled>
+ </provider>
+ </gateway>
+ <service>
+ <role>test-service-role</role>
+ </service>
+</topology>
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-negative.xml
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-negative.xml
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-negative.xml
new file mode 100644
index 0000000..efc1abd
--- /dev/null
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-negative.xml
@@ -0,0 +1,81 @@
+<!--
+ 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>authentication</role>
+ <name>ShiroProvider</name>
+ <enabled>true</enabled>
+ <param>
+ <name>main.ldapRealm</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+ </param>
+ <param>
+ <name>main.ldapContextFactory</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory</name>
+ <value>$ldapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.url</name>
+ <value>$LDAP_URL</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+ <value>simple</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemUsername</name>
+ <value>$LDAP_SYSTEM_USERNAME</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemPassword</name>
+ <value>$LDAP_SYSTEM_PASSWORD</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.principalRegex</name>
+ <value>(.*?)\\(.*)</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchBase</name>
+ <value>dc=hadoop,dc=apache,dc=org</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchFilter</name>
+ <value>(&(objectclass=person)(uid={2}))</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchScope</name>
+ <value>onelevel</value>
+ </param>
+ <param>
+ <name>urls./**</name>
+ <value>authcBasic</value>
+ </param>
+ </provider>
+ <provider>
+ <role>identity-assertion</role>
+ <name>Default</name>
+ <enabled>true</enabled>
+ </provider>
+ </gateway>
+ <service>
+ <role>test-service-role</role>
+ </service>
+</topology>
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-positive.xml
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-positive.xml
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-positive.xml
new file mode 100644
index 0000000..6706ca2
--- /dev/null
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-search-scope-onelevel-positive.xml
@@ -0,0 +1,81 @@
+<!--
+ 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>authentication</role>
+ <name>ShiroProvider</name>
+ <enabled>true</enabled>
+ <param>
+ <name>main.ldapRealm</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+ </param>
+ <param>
+ <name>main.ldapContextFactory</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory</name>
+ <value>$ldapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.url</name>
+ <value>$LDAP_URL</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+ <value>simple</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemUsername</name>
+ <value>$LDAP_SYSTEM_USERNAME</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.systemPassword</name>
+ <value>$LDAP_SYSTEM_PASSWORD</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.principalRegex</name>
+ <value>(.*?)\\(.*)</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchBase</name>
+ <value>ou={1},dc=hadoop,dc=apache,dc=org</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchFilter</name>
+ <value>(&(objectclass=person)(uid={2}))</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userSearchScope</name>
+ <value>onelevel</value>
+ </param>
+ <param>
+ <name>urls./**</name>
+ <value>authcBasic</value>
+ </param>
+ </provider>
+ <provider>
+ <role>identity-assertion</role>
+ <name>Default</name>
+ <enabled>true</enabled>
+ </provider>
+ </gateway>
+ <service>
+ <role>test-service-role</role>
+ </service>
+</topology>
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-user-dn-template.xml
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-user-dn-template.xml
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-user-dn-template.xml
new file mode 100644
index 0000000..2525a16
--- /dev/null
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/topologies/test-knox694-principal-regex-user-dn-template.xml
@@ -0,0 +1,65 @@
+<!--
+ 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>authentication</role>
+ <name>ShiroProvider</name>
+ <enabled>true</enabled>
+ <param>
+ <name>main.ldapRealm</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
+ </param>
+ <param>
+ <name>main.ldapContextFactory</name>
+ <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory</name>
+ <value>$ldapContextFactory</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.url</name>
+ <value>$LDAP_URL</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
+ <value>simple</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.principalRegex</name>
+ <value>(.*?)\\(.*)</value>
+ </param>
+ <param>
+ <name>main.ldapRealm.userDnTemplate</name>
+ <value>uid={2},ou={1},dc=hadoop,dc=apache,dc=org</value>
+ </param>
+ <param>
+ <name>urls./**</name>
+ <value>authcBasic</value>
+ </param>
+ </provider>
+ <provider>
+ <role>identity-assertion</role>
+ <name>Default</name>
+ <enabled>true</enabled>
+ </provider>
+ </gateway>
+ <service>
+ <role>test-service-role</role>
+ </service>
+</topology>
http://git-wip-us.apache.org/repos/asf/knox/blob/ce52a554/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/users.ldif
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/users.ldif
b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/users.ldif
index b982cb3..dd9f307 100644
--- a/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/users.ldif
+++ b/gateway-test/src/test/resources/org/apache/hadoop/gateway/GatewayMultiFuncTest/users.ldif
@@ -29,6 +29,18 @@ objectclass:top
objectclass:organizationalUnit
ou: people
+# entry for a sample admin user
+# please replace with site specific values
+dn: uid=admin,ou=people,dc=hadoop,dc=apache,dc=org
+objectclass:top
+objectclass:person
+objectclass:organizationalPerson
+objectclass:inetOrgPerson
+cn: Admin
+sn: Admin
+uid: admin
+userPassword:admin-password
+
# entry for a sample end user
# please replace with site specific values
dn: uid=guest,ou=people,dc=hadoop,dc=apache,dc=org
|