KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > jaas > CertificateLoginModule


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

18
19 package org.apache.activemq.jaas;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import java.io.IOException JavaDoc;
25 import java.security.cert.X509Certificate JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import javax.security.auth.Subject JavaDoc;
32 import javax.security.auth.callback.Callback JavaDoc;
33 import javax.security.auth.callback.CallbackHandler JavaDoc;
34 import javax.security.auth.callback.UnsupportedCallbackException JavaDoc;
35 import javax.security.auth.login.FailedLoginException JavaDoc;
36 import javax.security.auth.login.LoginException JavaDoc;
37 import javax.security.auth.spi.LoginModule JavaDoc;
38
39 /**
40  * A LoginModule that allows for authentication based on SSL certificates.
41  *
42  * Allows for subclasses to define methods used to verify user certificates and find user groups.
43  * Uses CertificateCallbacks to retrieve certificates.
44  *
45  * @author sepandm@gmail.com (Sepand)
46  *
47  */

48 public abstract class CertificateLoginModule implements LoginModule JavaDoc {
49     
50     private CallbackHandler JavaDoc callbackHandler;
51     private Subject JavaDoc subject;
52     
53     private X509Certificate JavaDoc certificates[];
54     private String JavaDoc username = null;
55     private Set JavaDoc groups = null;
56     
57     private Set JavaDoc principals = new HashSet JavaDoc();
58     
59     private static final Log log = LogFactory.getLog(CertificateLoginModule.class);
60     private boolean debug;
61
62     /**
63      * Overriding to allow for proper initialization.
64      *
65      * Standard JAAS.
66      */

67     public void initialize(Subject JavaDoc subject, CallbackHandler JavaDoc callbackHandler, Map JavaDoc sharedState, Map JavaDoc options) {
68         this.subject = subject;
69         this.callbackHandler = callbackHandler;
70         
71         debug = "true".equalsIgnoreCase((String JavaDoc) options.get("debug"));
72         
73         if (debug) {
74             log.debug("Initialized debug");
75         }
76     }
77
78     /**
79      * Overriding to allow for certificate-based login.
80      *
81      * Standard JAAS.
82      */

83     public boolean login() throws LoginException JavaDoc {
84         Callback JavaDoc[] callbacks = new Callback JavaDoc[1];
85
86         callbacks[0] = new CertificateCallback();
87         try {
88             callbackHandler.handle(callbacks);
89         } catch (IOException JavaDoc ioe) {
90             throw new LoginException JavaDoc(ioe.getMessage());
91         } catch (UnsupportedCallbackException JavaDoc uce) {
92             throw new LoginException JavaDoc(uce.getMessage() + " Unable to obtain client certificates.");
93         }
94         certificates = ((CertificateCallback) callbacks[0]).getCertificates();
95         
96         username = getUserNameForCertificates(certificates);
97         if ( username == null )
98             throw new FailedLoginException JavaDoc("No user for client certificate: "
99                 + getDistinguishedName(certificates));
100
101         groups = getUserGroups(username);
102         
103         if (debug) {
104             log.debug("Certificate for user: " + username);
105         }
106         return true;
107     }
108
109     /**
110      * Overriding to complete login process.
111      *
112      * Standard JAAS.
113      */

114     public boolean commit() throws LoginException JavaDoc {
115         principals.add(new UserPrincipal(username));
116
117         String JavaDoc currentGroup = null;
118         for (Iterator JavaDoc iter = groups.iterator(); iter.hasNext(); ) {
119             currentGroup = (String JavaDoc)iter.next();
120             principals.add(new GroupPrincipal(currentGroup));
121         }
122
123         subject.getPrincipals().addAll(principals);
124
125         clear();
126
127         if (debug) {
128             log.debug("commit");
129         }
130         return true;
131     }
132
133     /**
134      * Standard JAAS override.
135      */

136     public boolean abort() throws LoginException JavaDoc {
137         clear();
138
139         if (debug) {
140             log.debug("abort");
141         }
142         return true;
143     }
144
145     /**
146      * Standard JAAS override.
147      */

148     public boolean logout() {
149         subject.getPrincipals().removeAll(principals);
150         principals.clear();
151
152         if (debug) {
153             log.debug("logout");
154         }
155         return true;
156     }
157     
158     /**
159      * Helper method.
160      */

161     private void clear() {
162         groups.clear();
163         certificates = null;
164     }
165     
166     /**
167      * Should return a unique name corresponding to the certificates given.
168      *
169      * The name returned will be used to look up access levels as well as
170      * group associations.
171      *
172      * @param dn The distinguished name.
173      * @return The unique name if the certificate is recognized, null otherwise.
174      */

175     protected abstract String JavaDoc getUserNameForCertificates(final X509Certificate JavaDoc[] certs) throws LoginException JavaDoc;
176     
177     /**
178      * Should return a set of the groups this user belongs to.
179      *
180      * The groups returned will be added to the user's credentials.
181      *
182      * @param username The username of the client. This is the same name that
183      * getUserNameForDn returned for the user's DN.
184      * @return A Set of the names of the groups this user belongs to.
185      */

186     protected abstract Set JavaDoc getUserGroups(final String JavaDoc username) throws LoginException JavaDoc;
187
188     protected String JavaDoc getDistinguishedName(final X509Certificate JavaDoc[] certs) {
189         if (certs != null && certs.length > 0 && certs[0] != null) {
190             return certs[0].getSubjectDN().getName();
191         } else {
192             return null;
193         }
194     }
195
196 }
197
Popular Tags