KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > appserv > security > ProgrammaticLogin


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
25 package com.sun.appserv.security;
26
27 import java.util.Properties JavaDoc;
28 import java.util.logging.Logger JavaDoc;
29 import java.util.logging.Level JavaDoc;
30 import java.security.AccessController JavaDoc;
31 import java.security.PrivilegedAction JavaDoc;
32 import java.security.PrivilegedExceptionAction JavaDoc;
33
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import javax.servlet.http.HttpServletResponse JavaDoc;
36                          
37 import com.sun.logging.LogDomains;
38 import com.sun.enterprise.appclient.AppContainer;
39 import com.sun.enterprise.security.auth.LoginContextDriver;
40 import com.sun.enterprise.security.auth.login.ClientPasswordLoginModule;
41 import com.sun.enterprise.server.ApplicationServer;
42 import com.sun.web.security.WebProgrammaticLogin;
43
44
45 /**
46  * Implement programmatic login.
47  *
48  * <P>This class allows deployed applications to supply a name and
49  * password directly to the security service. This info will be used
50  * to attempt to login to the current realm. If authentication succeeds,
51  * a security context is established as this user.
52  *
53  * <P>This allows applications to programmatically handle authentication.
54  * The use of this mechanism is not recommended since it bypasses the
55  * standard J2EE mechanisms and places all burden on the application
56  * developer.
57  *
58  * <P>Invoking this method requires the permission
59  * ProgrammaticLoginPermission with the method name being invoked.
60  *
61  * <P>There are two forms of the login method, one which includes the HTTP
62  * request and response objects for use by servlets and one which can be used
63  * by EJBs.
64  *
65  *
66  */

67
68 public class ProgrammaticLogin
69 {
70     private static Logger JavaDoc logger =
71         LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
72
73     private static ProgrammaticLoginPermission plLogin =
74         new ProgrammaticLoginPermission("login");
75
76     private static ProgrammaticLoginPermission plLogout =
77         new ProgrammaticLoginPermission("logout");
78
79     private static boolean isServer =
80         (ApplicationServer.getServerContext() != null);
81
82     private static javax.security.auth.callback.CallbackHandler JavaDoc handler = new com.sun.enterprise.security.auth.login.LoginCallbackHandler(false);
83     
84     /**
85      * Attempt to login.
86      *
87      * <P>Upon successful return from this method the SecurityContext will
88      * be set in the name of the given user as its Subject.
89      *
90      * <p>On client side, realm and errors parameters will be ignored and
91      * the actual login will not occur until we actually access a resource
92      * requiring a login. And a java.rmi.AccessException with
93      * COBRA NO_PERMISSION will occur when actual login is failed.
94      *
95      * <P>This method is intented primarily for EJBs wishing to do
96      * programmatic login. If servlet code used this method the established
97      * identity will be propagated to EJB calls but will not be used for
98      * web container manager authorization. In general servlets should use
99      * the servlet-specific version of login instead.
100      *
101      * @param user User name.
102      * @param password Password for user.
103      * @param realm the realm name in which the user should be logged in.
104      * @param errors errors=true, propagate any exception encountered to the user
105      * errors=false, no exceptions are propagated.
106      * @return Boolean containing true or false to indicate success or
107      * failure of login.
108      * @throws Exception any exception encountered during Login.
109      */

110     public Boolean JavaDoc login(final String JavaDoc user, final String JavaDoc password,
111         final String JavaDoc realm, boolean errors) throws Exception JavaDoc
112     {
113         Boolean JavaDoc authenticated = null;
114         // check permission to login
115
try {
116
117             // exception thrown on failure
118
checkLoginPermission(user);
119
120             // try to login. doPrivileged is used since application code does
121
// not have permissions to process the jaas login.
122
authenticated = (Boolean JavaDoc)
123                 AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
124                     public java.lang.Object JavaDoc run() {
125                     // if realm is null, LCD will log into the default realm
126
if (isServer) {
127                             LoginContextDriver.login(user, password, realm);
128                         } else {
129                             int type = AppContainer.USERNAME_PASSWORD;
130                             System.setProperty(
131                                 ClientPasswordLoginModule.LOGIN_NAME, user);
132                             System.setProperty(
133                                 ClientPasswordLoginModule.LOGIN_PASSWORD,
134                                 password);
135                             //should not set realm here
136
LoginContextDriver.doClientLogin(type, handler);
137                         }
138                         return Boolean.valueOf(true);
139                     }
140                 });
141         } catch (Exception JavaDoc e) {
142             logger.severe("Programmatic login failed: "+e.toString());
143             if(errors == true){ // propagate the exception ahead
144
throw e;
145             } else{
146                 authenticated = Boolean.valueOf(false);
147             }
148         }
149         return authenticated;
150     }
151
152     /** Attempt to login.
153      *
154      * <P>Upon successful return from this method the SecurityContext will
155      * be set in the name of the given user as its Subject.
156      *
157      * <p>On client side, the actual login will not occur until we actually
158      * access a resource requiring a login. And a java.rmi.AccessException
159      * with COBRA NO_PERMISSION will occur when actual login is failed.
160      *
161      * <P>This method is intented primarily for EJBs wishing to do
162      * programmatic login. If servlet code used this method the established
163      * identity will be propagated to EJB calls but will not be used for
164      * web container manager authorization. In general servlets should use
165      * the servlet-specific version of login instead.
166      *
167      * @param user User name.
168      * @param password Password for user.
169      * @return Boolean containing true or false to indicate success or
170      * failure of login.
171      */

