KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > security > auth > LoginContextDriver


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 package com.sun.enterprise.security.auth;
24
25 import java.util.Set JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.logging.*;
28 import java.security.AccessController JavaDoc;
29 import java.security.PrivilegedAction JavaDoc;
30 import javax.security.auth.Subject JavaDoc;
31 import javax.security.auth.login.LoginContext JavaDoc;
32 import sun.security.x509.X500Name;
33 import com.sun.logging.*;
34 import com.sun.enterprise.iiop.security.GSSUPName;
35 import com.sun.enterprise.iiop.security.AnonCredential;
36 import com.sun.enterprise.security.SecurityContext;
37 import com.sun.enterprise.security.auth.login.PasswordCredential;
38 import com.sun.enterprise.security.auth.login.X509CertificateCredential;
39 import com.sun.enterprise.security.auth.login.ServerLoginCallbackHandler;
40 import com.sun.enterprise.security.LoginException;
41 import com.sun.enterprise.security.auth.realm.Realm;
42 import com.sun.enterprise.security.Audit;
43 import com.sun.enterprise.security.auth.realm.certificate.CertificateRealm;
44 import com.sun.enterprise.security.audit.AuditManagerFactory;
45 import com.sun.enterprise.security.audit.AuditManager;
46
47 // FIXME: ACC methods need to be moved to ACC-specific class.
48
import com.sun.enterprise.security.ClientSecurityContext;
49 import com.sun.enterprise.appclient.AppContainer;
50
51
52 /**
53  *
54  * This class is invoked implicitly by the server to log in the user
55  * information that was sent on the wire by the client. Clients will
56  * use the <i>doClientLogin</i> method to simulate authentication to the
57  * server.
58  *
59  * @author Harpreet Singh (hsingh@eng.sun.com)
60  * @author Jyri Virkki
61  *
62  */

63 public class LoginContextDriver {
64
65     private static Logger _logger=null;
66     static {
67        _logger = LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
68     }
69
70     private static ServerLoginCallbackHandler
71         dummyCallback = new ServerLoginCallbackHandler();
72
73     private static String JavaDoc CLIENT_JAAS_PASSWORD = "default";
74     private static String JavaDoc CLIENT_JAAS_CERTIFICATE = "certificate";
75
76     public static String JavaDoc CERT_REALMNAME = "certificate";
77   
78     public static AuditManager AUDIT_MANAGER =
79         AuditManagerFactory.getAuditManagerInstance();
80     /** This class cannot be instantiated
81      *
82      */

83     private LoginContextDriver(){
84     }
85     /**
86      * This method is just a convenience wrapper for
87      * <i>login(Subject, Class)</i> method. It will construct a
88      * PasswordCredential class.
89      *
90      * @param String username
91      * @param String password
92      * @param String realmName the name of the realm to login into, if realmName
93      * is null, we login into the default realm
94      */

95     public static void login(String JavaDoc username, String JavaDoc password, String JavaDoc realmName){
96
97         if(realmName == null || !(Realm.isValidRealm(realmName))){
98             realmName = Realm.getDefaultRealm();
99         }
100         final Subject JavaDoc fs = new Subject JavaDoc();
101         final PasswordCredential pc =
102             new PasswordCredential(username, password, realmName);
103         
104         AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
105             public java.lang.Object JavaDoc run(){
106                 fs.getPrivateCredentials().add(pc);
107                 return fs;
108             }
109         });
110
111         LoginContextDriver.login(fs, PasswordCredential.class);
112     }
113
114     
115     /**
116      * This method performs the login on the server side.
117      *
118      * <P>This method is the main login method for S1AS. It is called
119      * with a Subject and the type (class) of credential which should
120      * be checked. The Subject must contain a credential of the
121      * specified type or login will fail.
122      *
123      * <P>While the implementation has been cleaned up, the login
124      * process still consists of a number of special cases which are
125      * treated separately at the realm level. In the future tighter
126      * JAAS integration could clean some of this up.
127      *
128      * <P>The following credential types are recognized at this time:
129      * <ul>
130      * <li>PasswordCredential - This is the general case for all login
131      * methods which rely on the client providing a name and password.
132      * It can be used with any realms/JAAS login modules which expect
133      * such data (e.g. file realm, LDAP realm, UNIX realm)
134      * <LI>X509CertificateCredential - Special case for SSL client auth.
135      * Here authentication has already been done by the SSL subsystem
136      * so this login only creates a security context based on the
137      * certificate data.
138      * <LI>AnonCredential - Unauthenticated session, set anonymous security
139      * context.
140      * <LI>GSSUPName - Retrieve user and realm and set security context.
141      * <LI>X500Name - Retrieve user and realm and set security context.
142      * </ul>
143      *
144      * @param Subject the subject of the client
145      * @param Class the class of the credential packaged in the subject.
146      *
147      */

