You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "Roytman, Alex" <ro...@peacetech.com> on 2001/04/03 01:45:42 UTC

JNDI & LDAP Realm for Tomcat 4.0 & Tomcat 3.2x alpha3 available: NEED YOUR FEEDBACK!

Dear tomcat users and developers,

This is an implementation of JNDI and LDAP realm for Tomcat 3 and 4 
I would greatly appreciate you feedback regarding its functionality. 

Alex Roytman

download from http://www.peacetech.com/java/files/apache/tomcat/

JndiRealm authenticates and authorizes users against JNDI. It was tested
against LDAP JNDI
with Sun's and Netscape's jndi providers
LdapRealm authenticates and authorizes users directly against LDAP using
Netscape LDAP JDK.
These two realms are interchangeable you can switch between them without
many configuration changes.
According to my tests it performs 10 faster under 20 concurrent threads than
JNDI with
Sun's LDAP provider. This is not final result because I need to test and
tune-up multithreaded
access and synchronization there might be some misunderstanding on my part.
I also noticed some cases of JNDI loosing connection to the server under
heavy multithreaded
load while Netscape's LDAP handled it nicely.
There are four classes in the package :
  JndiRealm and LdapRealm are for Tomcat 3.2x
  JndiRealmCatalina and LdapRealmCatalina for Tomcat 4.0

className="com.peacetech.webtools.tomcat.JndiRealm"           JNDI TOMCAT
3.2x
className="com.peacetech.webtools.tomcat.JndiRealmCatalina"   JNDI TOMCAT
4.0
className="com.peacetech.webtools.tomcat.LdapRealmCatalina"   LDAP TOMCAT
4.0
className="com.peacetech.webtools.tomcat.LdapRealm"           LDAP TOMCAT
3.2x

Jndi/LdapRealm uses searchBindDN and searchBindCredentials to connect to a
directory.
Then it looks for exactly one user name matching searchFilter in
searchBaseContext
scoped by searchScopeAsString (values are "base", "one", "sub" according to
LDAP URL rules)
If one and only one matching directory object is found it will use this
object and
tomcat supplied credentials to authenticate the user.
If successful Realm will fetch user roles using JNDI attributes listed in
securityAttributes
(comma separated directory attribute names). If attributesReadByOwner =
"true" Realm will use
authenticated user itself to pool the attributes from directory otherwise it
will use searchBindDN
to retrieve the attributes.
If roleMapperClass is specified Realm will use it to map user roles onto
application roles
specific for each web context for tomcat 3.2x and specific for each defined
Realm for tomcat 4.2.
Provided SimpleRoleMapper implementation will read role map from either
roleMapperSourceUrl
(if specified) or for tomcat 3.2x from WEB-INF/role-map.xml file in each web
context
if no roleMapperSourceUrl was defined (if WEB-INF/role-map.xml file does not
exist in a context
no mapping for this context will occur)


PARAMETERS:

jndiInitialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory"
                            (or "com.netscape.jndi.ldap.LdapContextFactory")
This attribute for JndiRealm ONLY.
It corresponds to javax.naming.Context.INITIAL_CONTEXT_FACTORY

directoryUrl = "ldap://207.176.93.66:389"
This attribute for both JndiRealm and LdapRealm.
It corresponds to javax.naming.Context.PROVIDER_URL

jndiSecurityAuthentication = "simple"
This attribute for JndiRealm ONLY.
It corresponds to javax.naming.Context.SECURITY_AUTHENTICATION

jndiSecurityProtocol = "" ("" vendor default or "ssl", or vendor specific)
This attribute for JndiRealm ONLY.
It corresponds to javax.naming.Context.SECURITY_PROTOCOL

searchBindDN = "cn=ldap-user,o=pti"
This attribute for both JndiRealm and LdapRealm. User name to bind to
directory
a to perform user name lookups. It corresponds to
javax.naming.Context.SECURITY_PRINCIPAL

searchBindCredentials = "mypassword"
This attribute for both JndiRealm and LdapRealm. Password for searchBindDN
It corresponds to javax.naming.Context.SECURITY_CREDENTIALS

searchBaseContext = "o=pti"
Base context for user lookups

ldapVersion = "3"
This attribute for LdapRealm ONLY. Defines LDAP version.

searchScopeAsString = "base" | "one" | "sub"
defines search scope "base" - object scope, "one" - one level scope, "sub" -
subtree scope.

attributesReadByOwner = "true"
defines who will read securityAttribures from the directory. If "true"
authenticating user account
will be used to retrieve the roles otherwise the searchBindDN account used
for user name lookups will
fetch the attributes. It is useful when either one or the other do not have
permission to read the
attributes so you can chose the one which has this permissions

