1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.authn;
18
19
20 import javax.naming.Context;
21 import javax.naming.NamingException;
22 import javax.naming.directory.Attribute;
23 import javax.naming.directory.Attributes;
24
25 import org.apache.ldap.common.exception.LdapAuthenticationException;
26 import org.apache.ldap.common.name.LdapName;
27 import org.apache.ldap.common.util.ArrayUtils;
28 import org.apache.ldap.common.aci.AuthenticationLevel;
29 import org.apache.ldap.server.jndi.ServerContext;
30 import org.apache.ldap.server.partition.DirectoryPartitionNexus;
31 import org.apache.ldap.server.partition.DirectoryPartitionNexusProxy;
32 import org.apache.ldap.server.invocation.Invocation;
33 import org.apache.ldap.server.invocation.InvocationStack;
34
35 import java.util.HashSet;
36 import java.util.Collections;
37 import java.util.Set;
38 import java.util.Collection;
39
40
41 /***
42 * A simple {@link Authenticator} that authenticates clear text passwords
43 * contained within the <code>userPassword</code> attribute in DIT.
44 *
45 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
46 */
47 public class SimpleAuthenticator extends AbstractAuthenticator
48 {
49 private static final Collection USERLOOKUP_BYPASS;
50
51 static
52 {
53 Set c = new HashSet();
54 c.add( "authenticationService" );
55 c.add( "authorizationService" );
56 c.add( "oldAuthorizationService" );
57 c.add( "schemaService" );
58 c.add( "subentryService" );
59 c.add( "operationalAttributeService" );
60 c.add( "eventService" );
61 USERLOOKUP_BYPASS = Collections.unmodifiableCollection( c );
62 }
63
64
65 /***
66 * Creates a new instance.
67 */
68 public SimpleAuthenticator( )
69 {
70 super( "simple" );
71 }
72
73
74 /***
75 * Looks up <tt>userPassword</tt> attribute of the entry whose name is
76 * the value of {@link Context#SECURITY_PRINCIPAL} environment variable,
77 * and authenticates a user with the plain-text password.
78 */
79 public LdapPrincipal authenticate( ServerContext ctx ) throws NamingException
80 {
81
82
83 Object creds = ctx.getEnvironment().get( Context.SECURITY_CREDENTIALS );
84
85 if ( creds == null )
86 {
87 creds = ArrayUtils.EMPTY_BYTE_ARRAY;
88 }
89 else if ( creds instanceof String )
90 {
91 creds = ( ( String ) creds ).getBytes();
92 }
93
94
95
96 String principal;
97
98 if ( ! ctx.getEnvironment().containsKey( Context.SECURITY_PRINCIPAL ) )
99 {
100 throw new LdapAuthenticationException();
101 }
102 else
103 {
104 principal = ( String ) ctx.getEnvironment().get( Context.SECURITY_PRINCIPAL );
105
106 if ( principal == null )
107 {
108 throw new LdapAuthenticationException();
109 }
110 }
111
112
113
114 LdapName principalDn = new LdapName( principal );
115 Invocation invocation = InvocationStack.getInstance().peek();
116 DirectoryPartitionNexusProxy proxy = invocation.getProxy();
117 Attributes userEntry;
118
119 try
120 {
121 userEntry = proxy.lookup( principalDn, new String[] {"userPassword"}, USERLOOKUP_BYPASS );
122 if ( userEntry == null )
123 {
124 throw new LdapAuthenticationException( "Failed to lookup user for authentication: " + principal );
125 }
126 }
127 catch( Exception cause )
128 {
129 LdapAuthenticationException e = new LdapAuthenticationException();
130 e.setRootCause( e );
131 throw e;
132 }
133
134
135 Object userPassword;
136
137 Attribute userPasswordAttr = userEntry.get( "userPassword" );
138
139
140
141 if ( userPasswordAttr == null )
142 {
143 userPassword = ArrayUtils.EMPTY_BYTE_ARRAY;
144 }
145 else
146 {
147 userPassword = userPasswordAttr.get();
148
149 if ( userPassword instanceof String )
150 {
151 userPassword = ( ( String ) userPassword ).getBytes();
152 }
153 }
154
155 if ( ! ArrayUtils.isEquals( creds, userPassword ) )
156 {
157 throw new LdapAuthenticationException();
158 }
159
160 return new LdapPrincipal( principalDn, AuthenticationLevel.SIMPLE );
161 }
162 }