148     public static void login(Subject JavaDoc subject, Class JavaDoc cls)
149         throws LoginException
150     {
151         if (_logger.isLoggable(Level.FINEST)) {
152             _logger.log(Level.FINEST,
153                         "Processing login with credentials of type: "+
154                         cls.toString());
155         }
156         
157         if(cls.equals(PasswordCredential.class)) {
158             doPasswordLogin(subject);
159
160         } else if (cls.equals(X509CertificateCredential.class)) {
161             doCertificateLogin(subject);
162             
163         } else if (cls.equals(AnonCredential.class)) {
164             doAnonLogin();
165             
166         } else if (cls.equals(GSSUPName.class)) {
167             doGSSUPLogin(subject);
168             
169         } else if (cls.equals(X500Name.class)) {
170             doX500Login(subject);
171             
172         } else {
173             _logger.log(Level.INFO, "java_security.unknown_credential",
174                         cls.toString());
175             throw new
176                 LoginException("Unknown credential type, cannot login.");
177         }
178     }
179
180
181     /**
182      * This method is used for logging in a run As principal. It creates
183      * a JAAS subject whose credential is to type GSSUPName.
184      * This is used primarily for runas
185      *
186      */

187     public static void loginPrincipal(String JavaDoc username, String JavaDoc realmName)
188         throws LoginException {
189
190         // no realm provided, assuming default
191
if(realmName == null || realmName.length() == 0){
192             realmName = Realm.getDefaultRealm();
193         }
194         
195         final Subject JavaDoc s = new Subject JavaDoc();
196
197         final com.sun.enterprise.deployment.PrincipalImpl p
198             = new com.sun.enterprise.deployment.PrincipalImpl(username);
199
200         final GSSUPName name = new GSSUPName(username, realmName);
201
202         AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
203             public java.lang.Object JavaDoc run() {
204                 s.getPrincipals().add(p);
205                 s.getPublicCredentials().add(name);
206                 return null;
207             }
208         });
209
210         setSecurityContext(username, s, realmName);
211     }
212
213     
214     /**
215      * This method logs out the user by clearing the security context.
216      *
217      */

218     public static void logout() throws LoginException {
219         unsetSecurityContext();
220     }
221
222
223     /**
224      * Log in subject with PasswordCredential. This is a generic login
225      * which applies to all login mechanisms which process PasswordCredential.
226      * In other words, any mechanism which receives an actual username, realm
227      * and password set from the client.
228      *
229      * <P>The realm contained in the credential is checked, and a JAAS
230      * LoginContext is created using a context name obtained from the
231      * appropriate Realm instance. The applicable JAAS LoginModule
232      * is initialized (based on the jaas login configuration) and login()
233      * is invoked on it.
234      *
235      * <P>RI code makes several assumptions which are retained here:
236      * <ul>
237      * <li>The PasswordCredential is stored as a private credential of
238      * the subject.
239      * <li>There is only one such credential present (actually, only
240      * the first one is relevant if more are present).
241      * </ui>
242      *
243      * @param s Subject to be authenticated.
244      * @throws LoginException Thrown if the login fails.
245      *
246      */

