diff --git a/sandbox/src/main/java/org/springframework/ldap/authentication/ThreadLocalAuthenticationHolder.java b/sandbox/src/main/java/org/springframework/ldap/authentication/ThreadLocalAuthenticationHolder.java
new file mode 100644
index 00000000..405c9871
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ldap/authentication/ThreadLocalAuthenticationHolder.java
@@ -0,0 +1,60 @@
+package org.springframework.ldap.authentication;
+
+/**
+ * Holder for ThreadLocal values of principal and credentials, used by
+ * {@link ThreadLocalAuthenticationSource} to get its values.
+ *
+ * @author Mattias Arthursson
+ *
+ */
+public class ThreadLocalAuthenticationHolder {
+ private static ThreadLocal threadPrincipal = new ThreadLocal();
+
+ private static ThreadLocal threadCredentials = new ThreadLocal();
+
+ /**
+ * Not to be instantiated.
+ */
+ private ThreadLocalAuthenticationHolder() {
+ }
+
+ /**
+ * Set the ThreadLocal principal DN.
+ *
+ * @param principal
+ * the principal to be returned in this thread by
+ * {@link ThreadLocalAuthenticationSource#getPrincipal()}.
+ */
+ public static void setPrincipal(String principal) {
+ threadPrincipal.set(principal);
+ }
+
+ /**
+ * Set the ThreadLocal credentials.
+ *
+ * @param credentials
+ * the credentials to be returned in this thread by
+ * {@link ThreadLocalAuthenticationSource#getCredentials()}.
+ */
+ public static void setCredentials(String credentials) {
+ threadCredentials.set(credentials);
+ }
+
+ /**
+ * Get the currently bound principal.
+ *
+ * @return the currently bound principal.
+ */
+ public static String getPrincipal() {
+ return (String) threadPrincipal.get();
+ }
+
+ /**
+ * Get the currently bound credentials.
+ *
+ * @return the currently bound credentials.
+ */
+ public static String getCredentials() {
+ return (String) threadCredentials.get();
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ldap/authentication/ThreadLocalAuthenticationSource.java b/sandbox/src/main/java/org/springframework/ldap/authentication/ThreadLocalAuthenticationSource.java
new file mode 100644
index 00000000..57398115
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ldap/authentication/ThreadLocalAuthenticationSource.java
@@ -0,0 +1,75 @@
+package org.springframework.ldap.authentication;
+
+import org.springframework.ldap.core.AuthenticationSource;
+
+/**
+ * {@link AuthenticationSource} to be used if the principal and credentials
+ * should be returned on a ThreadLocal basis. With this
+ * AuthenticationSource, the {@link #getPrincipal()} and
+ * {@link #getCredentials()} methods return the values set using
+ * {@link ThreadLocalAuthenticationHolder#setPrincipal(String)} and
+ * {@link ThreadLocalAuthenticationHolder#setCredentials(String)} respectively,
+ * thus enabling use of a singleton ContextSource but still enabling the
+ * authentication information to be thread specific.
+ *
+ * This AuthenticationSource can be used e.g. to implement a
+ * simple authentication mechanism using ContextSource, like so:
+ *
+ * Configuration: + *
+ * <bean id="abstractContextSource" abstract="true" + * class="org.springframework.ldap.core.support.LdapContextSource" > + * ... Common configuration here ... + * </bean> + * + * <bean id="contextSource" + * parent="abstractContextSource" > + * <property name="userName" value="..." /> + * <property name="password" value="..." /> + * </bean> + * + * <bean id="authenticationContextSource" + * parent="abstractContextSource" > + * <property name="authenticationSource"> + * <bean class="org.springframework.ldap.authentication.ThreadLocalAuthenticationSource" /> + * </property> + * </bean> + *+ *
+ * Authentication code: + *
+ * public class MyDao {
+ * private ContextSource authenticationContextSource;
+ *
+ * public void setAuthenticationContextSource(ContextSource contextSource){
+ * this.authenticationContextSource = contextSource;
+ * }
+ *
+ * ...
+ *
+ * public boolean authenticate(String userDN, String credentials){
+ * ThreadLocalAuthenticationHolder.setPrincipal(userDN);
+ * ThreadLocalAuthenticationHolder.setCredentials(credentials);
+ *
+ * try{
+ * authenticationContextSource.getReadWriteContext();
+ * return true;
+ * }catch(Exception e){
+ * return false;
+ * }
+ * }
+ * }
+ *
+ *
+ * @author Mattias Arthursson
+ *
+ */
+public class ThreadLocalAuthenticationSource implements AuthenticationSource {
+ public String getCredentials() {
+ return ThreadLocalAuthenticationHolder.getCredentials();
+ }
+
+ public String getPrincipal() {
+ return ThreadLocalAuthenticationHolder.getPrincipal();
+ }
+}