KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ldap > server > authn > AuthenticationService


1 /*
2  * Copyright 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.ldap.server.authn;
18
19
20 import org.apache.ldap.common.exception.LdapAuthenticationException;
21 import org.apache.ldap.common.exception.LdapAuthenticationNotSupportedException;
22 import org.apache.ldap.common.message.ResultCodeEnum;
23 import org.apache.ldap.common.util.StringTools;
24 import org.apache.ldap.server.interceptor.Interceptor;
25 import org.apache.ldap.server.interceptor.InterceptorContext;
26 import org.apache.ldap.server.interceptor.NextInterceptor;
27 import org.apache.ldap.server.invocation.Invocation;
28 import org.apache.ldap.server.jndi.EnvKeys;
29 import org.apache.ldap.server.jndi.ServerContext;
30 import org.apache.ldap.server.jndi.ServerLdapContext;
31
32 import javax.naming.Context JavaDoc;
33 import javax.naming.NamingException JavaDoc;
34 import java.lang.reflect.Constructor JavaDoc;
35 import java.util.*;
36
37
38 /**
39  * An {@link Interceptor} that authenticates users.
40  *
41  * @author Apache Directory Project (dev@directory.apache.org)
42  * @author Alex Karasulu (akarasulu@apache.org)
43  * @author Trustin Lee (trustin@apache.org)
44  * @version $Rev: 169198 $, $Date: 2005-05-08 20:05:59 -0400 (Sun, 08 May 2005) $
45  */