247     private static void doPasswordLogin(Subject JavaDoc subject)
248         throws LoginException
249     {
250         final Subject JavaDoc s = subject;
251         
252         Object JavaDoc obj = getPrivateCredentials(s, PasswordCredential.class);
253         assert obj != null;
254         
255         PasswordCredential p = (PasswordCredential) obj;
256         String JavaDoc user = p.getUser();
257         String JavaDoc pwd = p.getPassword();
258         String JavaDoc realm = p.getRealm();
259         String JavaDoc jaasCtx = null;
260         try {
261             jaasCtx = Realm.getInstance(realm).getJAASContext();
262         } catch(Exception JavaDoc ex) {
263             if( ex instanceof LoginException )
264                 throw (LoginException)ex;
265             else
266                 throw (LoginException)new LoginException(ex.toString()).initCause(ex);
267         }
268
269         assert user != null;
270         assert pwd != null;
271         assert realm != null;
272         assert jaasCtx != null;
273
274         if (_logger.isLoggable(Level.FINE)) {
275             _logger.fine("Logging in user [" + user + "] into realm: " +
276                          realm + " using JAAS module: "+jaasCtx);
277         }
278
279         try {
280             // A dummyCallback is used to satisfy JAAS but it is never used.
281
// name/pwd info is already contained in Subject's Credential
282
LoginContext JavaDoc lg = new LoginContext JavaDoc(jaasCtx, s, dummyCallback);
283             lg.login();
284             
285         } catch (Exception JavaDoc e) {
286             if (_logger.isLoggable(Level.INFO)) {
287                 _logger.log(Level.INFO, "java_security.audit_auth_refused",
288                             user);
289             }
290             if(AUDIT_MANAGER.isAuditOn()){
291                 AUDIT_MANAGER.authentication(user, realm, false);
292             }
293             if( e instanceof LoginException )
294                 throw (LoginException)e;
295             else
296                 throw (LoginException)
297                     new LoginException("Login failed: " + e.toString()).initCause(e);
298         }
299         if(AUDIT_MANAGER.isAuditOn()){
300             AUDIT_MANAGER.authentication(user, realm, true);
301         }
302         if (_logger.isLoggable(Level.FINE)) {
303             _logger.fine("Password login succeeded for : " + user);
304         }
305
306         setSecurityContext(user, s, realm);
307         if (_logger.isLoggable(Level.FINE)) {
308             _logger.log(Level.FINE, "Set security context as user: "+user);
309         }
310     }
311   /** Performs login for webservices security. The difference between this
312      * method and others is that it just verifies whether the login will succeed
313      * in the given realm.
314      * It does not set the result of the authentication in the appserver runtime
315      * environment
316      * A silent return from this method means that the given user succeeding in
317      * authenticating with the given password in the given realm
318      * @param username
319      * @param password
320      * @param realmName the realm to authenticate under
321      * @returns void on successful authentication
322      * @throws LoginException
323      */

324                                                                                                                             
325   public static void wssLoginUsernamePassword(String JavaDoc username, String JavaDoc password,
326         String JavaDoc realmName)
327         throws LoginException
328     {
329         if(realmName == null || !(Realm.isValidRealm(realmName))){
330             realmName = Realm.getDefaultRealm();
331         }
332         final Subject JavaDoc fs = new Subject JavaDoc();
333         final PasswordCredential pc =
334             new PasswordCredential(username, password, realmName);
335                                                                                                                             
336         AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
337             public java.lang.Object JavaDoc run(){
338                 fs.getPrivateCredentials().add(pc);
339                 return fs;
340             }
341         });
342                                                                                                                             
343         String JavaDoc jaasCtx = null;
344         try {
345             jaasCtx = Realm.getInstance(realmName).getJAASContext();
346         } catch(Exception JavaDoc ex) {
347             if( ex instanceof LoginException )
348                 throw (LoginException)ex;
349             else
350                 throw (LoginException)
351                     new LoginException(ex.toString()).initCause(ex);
352         }
353                                                                                                                             
354         if (_logger.isLoggable(Level.FINE)) {
355             _logger.fine("Logging in user [" + username + "] into realm: " +
356                          realmName + " using JAAS module: "+jaasCtx);
357         }
358                                                                                                                             
359         try{
360
361         // A dummyCallback is used to satisfy JAAS but it is never used.
362
// name/pwd info is already contained in Subject's Credential
363
LoginContext JavaDoc lg = new LoginContext JavaDoc(jaasCtx, fs, dummyCallback);
364             lg.login();
365                                                                                                                             
366         } catch (Exception JavaDoc e) {
367             if (_logger.isLoggable(Level.INFO)) {
368                 _logger.log(Level.INFO, "java_security.audit_auth_refused",
369                             username);
370             }
371             if(AUDIT_MANAGER.isAuditOn()){
372                 AUDIT_MANAGER.authentication(username, realmName, false);
373             }
374
375             if( e instanceof LoginException )
376                 throw (LoginException)e;
377             else
378                 throw (LoginException)
379                     new LoginException("Login failed: " + e.toString()).initCause(e);
380         }
381         if(AUDIT_MANAGER.isAuditOn()){
382             AUDIT_MANAGER.authentication(username, realmName, true);
383         }
384         if (_logger.isLoggable(Level.FINE)) {
385             _logger.fine("Password login succeeded for : " + username);
386         }
387         // do not set the security Context
388
}
389
390
391     /**
392      * A special case login for handling X509CertificateCredential.
393      * This does not get triggered based on current RI code. See X500Login.
394      *
395      */

