1 package org.springframework.security.ldap;
2
3 import org.springframework.security.BadCredentialsException;
4 import org.springframework.security.SpringSecurityMessageSource;
5 import org.springframework.context.MessageSource;
6 import org.springframework.context.MessageSourceAware;
7 import org.springframework.context.support.MessageSourceAccessor;
8 import org.springframework.ldap.core.support.LdapContextSource;
9 import org.springframework.util.Assert;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13
14 import javax.naming.Context;
15 import javax.naming.directory.DirContext;
16 import java.util.ArrayList;
17 import java.util.Hashtable;
18 import java.util.StringTokenizer;
19
20
21
22
23
24
25
26
27
28
29 public class DefaultSpringSecurityContextSource extends LdapContextSource implements SpringSecurityContextSource,
30 MessageSourceAware {
31
32 private static final Log logger = LogFactory.getLog(DefaultSpringSecurityContextSource.class);
33 private String rootDn;
34
35 protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
36
37
38
39
40
41
42 public DefaultSpringSecurityContextSource(String providerUrl) {
43 Assert.hasLength(providerUrl, "An LDAP connection URL must be supplied.");
44
45 StringTokenizer st = new StringTokenizer(providerUrl);
46
47 ArrayList urls = new ArrayList();
48
49
50 while (st.hasMoreTokens()) {
51 String url = st.nextToken();
52 String urlRootDn = LdapUtils.parseRootDnFromUrl(url);
53
54 urls.add(url.substring(0, url.lastIndexOf(urlRootDn)));
55
56 logger.info(" URL '" + url + "', root DN is '" + urlRootDn + "'");
57
58 if (rootDn == null) {
59 rootDn = urlRootDn;
60 } else if (!rootDn.equals(urlRootDn)) {
61 throw new IllegalArgumentException("Root DNs must be the same when using multiple URLs");
62 }
63 }
64
65 super.setUrls((String[]) urls.toArray(new String[urls.size()]));
66 super.setBase(rootDn);
67 }
68
69 public DirContext getReadWriteContext(String userDn, Object credentials) {
70 Hashtable env = new Hashtable(getAnonymousEnv());
71
72 env.put(Context.SECURITY_PRINCIPAL, userDn);
73 env.put(Context.SECURITY_CREDENTIALS, credentials);
74
75 if (logger.isDebugEnabled()) {
76 logger.debug("Creating context with principal: '" + userDn + "'");
77 }
78
79 try {
80 return createContext(env);
81 } catch (org.springframework.ldap.NamingException e) {
82 if ((e instanceof org.springframework.ldap.AuthenticationException)
83 || (e instanceof org.springframework.ldap.OperationNotSupportedException)) {
84 throw new BadCredentialsException(
85 messages.getMessage("DefaultSpringSecurityContextSource.badCredentials", "Bad credentials"), e);
86 }
87 throw e;
88 }
89 }
90
91 public void setMessageSource(MessageSource messageSource) {
92 this.messages = new MessageSourceAccessor(messageSource);
93 }
94 }