KNOX-242-support basedn, search attribute based LDAP authentication

Summary

 

At present (as of Knox-0.4.0),  LDAP authentication in Knox infers the baseDN of the user using UserDNTemplate and the login id given by client user.

This does not work in enterprises where users could belong to multiple branches of LDAP tree.

This JIRA proposes adding LDAP search to find the bind DN.

Description

Problem with  LDAP Authentication in Knox at present (as of Knox 0.4.0)

 

Knox uses Apache Shiro for doing authentication of clients using LDAP userId and password.

Knox does this using either JNDILdapRealm bundled with Apache Shiro or KnoxLdapRealm implemented by Apache Knox.

Apache Knox KnoxLdapRealm is a subclass of Apache Shiro JNDILdapRealm, adding  group lookup feature.

 

JNDILdapRealm and KnoxLdapRealm have a configuration parameter ldapRealm.userDnTemplate.

Typical value of userDNTemplate would look like uid={0},ou=people,dc=hadoop,dc=apache,dc=org.

 

To compute bind DN of the client,  we swap the place holder  {0} with login id provided by the client.

For example, if the login id provided by the client is  "guest',  the computed bind DN would be uid=guest,ou=people,dc=hadoop,dc=apache,dc=org.

 

This keeps configuration simple.

However, this does not work if users belong to different branches of LDAP DIT.

For example, if there are some users under ou=people,dc=hadoop,dc=apache,dc=org and some users under ou=contractors,dc=hadoop,dc=apache,dc=org,  we can not come up with userDnTemplate that would work for all the users.

 

Proposed Enhancement

 

We would add following additional  optional configuration parameters:  ldapRealm.userSearchAttributeName,  ldapRealm.userObjectClass

ldapRealm.userSearchAttributeName


This is an optional parameter.

There is no default value for this parameter. If a value is specified for this parameter, we would find bind DN by doing ldapsearch.

If no value is specified for this parameter,  we compute bind DN using userDnTemplate as we are already doing.

ldapRealm.userObjectClass

 

This is an optional parameter with default value of "person".

Example search filter to find the client bind DN

 

Assuming,  

ldapRealm.userSearchAttributeName=uid

ldapRealm.userObjectClass=person

client  specified login id =  "guest"

 

LDAP Filter for doing a search to find the bind DN would be

(&(uid=guest)(objectclass=person))

 

Bind Credentials for the search to find the client bind DN

 

System bind DN to search for client bind DN is specified by the property ldapRealm.contextFactory.systemUsername.

Password for system bind DN is specified by the property ldapRealm.contextFactory.systemPassword.

 

Value of ldapRealm.contextFactory.systemPassword can reference password alias using  the format ${ALIAS=ldcSystemPassword}.

If the password alias reference is used, password is obtained from credential store at runtime.

Search Scope for the search to find the client bind DN

 

Search scope for search to find  the client bind DN can be specified with parameter ldapRealm.userSearchBase.

If no value is specified for  ldapRealm.userSearchBase,  it would default to the value of ldapRealm.searchBase.

 

Sample Shiro Section of Topology file illustrating KnoxLdapRealm parameters

New parameters added by this enhancement are shown in bold

 

<provider>
<role>authentication</role>
<name>ShiroProvider</name>
<enabled>true</enabled>
<param>
<!--
session timeout in minutes, this is really idle timeout,
defaults to 30mins, if the property value is not defined,,
current client authentication would expire if client idles contiuosly for more than this value
-->
<name>sessionTimeout</name>
<value>30</value>
</param>

<param>
<name>main.ldapRealm</name>
<value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
</param>

<param>
<name>main.ldapRealm.contextFactory.url</name>
<value>ldap://localhost:33389</value>
</param>

<!-- optional, default value: simple -->
<param>
<name>main.ldapRealm.contextFactory.authenticationMechanism</name>
<value>simple</value>
</param>

<!-- optional, default value: null -->
<param>
<name>main.ldapRealm.contextFactory.systemUsername</name>
<value>uid=guest,ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>

<!-- optional, default value: null -->
<param>
<name>main.ldapRealm.contextFactory.systemPassword</name>
<!--
<value>${ALIAS=ldcSystemPassword}</value>
-->
<value>guest-password</value>
</param>

<param>
<name>main.ldapRealm.searchBase</name>
<value>dc=hadoop,dc=apache,dc=org</value>
</param>

<!-- optional, default value: empty -->
<param>
<name>main.ldapRealm.userDnTemplate</name>
<value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>


<!-- optional, default value: null -->
<param>
<name>main.ldapRealm.userSearchAttributeName</name>
<value>uid</value>
</param>

<!-- optional, default value: person -->
<param>
<name>main.ldapRealm.userObjectClass</name>
<value>person</value>
</param>

<!-- optional, default value: value of main.ldapRealm.searchBasae -->
<param>
<name>main.ldapRealm.userSearchBase</name>
<value>ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>

<!-- optional, default value: false -->
<param>
<name>main.ldapRealm.authorizationEnabled</name>
<value>true</value>
</param>

<!-- optional, default value: uid={0} -->
<param>
<name>main.ldapRealm.memberAttributeValueTemplate</name>
<value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>

<!-- optional, default value: value of main.ldapRealm.searchBasae -->
<param>
<name>main.ldapRealm.groupSearchBase</name>
<value>ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>

<!-- optional, default value: groupOfNames -->
<param>
<name>main.ldapRealm.groupObjectClass</name>
<!--
<value>groupOfNames</value>
-->
<value>groupOfUrls</value>
</param>

<!-- optional, default value: member -->
<param>
<name>main.ldapRealm.memberAttribute</name>
<!--
<value>member</value>
-->
<value>memberUrl</value>
</param>

<!-- optional, default value: cn -->
<param>
<name>main.ldapRealm.groupIdAttribute</name>
<value>cn</value>
</param>

<param>
<name>urls./**</name>
<value>authcBasic</value>
</param>

</provider>

 

 

 

 

 

 

 

 

 

 

 

  • No labels