KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > security > auth > realm > certificate > CertificateRealm


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.security.auth.realm.certificate;
25
26 import java.lang.*;
27 import java.util.*;
28 import java.util.logging.Logger JavaDoc;
29 import java.io.*;
30 import java.security.*;
31
32 import javax.security.auth.login.*;
33 import javax.security.auth.Subject JavaDoc;
34
35 import com.sun.enterprise.deployment.Group;
36 import com.sun.enterprise.security.SecurityContext;
37 import com.sun.enterprise.security.auth.Privilege;
38 import com.sun.enterprise.security.auth.PrivilegeImpl;
39 import com.sun.enterprise.security.auth.realm.User;
40 import com.sun.enterprise.security.auth.realm.Realm;
41 import com.sun.enterprise.security.auth.realm.BadRealmException;
42 import com.sun.enterprise.security.auth.realm.NoSuchUserException;
43 import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
44 import com.sun.enterprise.security.auth.realm.AuthenticationHandler;
45 import com.sun.enterprise.security.auth.realm.InvalidOperationException;
46
47 import com.sun.enterprise.server.*;
48 import com.sun.enterprise.security.util.*;
49 import com.sun.enterprise.security.auth.realm.IASRealm;
50
51 import sun.security.x509.X500Name;
52
53
54 /**
55  * Realm wrapper for supporting certificate authentication.
56  *
57  * <P>The certificate realm provides the security-service functionality
58  * needed to process a client-cert authentication. Since the SSL processing,
59  * and client certificate verification is done by NSS, no authentication
60  * is actually done by this realm. It only serves the purpose of being
61  * registered as the certificate handler realm and to service group
62  * membership requests during web container role checks.
63  *
64  * <P>There is no JAAS LoginModule corresponding to the certificate realm,
65  * therefore this realm does not require the jaas-context configuration
66  * parameter to be set. The purpose of a JAAS LoginModule is to implement
67  * the actual authentication processing, which for the case of this
68  * certificate realm is already done by the time execution gets to Java.
69  *
70  * <P>The certificate realm needs the following properties in its
71  * configuration: None.
72  *
73  * <P>The following optional attributes can also be specified:
74  * <ul>
75  * <li>assign-groups - A comma-separated list of group names which
76  * will be assigned to all users who present a cryptographically
77  * valid certificate. Since groups are otherwise not supported
78  * by the cert realm, this allows grouping cert users
79  * for convenience.
80  * </ul>
81  *
82  */

