KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > security > jaas > JaasLoginCoordinator


1 /**
2  *
3  * Copyright 2003-2004 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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 package org.apache.geronimo.security.jaas;
18
19 import java.security.Principal JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.HashSet JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Set JavaDoc;
27 import javax.security.auth.Subject JavaDoc;
28 import javax.security.auth.callback.Callback JavaDoc;
29 import javax.security.auth.callback.CallbackHandler JavaDoc;
30 import javax.security.auth.login.LoginException JavaDoc;
31 import javax.security.auth.spi.LoginModule JavaDoc;
32
33 import org.apache.geronimo.kernel.KernelRegistry;
34 import org.apache.geronimo.kernel.Kernel;
35 import org.apache.geronimo.security.remoting.jmx.JaasLoginServiceRemotingClient;
36
37 /**
38  * A LoginModule implementation which connects to a Geronimo server under
39  * the covers, and uses Geronimo realms to resolve the login. It handles a
40  * mix of client-side and server-side login modules. It treats any client
41  * side module as something it should manage and execute, while a server side
42  * login module would be managed and executed by the Geronimo server.
43  *
44  * Note that this can actually be run from within a Geronimo server, in which
45  * case the client/server distinction is somewhat less important, and the
46  * communication is optimized by avoiding network traffic.
47  *
48  * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
49  */

