KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > security > realm > providers > CertificatePropertiesFileLoginModule


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.security.realm.providers;
19
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.net.URI JavaDoc;
23 import java.security.cert.X509Certificate JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Properties JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.Collection JavaDoc;
32 import javax.security.auth.Subject JavaDoc;
33 import javax.security.auth.callback.Callback JavaDoc;
34 import javax.security.auth.callback.CallbackHandler JavaDoc;
35 import javax.security.auth.callback.UnsupportedCallbackException JavaDoc;
36 import javax.security.auth.login.LoginException JavaDoc;
37 import javax.security.auth.login.FailedLoginException JavaDoc;
38 import javax.security.auth.spi.LoginModule JavaDoc;
39 import javax.security.auth.x500.X500Principal JavaDoc;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.apache.geronimo.common.GeronimoSecurityException;
44 import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
45 import org.apache.geronimo.system.serverinfo.ServerInfo;
46
47
48 /**
49  * An example LoginModule that reads a list of users and group from a file on disk.
50  * Authentication is provided by the SSL layer supplying the client certificate.
51  * All we check is that it is present. The
52  * file should be formatted using standard Java properties syntax. Expects
53  * to be run by a GenericSecurityRealm (doesn't work on its own).
54  *
55  * The usersURI property file should have lines of the form token=certificatename
56  * where certificate name is X509Certificate.getSubjectX500Principal().getName()
57  *
58  * The groupsURI property file should have lines of the form group=token1,token2,...
59  * where the tokens were associated to the certificate names in the usersURI properties file.
60  *
61  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
62  */

