libspring-ldap-java-1.3.1.RELEASE.orig/ 0002777 0000000 0000000 00000000000 11550465534 014264 5 ustar libspring-ldap-java-1.3.1.RELEASE.orig/docs/ 0002755 0000000 0000000 00000000000 11550465534 015210 5 ustar libspring-ldap-java-1.3.1.RELEASE.orig/docs/docbkx/ 0002755 0000000 0000000 00000000000 11550465534 016462 5 ustar libspring-ldap-java-1.3.1.RELEASE.orig/docs/docbkx/configuration.xml 0000644 0000000 0000000 00000043404 11131412553 022042 0 ustar
Configuration
ContextSource Configuration
There are several properties in AbstractContextSource
(superclass of DirContextSource and LdapContextSource)
that can be used to modify its behaviour.
LDAP Server URLs
The URL of the LDAP server is specified using the url property.
The URL should be in the format ldap://myserver.example.com:389.
For SSL access, use the ldaps protocol and the appropriate port, e.g.
ldaps://myserver.example.com:636
It is possible to configure multiple alternate LDAP servers using the
urls property. In this case, supply all server urls in a String
array to the urls property.
Base LDAP path
It is possible to specify the root context for all LDAP operations using the
base property of AbstractContextSource.
When a value has been specified to this property, all Distinguished Names supplied to and received from LDAP operations
will be relative to the LDAP path supplied. This can significantly simplify working against the LDAP
tree; however there are several occations when you will need to have access to the base path.
For more information on this, please refer to
DirContext Authentication
When DirContext instances are created to be used for performing
operations on an LDAP server these contexts often need to be authenticated. There are
different options for configuring this using Spring LDAP, described in this chapter.
This section refers to authenticating contexts in the core functionality
of the ContextSource - to construct DirContext instances
for use by LdapTemplate. LDAP is commonly used for the sole purpose
of user authentication, and the ContextSource may be used for that as
well. This process is discussed in .
Authenticated contexts are created for both read-only and
read-write operations by default. You specify
userDn and password of the LDAP
user to be used for authentication on the
ContextSource.
The userDn needs to be the full
Distinguished Name (DN) of the user from the root of the LDAP tree,
regardless of whether a base LDAP path has been supplied to
the ContextSource.
Some LDAP server setups allow anonymous read-only access. If you
want to use anonymous Contexts for read-only operations, set the
anonymousReadOnly property to
true.
Custom DirContext Authentication Processing
The default authentication mechanism used in Spring LDAP is SIMPLE authentication.
This means that in the user DN (as specified to the userDn property) and
the credentials (as specified to the password) are set in
the Hashtable sent to the DirContext implementation constructor.
There are many occasions when this processing is not sufficient. For instance,
LDAP Servers are commonly set up to only accept communication on a secure TLS channel;
there might be a need to use the particular LDAP Proxy Auth mechanism, etc.
It is possible to specify an alternative authentication mechanism by supplying a
DirContextAuthenticationStrategy implementation to the ContextSource
in the configuration.
TLS
Spring LDAP provides two different configuration options for LDAP servers requiring TLS secure
channel communication: DefaultTlsDirContextAuthenticationStrategy and
ExternalTlsDirContextAuthenticationStrategy. Both these
implementations will negotiate a TLS channel on the target connection, but they differ in the actual authentication mechanism.
Whereas the DefaultTlsDirContextAuthenticationStrategy will apply SIMPLE authentication
on the secure channel (using the specified userDn and password),
the ExternalDirContextAuthenticationStrategy will use EXTERNAL SASL authentication,
applying a client certificate configured using system properties for authentication.
Since different LDAP server implementations respond differently to explicit shutdown of the
TLS channel (some servers require the connection be shutdown gracefully; others do not support it),
the TLS DirContextAuthenticationStrategy implementations support specifying
the shutdown behavior using the shutdownTlsGracefully parameter. If this
property is set to false (the default), no explicit TLS shutdown will happen;
if it is true, Spring LDAP will try to shutdown the TLS channel gracefully
before closing the target context.
When working with TLS connections you need to make sure that the native LDAP
Pooling functionality is turned off. As of release 1.3, the default setting is off. For earlier
versions, simply set the pooled property to false. This is
particularly important if shutdownTlsGracefully is set to false.
However, since the TLS channel negotiation process is quite expensive, great performance benefits will
be gained by using the Spring LDAP Pooling Support, described in .
Custom Principal and Credentials Management
While the user name (i.e. user DN) and password used for
creating an authenticated Context are static by
default - the ones set on the ContextSource on
startup will be used throughout the lifetime of the
ContextSource - there are however several cases in
which this is not the desired behaviour. A common scenario is that the
principal and credentials of the current user should be used when
executing LDAP operations for that user. The default behaviour can be
modified by supplying a custom AuthenticationSource
implementation to the ContextSource on startup,
instead of explicitly specifying the userDn and
password. The
AuthenticationSource will be queried by the
ContextSource for principal and credentials each
time an authenticated Context is to be
created.
If you are using Spring Security
you can make sure the principal and credentials of the currently logged in user
is used at all times by configuring your ContextSource
with an instance of the SpringSecurityAuthenticationSource
shipped with Spring Security.
The Spring bean definition for a
SpringSecurityAuthenticationSource
<beans>
...
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="authenticationSource" ref="springSecurityAuthenticationSource" />
</bean>
<bean id="springSecurityAuthenticationSource"
class="org.springframework.security.ldap.SpringSecurityAuthenticationSource" />
...
</beans>
We don't specify any userDn or
password to our ContextSource
when using an AuthenticationSource - these
properties are needed only when the default behaviour is
used.
When using the SpringSecurityAuthenticationSource
you need to use Spring Security's
LdapAuthenticationProvider to authenticate the
users against LDAP.
Default Authentication
When using SpringSecurityAuthenticationSource,
authenticated contexts will only be possible to create once the user
is logged in using Spring Security. To use default authentication information
when no user is logged in, use the
DefaultValuesAuthenticationSourceDecorator:
Configuring a
DefaultValuesAuthenticationSourceDecorator
<beans>
...
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="authenticationSource" ref="authenticationSource" />
</bean>
<bean id="authenticationSource"
class="org.springframework.ldap.authentication.DefaultValuesAuthenticationSourceDecorator">
<property name="target" ref="springSecurityAuthenticationSource" />
<property name="defaultUser" value="cn=myDefaultUser" />
<property name="defaultPassword" value="pass" />
</bean>
<bean id="springSecurityAuthenticationSource"
class="org.springframework.security.ldap.SpringSecurityAuthenticationSource" />
...
</beans>
Native Java LDAP Pooling
The internal Java LDAP provider provides some very basic pooling capabilities.
This LDAP connection pooling can be turned on/off using the
pooled flag on AbstractContextSource.
The default value is false (since release 1.3), i.e. the native
Java LDAP pooling will be turned on. The configuration of LDAP connection pooling is managed using
System properties, so this needs to be handled
manually, outside of the Spring Context configuration. Details of the native pooling configuration
can be found here.
There are several serious deficiencies in the built-in LDAP connection pooling,
which is why Spring LDAP provides a more sophisticated approach to LDAP connection pooling,
described in . If pooling functionality is required, this is the
recommended approach.
Advanced ContextSource Configuration
Alternate ContextFactory
It is possible to configure the ContextFactory that the
ContextSource is to use when creating Contexts using the
contextFactory property. The default value is
com.sun.jndi.ldap.LdapCtxFactory.
Custom DirObjectFactory
As described in , a DirObjectFactory
can be used to translate the Attributes of found Contexts
to a more useful DirContext implementation. This can be
configured using the dirObjectFactory property. You can use
this property if you have your own, custom DirObjectFactory implementation.
The default value is DefaultDirObjectFactory.
Custom DirContext Environment Properties
In some cases the user might want to specify additional environment setup properties
in addition to the ones directly configurable from AbstractContextSource.
Such properties should be set in a Map and supplied to
the baseEnvironmentProperties property.
LdapTemplate Configuration
Ignoring PartialResultExceptions
Some Active Directory (AD) servers are unable to automatically following
referrals, which often leads to a PartialResultException being
thrown in searches. You can specify that PartialResultException
is to be ignored by setting the ignorePartialResultException
property to true.
This causes all referrals to be ignored, and no notice will be given that
a PartialResultException has been encountered.
There is currently no way of manually following referrals using LdapTemplate.
Obtaining a reference to the base LDAP path
As described above, a base LDAP path may be supplied to the ContextSource,
specifying the root in the LDAP tree to which all operations will be relative. This means that
you will only be working with relative distinguished names throughout your system, which is
typically rather handy. There are however some cases in which you will need to have access
to the base path in order to be able to construct full DNs, relative to the actual root of the LDAP tree.
One example would be when working with LDAP groups (e.g. groupOfNames objectclass),
in which case each group member attribute value will need to be the full DN of the referenced member.
For that reason, Spring LDAP has a mechanism by which any Spring controlled bean may be supplied
the base path on startup. For beans to be notified of the base path, two things need to be in place:
First of all, the bean that wants the base path reference needs to implement the
BaseLdapPathAware interface. Secondly, a BaseLdapPathBeanPostProcessor
needs to be defined in the application context
Implementing BaseLdapPathAware
package com.example.service;
public class PersonService implements PersonService, BaseLdapPathAware {
...
private DistinguishedName basePath;
public void setBaseLdapPath(DistinguishedName basePath) {
this.basePath = basePath;
}
...
private DistinguishedName getFullPersonDn(Person person) {
return new DistinguishedName(basePath).append(person.getDn());
}
...
}
Specifying a BaseLdapPathBeanPostProcessor in your ApplicationContext
<beans>
...
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="authenticationSource" ref="authenticationSource" />
</bean>
...
<bean class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" />
</beans>
The default behaviour of the BaseLdapPathBeanPostProcessor is to use the base path of the single
defined BaseLdapPathSource (AbstractContextSource )in the ApplicationContext.
If more than one BaseLdapPathSource is defined, you will need to specify which one to use with the
baseLdapPathSourceName property.
libspring-ldap-java-1.3.1.RELEASE.orig/docs/docbkx/index.xml 0000644 0000000 0000000 00000003047 11470260546 020312 0 ustar
Spring LDAP - Reference Documentation
&version;
Mattias
Arthursson
Ulrik
Sandberg
Eric
Dalquist
Keith
Barlow
Copies of this document may be made for your own use and
for distribution to others, provided that you do not
charge any fee for such copies and further provided that
each copy contains this Copyright Notice, whether
distributed in print or electronically.
libspring-ldap-java-1.3.1.RELEASE.orig/docs/docbkx/transactions.xml 0000644 0000000 0000000 00000032500 11337444401 021703 0 ustar
Transaction Support
Introduction
Programmers used to working with relational databases coming to the LDAP
world often express surprise to the fact that there is no notion of transactions.
It is not specified in the protocol, and thus no servers support it.
Recognizing that this may be a major problem, Spring LDAP provides support for client-side,
compensating transactions on LDAP resources.
LDAP transaction support is provided by ContextSourceTransactionManager, a
PlatformTransactionManager implementation that manages Spring transaction
support for LDAP operations. Along with its collaborators it keeps track of the LDAP operations
performed in a transaction, making record of the state before each operation and taking steps to
restore the initial state should the transaction need to be rolled back.
In addition to the actual transaction management, Spring LDAP transaction support also
makes sure that the same DirContext instance will be used throughout the same transaction,
i.e. the DirContext will not actually be closed until the transaction is finished,
allowing for more efficient resources usage.
It is important to note that while the approach used by Spring LDAP to provide transaction support
is sufficient for many cases it is by no means "real" transactions in the traditional sense.
The server is completely unaware of the transactions, so e.g. if the connection is broken there will
be no hope to rollback the transaction. While this should be carefully considered it should also be noted
that the alternative will be to operate without any transaction support whatsoever; this is pretty much
as good as it gets.
The client side transaction support will add some overhead in addition to the work required
by the original operations. While this overhead should not be something to worry about in most cases,
if your application will not perform several LDAP operations within the same
transaction (e.g. a modifyAttributes followed by a rebind), or
if transaction synchronization with a JDBC data source is not required (see below) there will be nothing to gain
by using the LDAP transaction support.
Configuration
Configuring Spring LDAP transactions should look very familiar if you're used to configuring Spring transactions.
You will create a TransactionManager instance and wrap your target object using a
TransactionProxyFactoryBean. In addition to this, you will also need to wrap your
ContextSource in a TransactionAwareContextSourceProxy.
<beans>
...
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="userDn" value="cn=Manager" />
<property name="password" value="secret" />
</bean>
<bean id="contextSource"
class="org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy">
<constructor-arg ref="contextSourceTarget" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>
<bean id="transactionManager"
class="org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager">
<property name="contextSource" ref="contextSource" />
</bean>
<bean id="myDataAccessObjectTarget" class="com.example.MyDataAccessObject">
<property name="ldapTemplate" ref="ldapTemplate" />
</bean>
<bean id="myDataAccessObject"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="target" ref="myDataAccessObjectTarget" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRES_NEW</prop>
</props>
</property>
</bean>
...
In a real world example you would probably apply the transactions on the service object level
rather than the DAO level; the above serves as an example to demonstrate the general idea.
You'll notice that the actual ContextSource and DAO instances get ids with a
"Target" suffix. The beans you will actually refer to are the Proxies that are created
around the targets; contextSource and myDataAccessObject
JDBC Transaction Integration
A common use case when working against LDAP is that some of the data is stored in the LDAP tree, but
other data is stored in a relational database. In this case, transaction support becomes even more important,
since the update of the different resources should be synchronized.
While actual XA transactions is not supported, support is provided to conceptually wrap JDBC and LDAP
access within the same transaction using the ContextSourceAndDataSourceTransactionManager.
A DataSource and a ContextSource is supplied to the
ContextSourceAndDataSourceTransactionManager, which will then manage the two transactions,
virtually as if they were one. When performing a commit, the LDAP part of the operation will always
be performed first, allowing both transactions to be rolled back should the LDAP commit fail. The JDBC
part of the transaction is managed exactly as in DataSourceTransactionManager, except that
nested transactions is not supported.
Once again it should be noted that the provided support is all client side. The wrapped transaction is not
an XA transaction. No two-phase as such commit is performed, as the LDAP server will be unable to vote on its outcome.
Once again, however, for the majority of cases the supplied support will be sufficient.
LDAP Compensating Transactions Explained
Spring LDAP manages compensating transactions by making record of the state in the LDAP tree
before each modifying operation (bind, unbind, rebind,
modifyAttributes, and rename).
This enables the system
to perform compensating operations should the transaction need to be rolled back. In many cases the
compensating operation is pretty straightforward. E.g. the compensating rollback operation for a
bind operation will quite obviously be to unbind the entry. Other operations however require
a different, more complicated approach because of some particular characteristics of LDAP databases. Specifically,
it is not always possible to get the values of all Attributes of an entry, making the above
strategy insufficient for e.g. an unbind operation.
This is why each modifying operation performed within a Spring LDAP managed transaction is internally
split up in four distinct operations - a recording operation, a preparation operation, a commit operation,
and a rollback operation. The specifics for each LDAP operation is described in the table below:
LDAP Operation
Recording
Preparation
Commit
Rollback
bind
Make record of the DN of the entry to bind.
Bind the entry.
No operation.
Unbind the entry using the recorded DN.
rename
Make record of the original and target DN.
Rename the entry.
No operation.
Rename the entry back to its original DN.
unbind
Make record of the original DN and calculate a temporary DN.
Rename the entry to the temporary location.
Unbind the temporary entry.
Rename the entry from the temporary location back to its original DN.
rebind
Make record of the original DN and the new Attributes, and calculate a temporary DN.
Rename the entry to a temporary location.
Bind the new Attributes at the original DN, and unbind the original entry
from its temporary location.
Rename the entry from the temporary location back to its original DN.
modifyAttributes
Make record of the DN of the entry to modify and calculate compensating ModificationItems
for the modifications to be done.
Perform the modifyAttributes operation.
No operation.
Perform a modifyAttributes operation using the calculated compensating
ModificationItems.
A more detailed description of the internal workings of the Spring LDAP transaction support is available in the
javadocs.
Renaming Strategies
As described in the table above, the transaction management of some operations require the original entry affected
by the operation to be temporarily renamed before the actual modification can be made in the commit.
The manner in which the temporary DN of the entry is calculated is managed by a TempEntryRenamingStrategy
supplied to the ContextSourceTransactionManager. Two implementations are supplied with Spring LDAP,
but if specific behaviour is required a custom implementation can easily be implemented by the user. The
provided TempEntryRenamingStrategy implementations are:
DefaultTempEntryRenamingStrategy (the default). Adds a suffix to the least significant
part of the entry DN. E.g. for the DN cn=john doe, ou=users, this strategy would return the
temporary DN cn=john doe_temp, ou=users. The suffix is configurable using the tempSuffix
property
DifferentSubtreeTempEntryRenamingStrategy. Takes the least significant part of the DN
and appends a subtree DN to this. This makes all temporary entries be placed at a specific location in the LDAP tree.
The temporary subtree DN is configured using the subtreeNode property. E.g., if
subtreeNode is ou=tempEntries and the original DN of the entry is
cn=john doe, ou=users, the temporary DN will be cn=john doe, ou=tempEntries.
Note that the configured subtree node needs to be present in the LDAP tree.
There are some situations where the DefaultTempEntryRenamingStrategy will not work. E.g. if your are planning
to do recursive deletes you'll need to use DifferentSubtreeTempEntryRenamingStrategy. This is because
the recursive delete operation actually consists of a depth-first delete of each node in the sub tree individually.
Since it is not allowed to rename an entry that has any children, and DefaultTempEntryRenamingStrategy would
leave each node in the same subtree (with a different name) in stead of actually removing it, this operation would fail.
When in doubt, use DifferentSubtreeTempEntryRenamingStrategy.