396     private static void doCertificateLogin(Subject JavaDoc s)
397         throws LoginException
398     {
399         if(_logger.isLoggable(Level.FINE)){
400             _logger.log(Level.FINE, "Processing X509 certificate login.");
401         }
402         String JavaDoc realm = CertificateRealm.AUTH_TYPE;
403         String JavaDoc user = null;
404         try{
405             Object JavaDoc obj = getPublicCredentials(s, X509CertificateCredential.class);
406
407             X509CertificateCredential xp = (X509CertificateCredential) obj;
408             user = xp.getAlias();
409             if(_logger.isLoggable(Level.FINE)){
410                 _logger.log(Level.FINE,"Set security context as user: "+user);
411             }
412             setSecurityContext(user, s, realm);
413             if(AUDIT_MANAGER.isAuditOn()){
414                 AUDIT_MANAGER.authentication(user, realm, true);
415             }
416         } catch(LoginException le){
417             if(AUDIT_MANAGER.isAuditOn()){
418                 AUDIT_MANAGER.authentication(user, realm, false);
419             }
420             throw le;
421         }
422     }
423
424
425     /**
426      * A special case login for anonymous credentials (no login info).
427      *
428      */

429     private static void doAnonLogin()
430         throws LoginException
431     {
432         // instance of anononymous credential login with guest
433
SecurityContext.setUnauthenticatedContext();
434        if(_logger.isLoggable(Level.FINE)){
435             _logger.log(Level.FINE,"Set anonymous security context.");
436         }
437     }
438
439
440     /**
441      * A special case login for GSSUPName credentials.
442      *
443      */

444     private static void doGSSUPLogin(Subject JavaDoc s)
445         throws LoginException
446     {
447        if(_logger.isLoggable(Level.FINE)){
448              _logger.fine("Processing GSSUP login.");
449        }
450        String JavaDoc user = null;
451        String JavaDoc realm = Realm.getDefaultRealm();
452        try{
453             Object JavaDoc obj = getPublicCredentials(s, GSSUPName.class);
454
455             user = ((GSSUPName)obj).getUser();
456     
457             setSecurityContext(user, s, realm);
458             if(AUDIT_MANAGER.isAuditOn()){
459                 AUDIT_MANAGER.authentication(user, realm, true);
460             }
461             if (_logger.isLoggable(Level.FINE)) {
462                 _logger.fine("GSSUP login succeeded for : " + user);
463             }
464        } catch (LoginException le){
465            if(AUDIT_MANAGER.isAuditOn()){
466                AUDIT_MANAGER.authentication(user, realm, false);
467            }
468            throw le;
469        }
470     }
471
472
473     /**
474      * A special case login for X500Name credentials.
475      * This is invoked for certificate login because the containers
476      * extract the X.500 name from the X.509 certificate before calling
477      * into this class.
478      *
479      */

