KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > console > core > security > PropertiesFileLoginModuleNoCache


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

17
18 package org.apache.geronimo.console.core.security;
19
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.net.URI JavaDoc;
23 import java.security.MessageDigest JavaDoc;
24 import java.security.NoSuchAlgorithmException JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Set JavaDoc;
32
33 import javax.security.auth.Subject JavaDoc;
34 import javax.security.auth.callback.Callback JavaDoc;
35 import javax.security.auth.callback.CallbackHandler JavaDoc;
36 import javax.security.auth.callback.NameCallback JavaDoc;
37 import javax.security.auth.callback.PasswordCallback JavaDoc;
38 import javax.security.auth.callback.UnsupportedCallbackException JavaDoc;
39 import javax.security.auth.login.LoginException JavaDoc;
40 import javax.security.auth.spi.LoginModule JavaDoc;
41
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.apache.geronimo.common.GeronimoSecurityException;
45 import org.apache.geronimo.kernel.Kernel;
46 import org.apache.geronimo.kernel.KernelRegistry;
47 import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
48 import org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal;
49 import org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal;
50 import org.apache.geronimo.system.serverinfo.ServerInfo;
51 import org.apache.geronimo.util.encoders.HexTranslator;
52
53 /**
54  * @version $Rev: 480049 $ $Date: 2006-11-28 09:06:46 -0500 (Tue, 28 Nov 2006) $
55  */

56 public class PropertiesFileLoginModuleNoCache implements LoginModule JavaDoc {
57
58     Kernel kernel;
59
60     ServerInfo serverInfo;
61
62     URI JavaDoc usersURI;
63
64     URI JavaDoc groupsURI;
65
66     public final static String JavaDoc USERS_URI = "usersURI";
67
68     public final static String JavaDoc GROUPS_URI = "groupsURI";
69
70     public final static String JavaDoc DIGEST = "digest";
71
72     private static Log log = LogFactory
73             .getLog(PropertiesFileLoginModuleNoCache.class);
74
75     final Properties JavaDoc users = new Properties JavaDoc();
76
77     final Map JavaDoc groups = new HashMap JavaDoc();
78
79     private String JavaDoc digest;
80
81     Subject JavaDoc subject;
82
83     CallbackHandler JavaDoc handler;
84
85     String JavaDoc username;
86
87     String JavaDoc password;
88
89     public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler,
90             Map JavaDoc sharedState, Map JavaDoc options) {
91         this.subject = subject;
92         this.handler = callbackHandler;
93         try {
94             kernel = KernelRegistry.getKernel((String JavaDoc) options
95                     .get(JaasLoginModuleUse.KERNEL_NAME_LM_OPTION));
96             serverInfo = (ServerInfo) options
97                     .get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
98             usersURI = new URI JavaDoc((String JavaDoc) options.get(USERS_URI));
99             groupsURI = new URI JavaDoc((String JavaDoc) options.get(GROUPS_URI));
100             digest = (String JavaDoc) options.get(DIGEST);
101             if(digest != null && !digest.equals("")) {
102                 // Check if the digest algorithm is available
103
try {
104                     MessageDigest.getInstance(digest);
105                 } catch(NoSuchAlgorithmException JavaDoc e) {
106                     log.error("Initialization failed. Digest algorithm "+digest+" is not available.", e);
107                     throw new IllegalArgumentException JavaDoc("Unable to configure properties file login module: "+e.getMessage());
108                 }
109             }
110         } catch (Exception JavaDoc e) {
111             log.error(e);
112             throw new IllegalArgumentException JavaDoc(
113                     "Unable to configure properties file login module: " + e);
114         }
115     }
116
117     public void loadProperties(Kernel kernel, ServerInfo serverInfo,
118             URI JavaDoc userURI, URI JavaDoc groupURI) throws GeronimoSecurityException {
119         try {
120             URI JavaDoc userFile = serverInfo.resolve(userURI);
121             URI JavaDoc groupFile = serverInfo.resolve(groupURI);
122             InputStream JavaDoc stream = userFile.toURL().openStream();
123             // always get a fresh group of users.
124
users.clear();
125             users.load(stream);
126             stream.close();
127
128             Properties JavaDoc temp = new Properties JavaDoc();
129             stream = groupFile.toURL().openStream();
130             temp.load(stream);
131             stream.close();
132             // refresh groups.
133
groups.clear();
134             Enumeration JavaDoc e = temp.keys();
135             while (e.hasMoreElements()) {
136                 String JavaDoc groupName = (String JavaDoc) e.nextElement();
137                 String JavaDoc[] userList = ((String JavaDoc) temp.get(groupName)).split(",");
138
139                 Set JavaDoc userset = (Set JavaDoc) groups.get(groupName);
140                 if (userset == null) {
141                     userset = new HashSet JavaDoc();
142                     groups.put(groupName, userset);
143                 }
144
145                 for (int i = 0; i < userList.length; i++) {
146                     userset.add(userList[i]);
147                 }
148             }
149
150         } catch (Exception JavaDoc e) {
151             log.error("Properties File Login Module - data load failed", e);
152             throw new GeronimoSecurityException(e);
153         }
154     }
155
156     public boolean login() throws LoginException JavaDoc {
157         // This is the fundamental modification to the parent class. load
158
// properties before login.
159
loadProperties(kernel, serverInfo, usersURI, groupsURI);
160
161         Callback JavaDoc[] callbacks = new Callback JavaDoc[2];
162
163         callbacks[0] = new NameCallback JavaDoc("User name");
164         callbacks[1] = new PasswordCallback JavaDoc("Password", false);
165         try {
166             handler.handle(callbacks);
167         } catch (IOException JavaDoc ioe) {
168             throw (LoginException JavaDoc) new LoginException JavaDoc().initCause(ioe);
169         } catch (UnsupportedCallbackException JavaDoc uce) {
170             throw (LoginException JavaDoc) new LoginException JavaDoc().initCause(uce);
171         }
172         assert callbacks.length == 2;
173         username = ((NameCallback JavaDoc) callbacks[0]).getName();
174         if (username == null || username.equals("")) {
175             return false;
176         }
177         password = users.getProperty(username);
178
179         return checkPassword(password, new String JavaDoc((((PasswordCallback JavaDoc) callbacks[1]).getPassword())));
180     }
181
182     public boolean commit() throws LoginException JavaDoc {
183         Set JavaDoc principals = subject.getPrincipals();
184
185         principals.add(new GeronimoUserPrincipal(username));
186
187         Iterator JavaDoc e = groups.keySet().iterator();
188         while (e.hasNext()) {
189             String JavaDoc groupName = (String JavaDoc) e.next();
190             Set JavaDoc users = (Set JavaDoc) groups.get(groupName);
191             Iterator JavaDoc iter = users.iterator();
192             while (iter.hasNext()) {
193                 String JavaDoc user = (String JavaDoc) iter.next();
194                 if (username.equals(user)) {
195                     principals.add(new GeronimoGroupPrincipal(groupName));
196                     break;
197                 }
198             }
199         }
200
201         return true;
202     }
203
204     public boolean abort() throws LoginException JavaDoc {
205         username = null;
206         password = null;
207
208         return true;
209     }
210
211     public boolean logout() throws LoginException JavaDoc {
212         username = null;
213         password = null;
214
215         return true;
216     }
217
218     /**
219      * Gets the names of all principal classes that may be populated into a
220      * Subject.
221      */