83
84
85 public final class CertificateRealm extends IASRealm
86 {
87     // Descriptive string of the authentication type of this realm.
88
public static final String JavaDoc AUTH_TYPE = "certificate";
89
90     // Optional link to a realm to verify group (possibly user, later)
91
// public static final String PARAM_USEREALM = "use-realm";
92

93     // Optional ordered list of possible elements to use as user name
94
// from X.500 name.
95
// public static final String PARAM_NAMEFIELD = "name-field";
96
// private String[] nameFields = null;
97
// private static final String LINK_SEP = ",";
98

99     // Optional group list to assign to all client-cert authenticated users
100
public static final String JavaDoc PARAM_GROUPS = "assign-groups";
101     private static final String JavaDoc GROUPS_SEP = ",";
102     private Vector defaultGroups = null;
103     // groupsPrivileges is from S1AS7 code, not used in this moment
104
//private Privilege[] groupsAsPrivileges = null;
105
private Group[] groupsAsPrincipals = null;
106
107
108     /**
109      * Initialize a realm with some properties. This can be used
110      * when instantiating realms from their descriptions. This
111      * method is invoked from Realm during initialization.
112      *
113      * @param props Initialization parameters used by this realm.
114      * @exception BadRealmException If the configuration parameters
115      * identify a corrupt realm.
116      * @exception NoSuchRealmException If the configuration parameters
117      * specify a realm which doesn't exist.
118      *
119      */

120     protected void init(Properties props)
121     {
122         /* future enhacement; allow using subset of DN as name field;
123            requires RI fixes to handle subject & principal names
124            consistently
125         String nameLink = props.getProperty(PARAM_NAMEFIELD);
126         if (nameLink == null) {
127             Util.debug(log, "CertificateRealm: No "+PARAM_NAMEFIELD+
128                        " provided, will use X.500 name.");
129         } else {
130
131             StringTokenizer st = new StringTokenizer(nameLink, LINK_SEP);
132             int n = st.countTokens();
133             nameFields = new String[n];
134
135             for (int i=0; i<n; i++) {
136                 nameFields[i] = (String)st.nextToken();
137             }
138         }
139         */

140
141         /* future enhancement; allow linking to other realm such that
142            user presence verification and group membership can be
143            defined/shared; requires RI fixes to consistently check role
144            memberships and RI fixes to allow multiple active realms.
145         String link = props.getProperty(PARAM_USEREALM);
146         if (link != null) {
147             this.setProperty(PARAM_USEREALM, link);
148             Util.debug(log, "CertificateRealm : "+PARAM_USEREALM+"="+link);
149         }
150         */

151
152                                 // populate assigned groups, if any
153
defaultGroups = new Vector();
154         String JavaDoc groupList = props.getProperty(PARAM_GROUPS);
155         
156         if (groupList != null) {
157             _logger.fine("CertificateRealm : groups: " + groupList);
158             StringTokenizer st = new StringTokenizer(groupList, GROUPS_SEP);
159             while (st.hasMoreTokens()) {
160                 String JavaDoc grp = (String JavaDoc)st.nextToken();
161                 defaultGroups.add(grp);
162             }
163              
164             // construct privilege set of known group list which will be
165
// set in security context after authentication complete
166
int groups = defaultGroups.size();
167             /*
168             // groupsPrivileges is from S1AS7 code, not used in this moment
169             groupsAsPrivileges = new Privilege[groups];
170             for (int i=0; i<groups; i++) {
171                 groupsAsPrivileges[i] =
172                     new PrivilegeImpl((String)defaultGroups.get(i));
173             }
174             */

175             groupsAsPrincipals = new Group[groups];
176             for (int i = 0; i < groups; i++) {
177                 groupsAsPrincipals[i] = new Group((String JavaDoc)defaultGroups.get(i));
178             }
179         } else {
180             
181             // groupsPrivileges is from S1AS7 code, not used in this moment
182
//groupsAsPrivileges = new Privilege[0];
183
groupsAsPrincipals = new Group[0];
184         }
185     }
186
187
188     /**
189      * Returns a short (preferably less than fifteen characters) description
190      * of the kind of authentication which is supported by this realm.
191      *
192      * @return Description of the kind of authentication that is directly
193      * supported by this realm.
194      */

195     public String JavaDoc getAuthType()
196     {
197         return AUTH_TYPE;
198     }
199     
200
201     /**
202      * Returns the name of all the groups that this user belongs to.
203      *
204      * @param username Name of the user in this realm whose group listing
205      * is needed.
206      * @return Enumeration of group names (strings).
207      * @exception InvalidOperationException thrown if the realm does not
208      * support this operation - e.g. Certificate realm does not support
209      * this operation.
210      *
211      */

212     public Enumeration getGroupNames(String JavaDoc username)
213         throws NoSuchUserException, InvalidOperationException
214     {
215         // This is called during web container role check, not during
216
// EJB container role cheks... fix RI for consistency.
217

218         // Groups for cert users is empty by default unless some assign-groups
219
// property has been specified (see init()).
220
return defaultGroups.elements();
221     }
222     
223
224     /**
225      * Returns name of JAAS context used by this realm. Overrides default
226      * Realm behavior of this method. The certificate realm does not
227      * require (or support) a LoginModule. This method should never get
228      * called unless there is a configuration error, so this overloading
229      * is provided to log an error message. See class documentation.
230      *
231      * @return null
232      *
233      */

234     public String JavaDoc getJAASContext()
235     {
236         _logger.warning("certrealm.nojaas");
237         return null;
238     }
239
240
241     /**
242      * Complete authentication of certificate user.
243      *
244      * <P>As noted, the certificate realm does not do the actual
245      * authentication (signature and cert chain validation) for
246      * the user certificate, this is done earlier in NSS. This method
247      * simply sets up the security context for the user in order to
248      * properly complete the authentication processing.
249      *
250      * <P>If any groups have been assigned to cert-authenticated users
251      * through the assign-groups property these groups are added to
252      * the security context for the current user.
253      *
254      * @param subject The Subject object for the authentication request.
255      * @param x500name The X500Name object from the user certificate.
256      *
257      */

258     public void authenticate(Subject JavaDoc subject, X500Name x500name)
259     {
260         // It is important to use x500name.getName() in order to be
261
// consistent with web containers view of the name - see bug
262
// 4646134 for reasons why this matters.
263

264         String JavaDoc name = x500name.getName();
265
266         _logger.finest("Certificate realm setting up security context for: "+
267                        name);
268
269         // FIXME - auth cleanup - 'groupsAsPrivileges' needs to be
270
// populated into the 'subject'
271
int gsize = groupsAsPrincipals.length;
272         Set principalSet = subject.getPrincipals();
273         for (int i = 0; i < gsize; i++) {
274             principalSet.add(groupsAsPrincipals[i]);
275         }
276         SecurityContext securityContext =
277         new SecurityContext(name, subject);
278         
279     SecurityContext.setCurrent(securityContext);
280     }
281
282
283 }
284
Popular Tags