480     private static void doX500Login(Subject JavaDoc s)
481         throws LoginException
482     {
483        if(_logger.isLoggable(Level.FINE)){
484             _logger.fine("Processing X.500 name login.");
485        }
486        String JavaDoc user = null;
487        String JavaDoc realm_name = null;
488        try{
489             X500Name x500name = (X500Name)getPublicCredentials(s, X500Name.class);
490             user = x500name.getName();
491         
492             // In the RI-inherited implementation this directly creates
493
// some credentials and sets the security context. This means
494
// that the certificate realm does not get an opportunity to
495
// process the request. While the realm will not do any
496
// authentication (already done by this point) it can choose
497
// to adjust the groups or principal name or other variables
498
// of the security context. Of course, bug 4646134 needs to be
499
// kept in mind at all times.
500

501             Realm realm = Realm.getInstance(CertificateRealm.AUTH_TYPE);
502
503             if (realm instanceof CertificateRealm) { // should always be true
504

505                 CertificateRealm certRealm = (CertificateRealm)realm;
506                 certRealm.authenticate(s, x500name);
507                 realm_name = CertificateRealm.AUTH_TYPE;
508                 if(AUDIT_MANAGER.isAuditOn()){
509                     AUDIT_MANAGER.authentication(user, realm_name, true);
510                 }
511             } else {
512                 _logger.warning("certlogin.badrealm");
513                 setSecurityContext(user, s, realm_name);
514                 realm_name = realm.getName();
515             }
516         
517             if (_logger.isLoggable(Level.FINE)) {
518                 _logger.fine("X.500 name login succeeded for : " + user);
519             }
520        } catch (LoginException le){
521            if(AUDIT_MANAGER.isAuditOn()){
522                AUDIT_MANAGER.authentication(user, realm_name, false);
523            }
524            throw le;
525        } catch (Exception JavaDoc ex) {
526            throw (LoginException)new LoginException(ex.toString()).initCause(ex);
527        }
528     }
529
530
531     /**
532      * Retrieve a public credential of the given type (java class) from the
533      * subject.
534      *
535      * <P>This method retains the RI assumption that only the first
536      * credential of the given type is used.
537      *
538      */

539     private static Object JavaDoc getPublicCredentials(Subject JavaDoc s, Class JavaDoc cls)
540         throws LoginException
541     {
542         Set JavaDoc credset = s.getPublicCredentials(cls);
543         
544         final Iterator JavaDoc iter = credset.iterator();
545
546         if(!iter.hasNext()) {
547             String JavaDoc credmsg = cls.toString();
548             if(_logger.isLoggable(Level.FINER)){
549                 _logger.finer("Expected public credentials of type : " +
550                           credmsg + " but none found.");
551             }
552             throw new LoginException("Expected public credential of type: "+
553                                      credmsg + " but none found.");
554         }
555         
556         Object JavaDoc obj = null;
557         try{
558             obj = AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
559                 public java.lang.Object JavaDoc run(){
560                     return iter.next();
561                 }
562             });
563         } catch (Exception JavaDoc e){
564             // should never come here
565
if( e instanceof LoginException )
566                 throw (LoginException)e;
567             else
568                 throw (LoginException)
569                     new LoginException("Failed to retrieve public credential: "+
570                                        e.toString()).initCause(e);
571         }
572
573         return obj;
574     }
575
576
577     /**
578      * Retrieve a private credential of the given type (java class) from the
579      * subject.
580      *
581      * <P>This method retains the RI assumption that only the first
582      * credential of the given type is used.
583      *
584      */

585     private static Object JavaDoc getPrivateCredentials(Subject JavaDoc subject,
586                                                 Class JavaDoc cls)
587         throws LoginException
588     {
589         final Subject JavaDoc s = subject;
590         final Class JavaDoc cl = cls;
591         
592         final Set JavaDoc credset = (Set JavaDoc)
593             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
594                 public java.lang.Object JavaDoc run() {
595                     return
596                         s.getPrivateCredentials(cl);
597                 }
598             });
599
600         final Iterator JavaDoc iter = credset.iterator();
601
602         if (!iter.hasNext()) {
603            String JavaDoc credmsg = cls.toString();
604            if(_logger.isLoggable(Level.FINER)){
605                  _logger.finer("Expected private credential of type: "+
606                               credmsg + " but none found.");
607            }
608             throw new LoginException("Expected private credential of type: "+
609                                      credmsg + " but none found.");
610         }
611
612         // retrieve only first credential of give type
613
Object JavaDoc obj = null;
614         try{
615             obj = AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
616                 public java.lang.Object JavaDoc run(){
617                     return iter.next();
618                 }
619             });
620         } catch (Exception JavaDoc e){
621             // should never come here
622
if( e instanceof LoginException )
623                 throw (LoginException)e;
624             else
625                 throw (LoginException)
626                     new LoginException("Failed to retrieve private credential: "+
627                                      e.toString()).initCause(e);
628         }
629
630         return obj;
631     }
632
633     
634     /**
635      * This method sets the security context on the current Thread Local
636      * Storage
637      * @param String username is the user who authenticated
638      * @param Subject is the subject representation of the user
639      * @param Credentials the credentials that the server associated with it
640      */