172     public Boolean JavaDoc login(final String JavaDoc user, final String JavaDoc password)
173     {
174         // call login with realm-name = null and request for errors = false
175
Boolean JavaDoc authenticated = null;
176         try{
177             authenticated = login(user, password, null, false);
178         } catch(Exception JavaDoc e){
179             // sanity checking, will never come here
180
authenticated = Boolean.valueOf(false);
181         }
182         return authenticated;
183     }
184     /** Attempt to login. This method is specific to servlets (and JSPs).
185      *
186      * <P>Upon successful return from this method the SecurityContext will
187      * be set in the name of the given user as its Subject. In addition, the
188      * principal stored in the request is set to the user name. If a session
189      * is available, its principal is also set to the user provided.
190      *
191      * @returns Boolean containing true or false to indicate success or
192      * failure of login.
193      * @param realm
194      * @param errors
195      * @param user User name.
196      * @param password Password for user.
197      * @param request HTTP request object provided by caller application. It
198      * should be an instance of HttpRequestFacade.
199      * @param response HTTP response object provided by called application. It
200      * should be an instance of HttpServletResponse.
201      * @throws Exception any exceptions encountered during login
202      * @return Boolean indicating true for successful login and false otherwise
203      */

204     public Boolean JavaDoc login(final String JavaDoc user, final String JavaDoc password,
205                          final String JavaDoc realm,
206                          final HttpServletRequest JavaDoc request,
207                          final HttpServletResponse JavaDoc response, boolean errors)
208                          throws Exception JavaDoc
209     {
210         Boolean JavaDoc authenticated = null;
211         try{
212             // check permission to login
213
checkLoginPermission(user);
214             // try to login. doPrivileged is used since application code does
215
// not have permissions to process the jaas login.
216
authenticated = (Boolean JavaDoc)
217                 AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
218                     public java.lang.Object JavaDoc run() {
219                         return WebProgrammaticLogin.login(user, password, realm,
220                                                           request, response);
221                     }
222                 });
223         } catch(Exception JavaDoc e){
224             if(errors != true){
225                 authenticated = Boolean.valueOf(false);
226             } else{
227                 throw e;
228             }
229         }
230         return authenticated;
231     }
232
233     /**
234      * Attempt to login. This method is specific to servlets (and JSPs).
235      *
236      * <P>Upon successful return from this method the SecurityContext will
237      * be set in the name of the given user as its Subject. In addition, the
238      * principal stored in the request is set to the user name. If a session
239      * is available, its principal is also set to the user provided.
240      *
241      * @param user User name.
242      * @param password Password for user.
243      * @param request HTTP request object provided by caller application. It
244      * should be an instance of HttpRequestFacade.
245      * @param response HTTP response object provided by called application. It
246      * should be an instance of HttpServletResponse.
247      * @return Boolean containing true or false to indicate success or
248      * failure of login.
249      *
250      */

251     public Boolean JavaDoc login(final String JavaDoc user, final String JavaDoc password,
252                          final HttpServletRequest JavaDoc request,
253                          final HttpServletResponse JavaDoc response)
254     {
255         Boolean JavaDoc authenticated = null;
256         try{
257             // pass a null realmname and errors=false
258
authenticated = login(user, password, null, request, response, false);
259         }catch (Exception JavaDoc e){
260             // sanity check will never come here
261
authenticated = Boolean.valueOf(false);
262         }
263         return authenticated;
264     }
265     /**
266      * Attempt to logout.
267      * @returns Boolean containing true or false to indicate success or
268      * failure of logout.
269      *
270      */