searchFilter = "cn={0}"
Filter to lookup authorizing user. Support java.text.MessageFormat.
The only parameter is to java.text.MessageFormat pattern authorizing
username.
i.e. jndiSearchFilter = "cn={0}" for user alex will result in lookup for
"cn=alex"

securityAttributes = "securityEquals"
One or more directory attributes separated with semicolon which contains
security roles
attributes can be multivalued. If blank no attempt to retrieve roles from
directory will be done

roleMapperClass = "com.peacetech.webtools.tomcat.SimpleRoleMapper"/>
ATTNTION: It requires SAX2/JAX1.1 (Apache Xerces or Sun JAXP1.1
distribution)
Implemntation of RoleMapper interface to be used to transform user directory
roles
to application roles. In tomcat 3.2x MapperClass is server wide but actual
mapping data
is context specific (unless you specified roleMapperSourceUrl)
in tomcat 4.0 both RoleMapper and mapping data are Realm specific and you
have to specify
roleMapperSourceUrl. If it is blank no role mapping will occur

roleMapperSourceUrl="file:///d:/tomcat4/conf/my-role-map.xml"
URL to RoleMapper source. In tomcat 3.2x if it is not specified we try to
find file
WEB-INF/role-map.xml in every initializing tomcat context.

connectionMaxPoolSize = 10
JNDI does not allow multi-threaded access to a single context instance. We
pool contexts which
do user filter lookup instead creating and re-authenticating every time.
Access to pool
is synchronized. In LdapPrincipal factory we pool user connection so we
reauthenticate without reconnecting

SAMPLES:

TOMCAT 4:
<Realm className="com.peacetech.webtools.tomcat.LdapRealmCatalina"
  debug="1"
  directoryUrl = "ldap://207.176.93.66:389"
  searchBindDN = "cn=ldap-user,o=pti"
  searchBindCredentials = "mypassword"
  searchBaseContext = "o=pti"
  searchFilter = "cn={0}"
  searchScopeAsString = "sub"
  securityAttributes = "securityEquals"
  attributesReadByOwner = "true"
  connectionMaxPoolSize = "10"
  ldapVersion = "3"
  roleMapperClass = "com.peacetech.webtools.tomcat.SimpleRoleMapper"
 
roleMapperSourceUrl="file:///z:/Projects/Gao/gwiz/web/gwiz/WEB-INF/role-map.
xml" />

<Realm className="com.peacetech.webtools.tomcat.JndiRealmCatalina"
  debug="1"
  jndiInitialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory"
  jndiSecurityAuthentication = "simple"
  directoryUrl = "ldap://207.176.93.66:389"
  jndiSecurityProtocol = ""
  searchBindDN = "cn=ldap-user,o=pti"
  searchBindCredentials = "mypassword"
  searchBaseContext = "o=pti"
  searchFilter = "cn={0}"
  searchScopeAsString = "sub"
  securityAttributes = "securityEquals"
  attributesReadByOwner = "true"
  connectionMaxPoolSize = "10"
  roleMapperClass = "com.peacetech.webtools.tomcat.SimpleRoleMapper"
 
roleMapperSourceUrl="file:///z:/Projects/Gao/gwiz/web/gwiz/WEB-INF/role-map.
xml" />



TOMCAT 3:
<RequestInterceptor className="com.peacetech.webtools.tomcat.LdapRealm"
  debug="1"
  directoryUrl = "ldap://207.176.93.66:389"
  searchBindDN = "cn=ldap-user,o=pti"
  searchBindCredentials = "mypassword"
  searchBaseContext = "o=pti"
  searchFilter = "cn={0}"
  searchScopeAsString = "sub"
  securityAttributes = "securityEquals"
  attributesReadByOwner = "true"
  connectionMaxPoolSize = "10"
  ldapVersion = "3"
  roleMapperClass = "com.peacetech.webtools.tomcat.SimpleRoleMapper"
 
roleMapperSourceUrl="file:///z:/Projects/Gao/gwiz/web/gwiz/WEB-INF/role-map.
xml" />

<RequestInterceptor className="com.peacetech.webtools.tomcat.JndiRealm"
  debug="1"
  jndiInitialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory"
  jndiSecurityAuthentication = "simple"
  directoryUrl = "ldap://207.176.93.66:389"
  jndiSecurityProtocol = ""
  searchBindDN = "cn=ldap-user,o=pti"
  searchBindCredentials = "mypassword"
  searchBaseContext = "o=pti"
  searchFilter = "cn={0}"
  searchScopeAsString = "sub"
  securityAttributes = "securityEquals"
  attributesReadByOwner = "true"
  connectionMaxPoolSize = "10"
  roleMapperClass = "com.peacetech.webtools.tomcat.SimpleRoleMapper"
 
roleMapperSourceUrl="file:///z:/Projects/Gao/gwiz/web/gwiz/WEB-INF/role-map.
xml" />