641     private static void setSecurityContext(String JavaDoc userName,
642                                             Subject JavaDoc subject, String JavaDoc realm){
643
644         SecurityContext securityContext =
645             new SecurityContext(userName, subject, realm);
646         SecurityContext.setCurrent(securityContext);
647     }
648
649     
650     /**
651      * Set the current security context on the Thread Local Storage to null.
652      *
653      */

654     private static void unsetSecurityContext() {
655         SecurityContext.setCurrent((SecurityContext)null);
656     }
657
658     /**
659      * Perform login on the client side.
660      * It just simulates the login on the client side.
661      * The method uses the callback handlers and generates correct
662      * credential information that will be later sent to the server
663      * @param int type whether it is <i> username_password</i> or
664      * <i> certificate </i> based login.
665      * @param CallbackHandler the callback handler to gather user information.
666      * @exception LoginException the exception thrown by the callback handler.
667      */

668     public static Subject JavaDoc doClientLogin(int type,
669                      javax.security.auth.callback.CallbackHandler JavaDoc jaasHandler)
670         throws LoginException
671     {
672         final javax.security.auth.callback.CallbackHandler JavaDoc handler =
673             jaasHandler;
674         // the subject will actually be filled in with a PasswordCredential
675
// required by the csiv2 layer in the LoginModule.
676
// we create the dummy credential here and call the
677
// set security context. Thus, we have 2 credentials, one each for
678
// the csiv2 layer and the other for the RI.
679
final Subject JavaDoc subject = new Subject JavaDoc();
680         if (type == AppContainer.USERNAME_PASSWORD){
681             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
682                 public java.lang.Object JavaDoc run() {
683                     try{
684                         LoginContext JavaDoc lg =
685                             new LoginContext JavaDoc(CLIENT_JAAS_PASSWORD,
686                                              subject, handler);
687                         lg.login();
688                     }catch(javax.security.auth.login.LoginException JavaDoc e){
689                         throw (LoginException)
690                             new LoginException(e.toString()).initCause(e);
691                     }
692                     
693                     return null;
694                 }
695             });
696             postClientAuth(subject, PasswordCredential.class);
697             return subject;
698         } else if (type == AppContainer.CERTIFICATE){
699             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
700                 public java.lang.Object JavaDoc run() {
701                     try{
702                         LoginContext JavaDoc lg =
703                             new LoginContext JavaDoc(CLIENT_JAAS_CERTIFICATE,
704                                              subject, handler);
705                         lg.login();
706                     }catch(javax.security.auth.login.LoginException JavaDoc e){
707                         throw (LoginException)
708                             new LoginException(e.toString()).initCause(e);
709                     }
710                     
711                     return null;
712                 }
713             });
714             postClientAuth(subject, X509CertificateCredential.class);
715             return subject;
716         } else if (type == AppContainer.ALL){
717             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
718                 public java.lang.Object JavaDoc run() {
719                     try{
720                         LoginContext JavaDoc lgup =
721                             new LoginContext JavaDoc(CLIENT_JAAS_PASSWORD,
722                                              subject, handler);
723                         LoginContext JavaDoc lgc =
724                             new LoginContext JavaDoc(CLIENT_JAAS_CERTIFICATE,
725                                                  subject, handler);
726                         lgup.login();
727                         postClientAuth(subject, PasswordCredential.class);
728                         
729                         lgc.login();
730                         postClientAuth(subject,
731                                        X509CertificateCredential.class);
732                     }catch(javax.security.auth.login.LoginException JavaDoc e){
733                         throw (LoginException)
734                             new LoginException(e.toString()).initCause(e);
735                     }
736                     
737                     return null;
738                 }
739             });
740             return subject;
741         } else{
742             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
743                 public java.lang.Object JavaDoc run() {
744                     try{
745                         LoginContext JavaDoc lg =
746                             new LoginContext JavaDoc(CLIENT_JAAS_PASSWORD,
747                                              subject, handler);
748                         lg.login();
749                         postClientAuth(subject, PasswordCredential.class);
750                     }catch(javax.security.auth.login.LoginException JavaDoc e){
751                         throw (LoginException)
752                             new LoginException(e.toString()).initCause(e);
753                     }
754                     return null;
755                 }
756             });
757             return subject;
758         }
759     }
760
761     /**
762      * Perform logout on the client side.
763      * @exception LoginException
764      */

