KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > security > realm > web > catalina55 > JAAS


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 2004 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: JAAS.java,v 1.2 2005/04/28 08:43:26 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas.security.realm.web.catalina55;
27
28 import java.security.Principal JavaDoc;
29 import java.security.acl.Group JavaDoc;
30 import java.security.cert.X509Certificate JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.Iterator JavaDoc;
34
35 import javax.security.auth.Subject JavaDoc;
36 import javax.security.auth.login.AccountExpiredException JavaDoc;
37 import javax.security.auth.login.CredentialExpiredException JavaDoc;
38 import javax.security.auth.login.FailedLoginException JavaDoc;
39 import javax.security.auth.login.LoginContext JavaDoc;
40 import javax.security.auth.login.LoginException JavaDoc;
41
42 import org.objectweb.util.monolog.api.BasicLevel;
43 import org.objectweb.util.monolog.api.Logger;
44
45 import org.objectweb.jonas.common.Log;
46 import org.objectweb.jonas.security.auth.callback.NoInputCallbackHandler;
47
48 import org.apache.catalina.LifecycleException;
49 import org.apache.catalina.realm.GenericPrincipal;
50 import org.apache.catalina.realm.RealmBase;
51
52 import org.objectweb.security.context.SecurityContext;
53 import org.objectweb.security.context.SecurityCurrent;
54
55
56 /**
57  * <p>Implementation of a JAAS Realm. (by a wrapper)
58  * It uses the entry JAAS_CONFIG_NAME from the JAAS config file
59  * @author Florent Benoit
60  * @author Alexandre Thaveau (JAAS support with JOnAS)
61  * @author Marc-Antoine Bourgeot (JAAS support with JOnAS)
62  */