63 public class CertificatePropertiesFileLoginModule implements LoginModule JavaDoc {
64     public final static String JavaDoc USERS_URI = "usersURI";
65     public final static String JavaDoc GROUPS_URI = "groupsURI";
66     private static Log log = LogFactory.getLog(CertificatePropertiesFileLoginModule.class);
67     private final Map JavaDoc users = new HashMap JavaDoc();
68     final Map JavaDoc groups = new HashMap JavaDoc();
69
70     Subject JavaDoc subject;
71     CallbackHandler JavaDoc handler;
72     X500Principal JavaDoc principal;
73
74     public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler, Map JavaDoc sharedState, Map JavaDoc options) {
75         this.subject = subject;
76         this.handler = callbackHandler;
77         try {
78             ServerInfo serverInfo = (ServerInfo) options.get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
79             URI JavaDoc usersURI = new URI JavaDoc((String JavaDoc)options.get(USERS_URI));
80             URI JavaDoc groupsURI = new URI JavaDoc((String JavaDoc)options.get(GROUPS_URI));
81             loadProperties(serverInfo, usersURI, groupsURI);
82         } catch (Exception JavaDoc e) {
83             log.error(e);
84             throw new IllegalArgumentException JavaDoc("Unable to configure properties file login module: "+e);
85         }
86     }
87
88     public void loadProperties(ServerInfo serverInfo, URI JavaDoc usersURI, URI JavaDoc groupURI) throws GeronimoSecurityException {
89         try {
90             URI JavaDoc userFile = serverInfo.resolve(usersURI);
91             URI JavaDoc groupFile = serverInfo.resolve(groupURI);
92             InputStream JavaDoc stream = userFile.toURL().openStream();
93             Properties JavaDoc tmpUsers = new Properties JavaDoc();
94             tmpUsers.load(stream);
95             stream.close();
96
97             for (Iterator JavaDoc iterator = tmpUsers.entrySet().iterator(); iterator.hasNext();) {
98                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
99                 users.put(entry.getValue(), entry.getKey());
100             }
101
102             Properties JavaDoc temp = new Properties JavaDoc();
103             stream = groupFile.toURL().openStream();
104             temp.load(stream);
105             stream.close();
106
107             Enumeration JavaDoc e = temp.keys();
108             while (e.hasMoreElements()) {
109                 String JavaDoc groupName = (String JavaDoc) e.nextElement();
110                 String JavaDoc[] userList = ((String JavaDoc) temp.get(groupName)).split(",");
111
112                 Set JavaDoc userset = (Set JavaDoc) groups.get(groupName);
113                 if (userset == null) {
114                     userset = new HashSet JavaDoc();
115                     groups.put(groupName, userset);
116                 }
117
118                 for (int i = 0; i < userList.length; i++) {
119                     String JavaDoc userName = userList[i];
120                     userset.add(userName);
121                 }
122             }
123
124         } catch (Exception JavaDoc e) {
125             log.error("Properties File Login Module - data load failed", e);
126             throw new GeronimoSecurityException(e);
127         }
128     }
129
130
131     public boolean login() throws LoginException JavaDoc {
132         Callback JavaDoc[] callbacks = new Callback JavaDoc[1];
133
134         callbacks[0] = new CertificateCallback();
135         try {
136             handler.handle(callbacks);
137         } catch (IOException JavaDoc ioe) {
138             throw (LoginException JavaDoc) new LoginException JavaDoc().initCause(ioe);
139         } catch (UnsupportedCallbackException JavaDoc uce) {
140             throw (LoginException JavaDoc) new LoginException JavaDoc().initCause(uce);
141         }
142         assert callbacks.length == 1;
143         X509Certificate JavaDoc certificate = ((CertificateCallback)callbacks[0]).getCertificate();
144         if (certificate == null) {
145             return false;
146         }
147         principal = certificate.getSubjectX500Principal();
148
149         if(!users.containsKey(principal.getName())) {
150             throw new FailedLoginException JavaDoc();
151         }
152         return true;
153     }
154
155     public boolean commit() throws LoginException JavaDoc {
156         Set JavaDoc principals = subject.getPrincipals();
157
158         principals.add(principal);
159         String JavaDoc userName = (String JavaDoc) users.get(principal.getName());
160         principals.add(new GeronimoUserPrincipal(userName));
161
162         Iterator JavaDoc e = groups.keySet().iterator();
163         while (e.hasNext()) {
164             String JavaDoc groupName = (String JavaDoc) e.next();
165             Set JavaDoc users = (Set JavaDoc) groups.get(groupName);
166             Iterator JavaDoc iter = users.iterator();
167             while (iter.hasNext()) {
168                 String JavaDoc user = (String JavaDoc) iter.next();
169                 if (userName.equals(user)) {
170                     principals.add(new GeronimoGroupPrincipal(groupName));
171                     break;
172                 }
173             }
174         }
175
176         return true;
177     }
178
179     public boolean abort() throws LoginException JavaDoc {
180         principal = null;
181
182         return true;
183     }
184
185     public boolean logout() throws LoginException JavaDoc {
186         principal = null;
187         //todo: should remove principals added by commit
188
return true;
189     }
190
191     /**
192      * Gets the names of all principal classes that may be populated into
193      * a Subject.
194      */

195     public String JavaDoc[] getPrincipalClassNames() {
196         return new String JavaDoc[]{GeronimoUserPrincipal.class.getName(), GeronimoGroupPrincipal.class.getName()};
197     }
198
199     /**
200      * Gets a list of all the principals of a particular type (identified by
201      * the principal class). These are available for manual role mapping.
202      */

203     public String JavaDoc[] getPrincipalsOfClass(String JavaDoc className) {
204         Collection JavaDoc s;
205         if(className.equals(GeronimoGroupPrincipal.class.getName())) {
206             s = groups.keySet();
207         } else if(className.equals(GeronimoUserPrincipal.class.getName())) {
208             s = users.values();
209         } else if(className.equals(X500Principal JavaDoc.class.getName())) {
210             s = users.keySet();
211         } else {
212             throw new IllegalArgumentException JavaDoc("No such principal class "+className);
213         }
214         return (String JavaDoc[]) s.toArray(new String JavaDoc[s.size()]);
215     }
216 }
217
Popular Tags