50 public class JaasLoginCoordinator implements LoginModule JavaDoc {
51     public final static String JavaDoc OPTION_HOST = "host";
52     public final static String JavaDoc OPTION_PORT = "port";
53     public final static String JavaDoc OPTION_KERNEL = "kernel";
54     public final static String JavaDoc OPTION_REALM = "realm";
55     private String JavaDoc serverHost;
56     private int serverPort;
57     private String JavaDoc realmName;
58     private String JavaDoc kernelName;
59     private JaasLoginServiceMBean service;
60     private CallbackHandler JavaDoc handler;
61     private Subject JavaDoc subject;
62     private Set JavaDoc processedPrincipals = new HashSet JavaDoc();
63     private JaasLoginModuleConfiguration[] config;
64     private JaasClientId client;
65     LoginModuleConfiguration[] workers;
66
67     public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler,
68                            Map JavaDoc sharedState, Map JavaDoc options) {
69         serverHost = (String JavaDoc) options.get(OPTION_HOST);
70         Object JavaDoc port = options.get(OPTION_PORT);
71         if(port != null) {
72             serverPort = Integer.parseInt((String JavaDoc)port);
73         }
74         realmName = (String JavaDoc) options.get(OPTION_REALM);
75         kernelName = (String JavaDoc) options.get(OPTION_KERNEL);
76         service = connect();
77         handler = callbackHandler;
78         if(subject == null) {
79             this.subject = new Subject JavaDoc();
80         } else {
81             this.subject = subject;
82         }
83         //todo: shared state
84
}
85
86     public boolean login() throws LoginException JavaDoc {
87         client = service.connectToRealm(realmName);
88         config = service.getLoginConfiguration(client);
89         workers = new LoginModuleConfiguration[config.length];
90         for (int i = 0; i < workers.length; i++) {
91             LoginModule JavaDoc wrapper;
92             if(config[i].isServerSide()) {
93                 wrapper = new ServerLoginModule(i);
94             } else {
95                 LoginModule JavaDoc source = config[i].getLoginModule(JaasLoginCoordinator.class.getClassLoader());
96                 wrapper = new ClientLoginModule(source, i);
97             }
98             workers[i] = new LoginModuleConfiguration(wrapper, config[i].getFlag());
99             workers[i].getModule().initialize(subject, handler, new HashMap JavaDoc(), config[i].getOptions());
100         }
101         return LoginUtils.computeLogin(workers);
102     }
103
104     public boolean commit() throws LoginException JavaDoc {
105         for (int i = 0; i < workers.length; i++) {
106             workers[i].getModule().commit();
107         }
108         Principal JavaDoc[] principals = service.loginSucceeded(client);
109         for (int i = 0; i < principals.length; i++) {
110             Principal JavaDoc principal = principals[i];
111             subject.getPrincipals().add(principal);
112         }
113         return true;
114     }
115
116     public boolean abort() throws LoginException JavaDoc {
117         try {
118             for (int i = 0; i < workers.length; i++) {
119                 workers[i].getModule().abort();
120             }
121         } finally {
122             service.loginFailed(client);
123         }
124         clear();
125         return true;
126     }
127
128     public boolean logout() throws LoginException JavaDoc {
129         try {
130             for (int i = 0; i < workers.length; i++) {
131                 workers[i].getModule().logout();
132             }
133         } finally {
134             service.logout(client);
135         }
136         clear();
137         return true;
138     }
139
140     private void clear() {
141         Kernel kernel = KernelRegistry.getKernel(kernelName);
142         if (kernel != null) {
143             kernel.getProxyManager().destroyProxy(service);
144         }
145         serverHost = null;
146         serverPort = 0;
147         realmName = null;
148         kernelName = null;
149         service = null;
150         handler = null;
151         subject = null;
152         processedPrincipals.clear();
153         config = null;
154         client = null;
155         workers = null;
156     }
157
158     private JaasLoginServiceMBean connect() {
159         if(serverHost != null && serverPort > 0) {
160             return JaasLoginServiceRemotingClient.create(serverHost, serverPort);
161         } else {
162             Kernel kernel = KernelRegistry.getKernel(kernelName);
163             return (JaasLoginServiceMBean) kernel.getProxyManager().createProxy(JaasLoginService.OBJECT_NAME, JaasLoginServiceMBean.class);
164         }
165     }
166
167     private class ClientLoginModule implements LoginModule JavaDoc {
168         private LoginModule JavaDoc source;
169         int index;
170
171         public ClientLoginModule(LoginModule JavaDoc source, int index) {
172             this.source = source;
173             this.index = index;
174         }
175
176         public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler,
177                                Map JavaDoc sharedState, Map JavaDoc options) {
178             source.initialize(subject, callbackHandler, sharedState, options);
179         }
180
181         public boolean login() throws LoginException JavaDoc {
182            return source.login();
183         }
184
185         public boolean commit() throws LoginException JavaDoc {
186             boolean result = source.commit();
187             List JavaDoc list = new ArrayList JavaDoc();
188             for (Iterator JavaDoc it = subject.getPrincipals().iterator(); it.hasNext();) {
189                 Principal JavaDoc p = (Principal JavaDoc) it.next();
190                 if(!processedPrincipals.contains(p)) {
191                     list.add(p);
192                     processedPrincipals.add(p);
193                 }
194             }
195             service.clientLoginModuleCommit(client, index, (Principal JavaDoc[]) list.toArray(new Principal JavaDoc[list.size()]));
196             return result;
197         }
198
199         public boolean abort() throws LoginException JavaDoc {
200             return source.abort();
201         }
202
203         public boolean logout() throws LoginException JavaDoc {
204             return source.logout();
205         }
206     }
207
208     private class ServerLoginModule implements LoginModule JavaDoc {
209         int index;
210         CallbackHandler JavaDoc handler;
211         Callback JavaDoc[] callbacks;
212
213         public ServerLoginModule(int index) {
214             this.index = index;
215         }
216
217         public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc handler,
218                                Map JavaDoc sharedState, Map JavaDoc options) {
219             this.handler = handler;
220         }
221
222         public boolean login() throws LoginException JavaDoc {
223             try {
224                 callbacks = service.getServerLoginCallbacks(client, index);
225                 if(handler != null) {
226                     handler.handle(callbacks);
227                 } else if(callbacks != null && callbacks.length > 0) {
228                     System.err.println("No callback handler available for "+callbacks.length+" callbacks!");
229                 }
230                 return service.performServerLogin(client, index, callbacks);
231             } catch (LoginException JavaDoc e) {
232                 throw e;
233             } catch (Exception JavaDoc e) {
234                 e.printStackTrace();
235                 throw new LoginException JavaDoc("Unable to log in: "+e.getMessage());
236             }
237         }
238
239         public boolean commit() throws LoginException JavaDoc {
240             return service.serverLoginModuleCommit(client, index);
241         }
242
243         public boolean abort() throws LoginException JavaDoc {
244             return false; // taken care of with a single call to the server
245
}
246
247         public boolean logout() throws LoginException JavaDoc {
248             return false; // taken care of with a single call to the server
249
}
250     }
251 }
252
Popular Tags