63 public class JAAS extends RealmBase {
64
65     /**
66      * Descriptive information about this Realm implementation.
67      */

68     private static final String JavaDoc NAME = "JRealmJAASCatalina50";
69
70     /**
71      * Descriptive information about this Realm implementation.
72      */

73     private static final String JavaDoc INFO = "org.objectweb.jonas.security.realm.JRealmJAASCatalina50/1.0";
74
75     /**
76      * Name used in the JAAS config file
77      */

78     private static final String JavaDoc JAAS_CONFIG_NAME = "tomcat";
79
80     /**
81      * The logger used in JOnAS
82      */

83     private static Logger logger = null;
84
85     /**
86      * User Certificate
87      */

88     private X509Certificate JavaDoc cert = null;
89
90
91     /**
92      * Return descriptive information about this Realm implementation and
93      * the corresponding version number, in the format
94      * <code>&lt;description&gt;/&lt;version&gt;</code>.
95      * @return the info.
96      */

97     public String JavaDoc getInfo() {
98         return INFO;
99     }
100
101     /**
102      * Return the Principal associated with the specified X.509 certificate Distinguished Name
103      * if there is one; otherwise return <code>null</code>.
104      * @param cert X.509 Certificate of the user
105      * @return the principal associated
106      */

107     public Principal JavaDoc authenticate(X509Certificate JavaDoc[] cert) {
108         String JavaDoc headerCertificate = "##DN##";
109         //concat the header certificate and replace the caracters
110
String JavaDoc dn = headerCertificate.concat(cert[0].getSubjectDN().getName().replace('=', '#').replace(',', '%').replace(' ', '$'));
111         this.cert = cert[0];
112         return authenticate(dn, "");
113     }
114
115     /**
116      * Return the Principal associated with the specified username and
117      * credentials, if there is one; otherwise return <code>null</code>.
118      *
119      * @param username Username of the Principal to look up
120      * @param credentials Password or other credentials to use in
121      * authenticating this username
122      * @return the principal associated
123      */

124     public Principal JavaDoc authenticate(String JavaDoc username, String JavaDoc credentials) {
125
126         // No authentication can be made with a null username
127
if (username == null) {
128             log("No username so no authentication");
129             return null;
130         }
131         // Establish a LoginContext to use for authentication
132
LoginContext JavaDoc loginContext = null;
133         try {
134             loginContext = new LoginContext JavaDoc(JAAS_CONFIG_NAME, new NoInputCallbackHandler(username, credentials, this.cert));
135         } catch (LoginException JavaDoc e) {
136             logger.log(BasicLevel.ERROR, "loginException for user :" + username);
137             return null;
138         }
139         // Negotiate a login via this LoginContext
140
Subject JavaDoc subject = null;
141         try {
142             loginContext.login();
143             subject = loginContext.getSubject();
144             if (subject == null) {
145                 if (logger.isLoggable(BasicLevel.ERROR)) {
146                     logger.log(BasicLevel.ERROR, "failedLoginlogin for user :" + username);
147                 }
148                 return null;
149             }
150         } catch (AccountExpiredException JavaDoc e) {
151             if (logger.isLoggable(BasicLevel.ERROR)) {
152                 logger.log(BasicLevel.ERROR, "accountExpired for user :" + username);
153             }
154             return null;
155         } catch (CredentialExpiredException JavaDoc e) {
156             if (logger.isLoggable(BasicLevel.ERROR)) {
157                 logger.log(BasicLevel.ERROR, "credentialExpired for user :" + username);
158             }
159             return null;
160         } catch (FailedLoginException JavaDoc e) {
161             if (logger.isLoggable(BasicLevel.ERROR)) {
162                 logger.log(BasicLevel.ERROR, "failedLogin for user :" + username);
163             }
164             return null;
165         } catch (LoginException JavaDoc e) {
166             if (logger.isLoggable(BasicLevel.ERROR)) {
167                 logger.log(BasicLevel.ERROR, "loginException for user :" + username);
168             }
169             return null;
170         }
171
172         // Get credentials iterators from the subject
173
Iterator JavaDoc credentialsIterator = subject.getPrivateCredentials().iterator();
174         String JavaDoc credential = (String JavaDoc) credentialsIterator.next();
175
176         // Retrieve first principal name found (without groups)
177
Iterator JavaDoc iterator = subject.getPrincipals(Principal JavaDoc.class).iterator();
178         String JavaDoc userName = null;
179         while (iterator.hasNext() && (userName == null)) {
180             Principal JavaDoc principal = (Principal JavaDoc) iterator.next();
181             if (!(principal instanceof Group JavaDoc)) {
182                userName = principal.getName();
183             }
184         }
185
186         // No name --> error
187
if (userName == null) {
188             logger.log(BasicLevel.ERROR, "No Username found in the subject");
189             return null;
190         }
191
192         // Retrieve all roles of the user (Roles are members of the Group.class)
193
iterator = subject.getPrincipals(Group JavaDoc.class).iterator();
194         ArrayList JavaDoc roles = new ArrayList JavaDoc();
195         while (iterator.hasNext()) {
196             Group JavaDoc group = (Group JavaDoc) iterator.next();
197             Enumeration JavaDoc e = group.members();
198             while (e.hasMoreElements()) {
199                 Principal JavaDoc p = (Principal JavaDoc) e.nextElement();
200                 roles.add(p.getName());
201             }
202         }
203
204         GenericPrincipal principal = new GenericPrincipal(this, userName, credential, roles);
205         //instanciation of the security context
206
SecurityContext ctx = new SecurityContext(userName, roles);
207         SecurityCurrent current = SecurityCurrent.getCurrent();
208         current.setSecurityContext(ctx);
209
210         return principal;
211     }
212
213
214     /**
215      * Return a short name for this Realm implementation.
216      * @return the name
217      */

218     protected String JavaDoc getName() {
219         return NAME;
220     }
221
222
223     /**
224      * Return the password associated with the given principal's user name.
225      * @param username the given principal's user name.
226      * @return the password associated.
227      */

228     protected String JavaDoc getPassword(String JavaDoc username) {
229         return null;
230     }
231
232
233     /**
234      * Return the Principal associated with the given user name.
235      * @param username the given principal's user name.
236      * @return the Principal associated
237      */

238     protected Principal JavaDoc getPrincipal(String JavaDoc username) {
239         return null;
240     }
241
242
243     /**
244      * Prepare for active use of the public methods of this Component.
245      *
246      * @exception LifecycleException if this component detects a fatal error
247      * that prevents it from being started
248      */

249     public synchronized void start() throws LifecycleException {
250
251         if (logger == null) {
252             logger = Log.getLogger(Log.JONAS_SECURITY_PREFIX);
253         }
254
255         // Perform normal superclass initialization
256
super.start();
257
258     }
259
260
261     /**
262      * Gracefully shut down active use of the public methods of this Component.
263      *
264      * @exception LifecycleException if this component detects a fatal error
265      * that needs to be reported
266      */

267     public synchronized void stop() throws LifecycleException {
268         // Perform normal superclass finalization
269
super.stop();
270    }
271
272
273     /**
274      * Log a message on the Logger associated with our Container (if any)
275      *
276      * @param message Message to be logged
277      */

278     protected void log(String JavaDoc message) {
279         if (logger.isLoggable(BasicLevel.DEBUG)) {
280             logger.log(BasicLevel.DEBUG, message);
281         }
282     }
283
284
285 }
286
Popular Tags