271     public Boolean JavaDoc logout()
272     {
273         Boolean JavaDoc loggedout = null;
274         try{
275            loggedout = logout(false);
276         } catch(Exception JavaDoc e){
277             // sanity check will never come here
278
loggedout = Boolean.valueOf(false);
279         }
280         return loggedout;
281     }
282     /**
283      * Attempt to logout.
284      * @param errors, errors = true, the method will propagate the exceptions
285      * encountered while logging out, errors=false will return a Boolean value
286      * of false indicating failure of logout
287      * @return Boolean containing true or false to indicate success or
288      * failure of logout.
289      * @throws Exception encountered while logging out, if errors==false
290      *
291      */

292     public Boolean JavaDoc logout(boolean errors) throws Exception JavaDoc
293     {
294         Boolean JavaDoc loggedout = null;
295         // check logout permission
296
try{
297             checkLogoutPermission();
298             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
299                 public java.lang.Object JavaDoc run() {
300                     if (isServer) {
301                         LoginContextDriver.logout();
302                     } else {
303                         Properties JavaDoc sysProp = System.getProperties();
304                         sysProp.remove(ClientPasswordLoginModule.LOGIN_NAME);
305                         sysProp.remove(ClientPasswordLoginModule.LOGIN_PASSWORD);
306                         LoginContextDriver.doClientLogout();
307                         //If user try to access a protected resource after here
308
//then it will prompt for password in appclient or
309
//just fail in standalone client.
310
}
311                     return null;
312                 }
313             });
314             loggedout = Boolean.valueOf(true);
315         } catch (Exception JavaDoc e) {
316             logger.log(Level.WARNING, "Programmatic logout failed: "+e.toString());
317             if(errors){
318                 throw e;
319             } else{
320                 loggedout = Boolean.valueOf(false);
321             }
322         }
323         return loggedout;
324     }
325
326     /**
327      * Attempt to logout. Also removes principal from request (and session
328      * if available).
329      *
330      * @returns Boolean containing true or false to indicate success or
331      * failure of logout.
332      *
333      */

334     public Boolean JavaDoc logout(final HttpServletRequest JavaDoc request,
335                           final HttpServletResponse JavaDoc response)
336     {
337         Boolean JavaDoc loggedout = null;
338         try{
339             loggedout = logout(request, response, false);
340         }catch(Exception JavaDoc e){
341             // sanity check, will never come here
342
loggedout = Boolean.valueOf(false);
343         }
344         return loggedout;
345     }
346
347     /**
348      * Attempt to logout. Also removes principal from request (and session
349      * if available).
350      * @param errors, errors = true, the method will propagate the exceptions
351      * encountered while logging out, errors=false will return a Boolean value
352      * of false indicating failure of logout
353      *
354      * @return Boolean containing true or false to indicate success or
355      * failure of logout.
356      * @throws Exception, exception encountered while logging out and if errors
357      * == true
358      */

359     public Boolean JavaDoc logout(final HttpServletRequest JavaDoc request,
360                           final HttpServletResponse JavaDoc response,
361                           boolean errors) throws Exception JavaDoc
362     {
363         // check logout permission
364
Boolean JavaDoc loggedout = null;
365         try{
366             checkLogoutPermission();
367             loggedout = (Boolean JavaDoc)
368                 AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc() {
369                 public java.lang.Object JavaDoc run() throws Exception JavaDoc{
370                     return WebProgrammaticLogin.logout(request, response);
371                 }
372             });
373         }catch(Exception JavaDoc e){
374             if(errors){
375                 throw e;
376             }else{
377                 loggedout = Boolean.valueOf(false);
378             }
379         }
380         return loggedout;
381     }
382
383     
384     /**
385      * Check whether caller has login permission.
386      *
387      */

388     private void checkLoginPermission(String JavaDoc user) throws Exception JavaDoc
389     {
390         try {
391             if(logger.isLoggable(Level.FINE)){
392                 logger.log(Level.FINE, "ProgrammaticLogin.login() called for user: "
393                     + user);
394             }
395             SecurityManager JavaDoc sm = System.getSecurityManager();
396             if (sm != null) {
397                 sm.checkPermission(plLogin);
398             }
399
400         } catch (Exception JavaDoc e) {
401             logger.warning("proglogin.noperm");
402             throw e;
403         }
404     }
405
406
407     /**
408      * Check if caller has logout permission.
409      *
410      */

411     private void checkLogoutPermission() throws Exception JavaDoc
412     {
413         try {
414             if(logger.isLoggable(Level.FINE)){
415                 logger.log(Level.FINE, "ProgrammaticLogin.logout() called.");
416             }
417             SecurityManager JavaDoc sm = System.getSecurityManager();
418             if (sm != null) {
419                 sm.checkPermission(plLogout);
420             }
421             
422         } catch (Exception JavaDoc e) {
423             logger.warning("prologout.noperm");
424             throw e;
425         }
426     }
427     
428
429
430
431 }
432
Popular Tags