46 public class AuthenticationService implements Interceptor
47 {
48     /** short for Context.SECURITY_AUTHENTICATION */
49     private static final String JavaDoc AUTH_TYPE = Context.SECURITY_AUTHENTICATION;
50
51     /** short for Context.SECURITY_CREDENTIALS */
52     private static final String JavaDoc CREDS = Context.SECURITY_CREDENTIALS;
53
54     /** authenticators **/
55     public Map authenticators = new LinkedHashMap();
56
57
58     /**
59      * Creates an authentication service interceptor.
60      */

61     public AuthenticationService()
62     {
63     }
64
65     public void init( InterceptorContext ctx ) throws NamingException JavaDoc
66     {
67         /*
68          * Create and add the Authentication service interceptor to before
69          * interceptor chain.
70          */

71         boolean allowAnonymous = !ctx.getEnvironment().containsKey( EnvKeys.DISABLE_ANONYMOUS );
72
73         // create authenticator context
74

75         GenericAuthenticatorContext authenticatorContext = new GenericAuthenticatorContext();
76
77         authenticatorContext.setPartitionNexus( ctx.getRootNexus() );
78
79         authenticatorContext.setAllowAnonymous( allowAnonymous );
80
81         try // initialize default authenticators
82
{
83             // create anonymous authenticator
84

85             GenericAuthenticatorConfig authenticatorConfig = new GenericAuthenticatorConfig();
86
87             authenticatorConfig.setAuthenticatorName( "none" );
88
89             authenticatorConfig.setAuthenticatorContext( authenticatorContext );
90
91             org.apache.ldap.server.authn.Authenticator authenticator = new AnonymousAuthenticator();
92
93             authenticator.init( authenticatorConfig );
94
95             this.register( authenticator );
96
97             // create simple authenticator
98
authenticatorConfig = new GenericAuthenticatorConfig();
99
100             authenticatorConfig.setAuthenticatorName( "simple" );
101
102             authenticatorConfig.setAuthenticatorContext( authenticatorContext );
103
104             authenticator = new SimpleAuthenticator();
105
106             authenticator.init( authenticatorConfig );
107
108             this.register( authenticator );
109         }
110         catch ( Exception JavaDoc e )
111         {
112             throw new NamingException JavaDoc( e.getMessage() );
113         }
114
115         GenericAuthenticatorConfig[] configs = null;
116
117         configs = AuthenticatorConfigBuilder.getAuthenticatorConfigs( new Hashtable( ctx.getEnvironment() ) );
118
119         for ( int ii = 0; ii < configs.length; ii++ )
120         {
121             try
122             {
123                 configs[ii].setAuthenticatorContext( authenticatorContext );
124
125                 String JavaDoc authenticatorClass = configs[ii].getAuthenticatorClass();
126
127                 Class JavaDoc clazz = Class.forName( authenticatorClass );
128
129                 Constructor JavaDoc constructor = clazz.getConstructor( new Class JavaDoc[] { } );
130
131                 AbstractAuthenticator authenticator = ( AbstractAuthenticator ) constructor.newInstance( new Object JavaDoc[] { } );
132
133                 authenticator.init( configs[ii] );
134
135                 this.register( authenticator );
136             }
137             catch ( Exception JavaDoc e )
138             {
139                 e.printStackTrace();
140             }
141         }
142
143     }
144     
145     public void destroy()
146     {
147         authenticators.clear();
148     }
149
150     /**
151      * Registers an AuthenticationService with the AuthenticationService. Called by each
152      * AuthenticationService implementation after it has started to register for
153      * authentication operation calls.
154      *
155      * @param authenticator AuthenticationService component to register with this
156      * AuthenticatorService.
157      */

158     public void register( org.apache.ldap.server.authn.Authenticator authenticator )
159     {
160         Collection authenticatorList = getAuthenticators( authenticator.getAuthenticatorType() );
161
162         if ( authenticatorList == null )
163         {
164             authenticatorList = new ArrayList();
165
166             authenticators.put( authenticator.getAuthenticatorType(), authenticatorList );
167         }
168
169         authenticatorList.add( authenticator );
170     }
171
172     /**
173      * Unregisters an AuthenticationService with the AuthenticationService. Called for each
174      * registered AuthenticationService right before it is to be stopped. This prevents
175      * protocol server calls from reaching the Backend and effectively puts
176      * the ContextPartition's naming context offline.
177      *
178      * @param authenticator AuthenticationService component to unregister with this
179      * AuthenticationService.
180      */

181     public void unregister( org.apache.ldap.server.authn.Authenticator authenticator )
182     {
183         Collection authenticatorList = getAuthenticators( authenticator.getAuthenticatorType() );
184
185         if ( authenticatorList == null )
186         {
187             return;
188         }
189
190         authenticatorList.remove( authenticator );
191     }
192
193     /**
194      * Gets the authenticators with a specific type.
195      *
196      * @param type the authentication type
197      * @return the authenticators with the specified type
198      */

199     public Collection getAuthenticators( String JavaDoc type )
200     {
201         return ( Collection ) authenticators.get( type );
202     }
203     
204     public void process( NextInterceptor nextProcessor, Invocation call ) throws NamingException JavaDoc
205     {
206         // check if we are already authenticated and if so we return making
207
// sure first that the credentials are not exposed within context
208
ServerContext ctx = ( ServerLdapContext ) call.getContextStack().peek();
209
210         if ( ctx.getPrincipal() != null )
211         {
212             if ( ctx.getEnvironment().containsKey( CREDS ) )
213             {
214                 ctx.removeFromEnvironment( CREDS );
215             }
216
217             nextProcessor.process(call);
218
219             return;
220         }
221
222         String JavaDoc authList = ( String JavaDoc ) ctx.getEnvironment().get( AUTH_TYPE );
223
224         if ( authList == null )
225         {
226             if ( ctx.getEnvironment().containsKey( CREDS ) )
227             {
228                 // authentication type is simple here
229

230                 authList = "simple";
231             }
232             else
233             {
234                 // authentication type is anonymous
235

236                 authList = "none";
237             }
238
239         }
240
241         authList = StringTools.deepTrim( authList );
242
243         String JavaDoc[] auth = authList.split( " " );
244
245         Collection authenticators = null;
246
247         // pick the first matching authenticator type
248

249         for ( int i=0; i<auth.length; i++)
250         {
251             authenticators = getAuthenticators( auth[i] );
252
253             if ( authenticators != null )
254             {
255                 break;
256             }
257         }
258
259         if ( authenticators == null )
260         {
261             ctx.getEnvironment(); // shut's up idea's yellow light
262

263             ResultCodeEnum rc = ResultCodeEnum.AUTHMETHODNOTSUPPORTED;
264
265             throw new LdapAuthenticationNotSupportedException( rc );
266         }
267
268         // try each authenticators
269
for ( Iterator i = authenticators.iterator(); i.hasNext(); )
270         {
271             try
272             {
273                 Authenticator authenticator = ( Authenticator ) i.next();
274
275                 // perform the authentication
276

277                 LdapPrincipal authorizationId = authenticator.authenticate( ctx );
278
279                 // authentication was successful
280

281                 ctx.setPrincipal( new TrustedPrincipalWrapper( authorizationId ) );
282
283                 // remove creds so there is no security risk
284

285                 ctx.removeFromEnvironment( CREDS );
286
287                 nextProcessor.process(call);
288
289                 return;
290             }
291             catch ( LdapAuthenticationException e )
292             {
293                 // authentication failed, try the next authenticator
294
}
295         }
296
297         throw new LdapAuthenticationException();
298     }
299
300
301     /**
302      * Created this wrapper to pass to ctx.setPrincipal() which is public for added
303      * security. This adds more security because an instance of this class is not
304      * easily accessible whereas LdapPrincipals can be accessed easily from a context
305      * althought they cannot be instantiated outside of the authn package. Malicious
306      * code may not be able to set the principal to what they would like but they
307      * could switch existing principals using the now public ServerContext.setPrincipal()
308      * method. To avoid this we make sure that this metho takes a TrustedPrincipalWrapper
309      * as opposed to the LdapPrincipal. Only this service can create and call setPrincipal
310      * with a TrustedPrincipalWrapper.
311      */

312     public final class TrustedPrincipalWrapper
313     {
314         /** the wrapped ldap principal */
315         private final LdapPrincipal principal;
316
317
318         /**
319          * Creates a TrustedPrincipalWrapper around an LdapPrincipal.
320          *
321          * @param principal the LdapPrincipal to wrap
322          */

323         private TrustedPrincipalWrapper( LdapPrincipal principal )
324         {
325             this.principal = principal;
326         }
327
328
329         /**
330          * Gets the LdapPrincipal this TrustedPrincipalWrapper wraps.
331          *
332          * @return the wrapped LdapPrincipal
333          */

334         public LdapPrincipal getPrincipal()
335         {
336             return principal;
337         }
338     }
339 }
340
Popular Tags