765     public static void doClientLogout() throws LoginException {
766         unsetClientSecurityContext();
767     }
768     
769     /**
770      * Extract the relevant username and realm information from the
771      * subject and sets the correct state in the security context. The
772      * relevant information is set into the Thread Local Storage from
773      * which then is extracted to send over the wire.
774      *
775      * @param Subject the subject returned by the JAAS login.
776      * @param Class the class of the credential object stored in the subject
777      *
778      */

779     private static void postClientAuth(Subject JavaDoc subject, Class JavaDoc clazz){
780         final Class JavaDoc clas = clazz;
781         final Subject JavaDoc fs = subject;
782         Set JavaDoc credset =
783             (Set JavaDoc) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
784                 public java.lang.Object JavaDoc run() {
785                 if(_logger.isLoggable(Level.FINEST)){
786                     _logger.log(Level.FINEST,"LCD post login subject :" + fs);
787                 }
788                     return fs.getPrivateCredentials(clas);
789                 }
790             });
791         final Iterator JavaDoc iter = credset.iterator();
792         while(iter.hasNext()) {
793             Object JavaDoc obj = null;
794             try{
795                 obj = AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
796                     public java.lang.Object JavaDoc run(){
797                         return iter.next();
798                     }
799                 });
800             } catch (Exception JavaDoc e){
801                 // should never come here
802
_logger.log(Level.SEVERE,
803                             "java_security.accesscontroller_action_exception",
804                             e);
805             }
806             if(obj instanceof PasswordCredential) {
807                 PasswordCredential p = (PasswordCredential) obj;
808                 String JavaDoc user = p.getUser();
809                 if(_logger.isLoggable(Level.FINEST)){
810                     String JavaDoc realm = p.getRealm();
811                     _logger.log(Level.FINEST,"In LCD user-pass login:" +
812                             user +" realm :" + realm);
813                 }
814                 setClientSecurityContext(user, fs);
815                 return;
816             } else if (obj instanceof X509CertificateCredential){
817                 X509CertificateCredential p = (X509CertificateCredential) obj;
818                 String JavaDoc user = p.getAlias();
819                 if(_logger.isLoggable(Level.FINEST)){
820                     String JavaDoc realm = p.getRealm();
821                     _logger.log(Level.FINEST,"In LCD cert-login::" +
822                                 user +" realm :" + realm);
823                 }
824                 setClientSecurityContext(user, fs);
825                 return;
826             }
827         }
828     }
829
830     
831     /**
832      * Sets the security context on the appclient side.
833      * It sets the relevant information into the TLS
834      * @param String username is the user who authenticated
835      * @param Subject is the subject representation of the user
836      * @param Credentials the credentials that the server associated with it
837      */

838     private static void setClientSecurityContext(String JavaDoc username,
839                                                  Subject JavaDoc subject) {
840                                                  
841         ClientSecurityContext securityContext =
842             new ClientSecurityContext(username, subject);
843         ClientSecurityContext.setCurrent(securityContext);
844     }
845
846     
847     /**
848      * Unsets the current appclient security context on the Thread
849      * Local Storage
850      */

851     private static void unsetClientSecurityContext() {
852         ClientSecurityContext.setCurrent(null);
853     }
854
855     
856
857 }
858
Popular Tags