222     public String JavaDoc[] getPrincipalClassNames() {
223         return new String JavaDoc[] { GeronimoUserPrincipal.class.getName(),
224                 GeronimoGroupPrincipal.class.getName() };
225     }
226
227     /**
228      * Gets a list of all the principals of a particular type (identified by the
229      * principal class). These are available for manual role mapping.
230      */

231     public String JavaDoc[] getPrincipalsOfClass(String JavaDoc className) {
232         Set JavaDoc s;
233         if (className.equals(GeronimoGroupPrincipal.class.getName())) {
234             s = groups.keySet();
235         } else if (className.equals(GeronimoUserPrincipal.class.getName())) {
236             s = users.keySet();
237         } else {
238             throw new IllegalArgumentException JavaDoc("No such principal class "
239                     + className);
240         }
241         return (String JavaDoc[]) s.toArray(new String JavaDoc[s.size()]);
242     }
243
244     /**
245      * This method checks if the provided password is correct. The original password may have been digested.
246      * @param real Original password in digested form if applicable
247      * @param provided User provided password in clear text
248      * @return true If the password is correct
249      */

250     private boolean checkPassword(String JavaDoc real, String JavaDoc provided){
251         if(digest == null || digest.equals("")) {
252             // No digest algorithm is used
253
return real.equals(provided);
254         }
255         try {
256             // Digest the user provided password
257
MessageDigest JavaDoc md = MessageDigest.getInstance(digest);
258             byte[] data = md.digest(provided.getBytes());
259             // Convert bytes to hex digits
260
byte[] hexData = new byte[data.length * 2];
261             HexTranslator ht = new HexTranslator();
262             ht.encode(data, 0, data.length, hexData, 0);
263             // Compare the digested provided password with the actual one
264
return real.equalsIgnoreCase(new String JavaDoc(hexData));
265         } catch (NoSuchAlgorithmException JavaDoc e) {
266             // Should not occur. Availability of algorithm has been checked at initialization
267
log.error("Should not occur. Availability of algorithm has been checked at initialization.", e);
268         }
269         return false;
270     }
271 }
272
Popular Tags