KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > www > WebSessionServlet


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: WebSessionServlet.java,v 1.20 2007/02/20 04:10:43 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.www;
23
24 import java.io.IOException JavaDoc;
25 import java.security.Principal JavaDoc;
26 import java.util.Date JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.util.logging.Logger JavaDoc;
29
30 import javax.servlet.ServletConfig JavaDoc;
31 import javax.servlet.ServletContext JavaDoc;
32 import javax.servlet.ServletException JavaDoc;
33 import javax.servlet.http.HttpServlet JavaDoc;
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import javax.servlet.http.HttpServletResponse JavaDoc;
36 import javax.servlet.http.HttpSession JavaDoc;
37
38 import org.opensubsystems.core.error.OSSException;
39 import org.opensubsystems.core.util.CallContext;
40 import org.opensubsystems.core.util.ClassUtils;
41 import org.opensubsystems.core.util.Config;
42 import org.opensubsystems.core.util.GlobalConstants;
43 import org.opensubsystems.core.util.Log;
44 import org.opensubsystems.core.util.MyTimer;
45
46 /**
47  * Base class for all servlets developed as part of this project. It's main
48  * responsibility is to provide session information if required therefore making
49  * sure that nobody who is not logged in (or otherwise authenticated) can proceed.
50  * This servlet intercepts all requests, makes sure that valid HTTP session is
51  * established and after credentials are verified, let the request proceed.
52  *
53  * Developers are adviced to derive all servlets from this servlet since this
54  * helps us to establish effective security policy at a single place.
55  *
56  * @version $Id: WebSessionServlet.java,v 1.20 2007/02/20 04:10:43 bastafidli Exp $
57  * @author Miro Halas
58  * @code.reviewer Miro Halas
59  * @code.reviewed 1.13 2006/02/24 00:17:43 jlegeny
60  */

61 public class WebSessionServlet extends HttpServlet JavaDoc
62 {
63    // Configuration settings ///////////////////////////////////////////////////
64

65    /**
66     * Configuration setting specifying if the web tier should cache the request
67     * dispatchers used to dispatch client requests to various web resources.
68     * Caching of the request dispatchers can improve performance, but not all
69     * web containers allows to do it. Jetty allows this, some version of Weblogic
70     * don't.
71     * @see #WEBSESSION_DISPATCHER_CACHED_DEFAULT
72     */

73    public static final String JavaDoc WEBSESSION_DISPATCHER_CACHED
74                                  = "oss.webserver.dispatcher.cached";
75
76    /**
77     * Configuration setting specifying if the server must ensure that the client
78     * accepted the server session before it allows further communication. This
79     * improves the login process if one is needed since at the time of login
80     * the server already knows that the client supports and accepted its session
81     * tracking.
82     * @see #WEBSESSION_HADSHAKE_REQUIRED_DEFAULT
83     */

84    public static final String JavaDoc WEBSESSION_HANDSHAKE_REQUIRED
85                                  = "oss.webserver.sessionhandshake.required";
86
87    /**
88     * Configuration setting specifying the URL of handshake page to which user
89     * will be redirected if handshake is required and session wasn't confirmed
90     * at the time when the request is submitted to the server.
91     */

92    public static final String JavaDoc WEBSESSION_HANDSHAKE_URL = "oss.webserver.sessionhandshake.url";
93
94    /**
95     * Configuration setting specifying if user has to be logged in in order to
96     * process his or her request sent to the server.
97     * @see #WEBSESSION_LOGIN_REQUIRED_DEFAULT
98     */

99    public static final String JavaDoc WEBSESSION_LOGIN_REQUIRED
100                                  = "oss.webserver.login.required";
101
102    /**
103     * Configuration setting specifying the URL of login page to which user will
104     * be redirected if login is required and user is not logged in at the time
105     * when request is submitted to the server.
106     */

107    public static final String JavaDoc WEBSESSION_LOGIN_URL = "oss.webserver.login.url";
108
109    /**
110     * Configuration setting specifying name of the class implementing
111     * SessionValidator interface to verify validity of a session each time a
112     * request is submitted to the server.
113     */

114    public static final String JavaDoc SESSION_VALIDATOR_CLASS
115                                  = "oss.webserver.sessionvalidator.class";
116
117    /**
118     * Configuration setting specifying if the login page should be displayed
119     * in a secure mode using SSL protocol.
120     * @see #s_bLoginSecure
121     * @see #DEFAULT_LOGIN_SECURE
122     */

123    public static final String JavaDoc LOGIN_SECURE = "oss.login.secure";
124
125    /**
126     * Configuration setting specifying if all pages of the application should be
127     * displayed in a secure mode using SSL protocol.
128     * @see #s_bApplicationSecure
129     * @see #DEFAULT_APPLICATION_SECURE
130     */

131    public static final String JavaDoc APPLICATION_SECURE = "oss.application.secure";
132
133    // Constants ////////////////////////////////////////////////////////////////
134

135    /**
136     * Default value for WEBSESSION_DISPATCHER_CACHED.
137     * By default don't cache them since this will work on any servlet engine.
138     * @see #WEBSESSION_DISPATCHER_CACHED
139     */

140    public static final boolean WEBSESSION_DISPATCHER_CACHED_DEFAULT = false;
141
142    /**
143     * Default value for WEBSESSION_HANDSHAKE_REQUIRED
144     * @see #WEBSESSION_HANDSHAKE_REQUIRED
145     */

146    public static final boolean WEBSESSION_HADSHAKE_REQUIRED_DEFAULT = false;
147    
148    /**
149     * Default value for WEBSESSION_LOGIN_REQUIRED
150     * @see #WEBSESSION_LOGIN_REQUIRED
151     */

152    public static final boolean WEBSESSION_LOGIN_REQUIRED_DEFAULT = false;
153
154    /**
155     * Name of the HTTP session object storing path where to continue after login.
156     */

157    public static final String JavaDoc LOGIN_FORWARD_SESSION_PARAM = "login.forward";
158
159    /**
160     * Full URL how this servlet was invoked so that GUI can use it for callbacks.
161     */

162    public static final String JavaDoc SERVLET_PATH_REQUEST_PARAM = "servletpath";
163
164    /**
165     * Parameter which must be specified in URL if the user should be attached
166     * to this server after it was logged in at some other server.
167     */

168    public static final String JavaDoc ATTACH_INTERNAL_SESSION_ID_URL_PARAM = "osssessionid";
169
170    /**
171     * Default value for LOGIN_SECURE.
172     * @see #s_bLoginSecure
173     * @see #LOGIN_SECURE
174     */

175    public static final boolean DEFAULT_LOGIN_SECURE = false;
176
177    /**
178     * Default value for APPLICATION_SECURE.
179     * @see #s_bApplicationSecure
180     * @see #APPLICATION_SECURE
181     */

182    public static final boolean DEFAULT_APPLICATION_SECURE = DEFAULT_LOGIN_SECURE;
183
184    // Cached values ////////////////////////////////////////////////////////////
185

186    /**
187     * Logger for this class
188     */

189    private static Logger JavaDoc s_logger = Log.getInstance(WebSessionServlet.class);
190
191    /**
192     * Flag specifying if caching of request dispatchers is enabled.
193     * Jetty allows that, Weblogic doesn't.
194     * @see #WEBSESSION_DISPATCHER_CACHED
195     * @see #WEBSESSION_DISPATCHER_CACHED_DEFAULT
196     */

197    private static boolean s_bRequestDispatcherCached;
198    
199    /**
200     * True if client has to accept the session before it can proceed with further
201     * requests.
202     * @see #WEBSESSION_HANDSHAKE_REQUIRED
203     * @see #WEBSESSION_HADSHAKE_REQUIRED_DEFAULT
204     */

205    private boolean m_bHandhakeRequired;
206    
207    /**
208     * URL of the hadnshake page in case handshake is requried.
209     */

210    protected String JavaDoc m_strHandshakeURL;
211    
212    /**
213     * True if user has to be logged in to process request by this servlet
214     * @see #WEBSESSION_LOGIN_REQUIRED
215     * @see #WEBSESSION_LOGIN_REQUIRED_DEFAULT
216     */

217    private boolean m_bLoginRequired;
218    
219    /**
220     * URL of the login page in case login is requried.
221     */

222    private String JavaDoc m_strLoginURL;
223    
224    /**
225     * Servlets context.
226     */

227    protected ServletContext JavaDoc m_scServletContext;
228    
229    /**
230     * If not null, then this instance will be used to validate session for each
231     * request.
232     */

233    protected SessionValidator m_sessionValidator;
234
235    /**
236     * Flag signaling if login will be processed using SSL.
237     * @see #LOGIN_SECURE
238     * @see #DEFAULT_LOGIN_SECURE
239     */

240    protected static boolean s_bLoginSecure;
241
242    /**
243     * Flag signaling if whole application will be using SSL.
244     * @see #APPLICATION_SECURE
245     * @see #DEFAULT_APPLICATION_SECURE
246     */

247    protected static boolean s_bApplicationSecure;
248
249    // Attributes ///////////////////////////////////////////////////////////////
250

251    /**
252     * Generated serial version id for this class.
253     */

254    private static final long serialVersionUID = 322547463691937622L;
255
256    // Constructors /////////////////////////////////////////////////////////////
257

258    /**
259     * Static initializer.
260     */

261    static
262    {
263       // Load setting which specify if we can cache RequestDispatched
264
// Jetty allows that, Weblogic doesn't. There is only one property for
265
// all servlets therefore it is loaded using Config object.
266
Properties JavaDoc prpSettings;
267
268       prpSettings = Config.getInstance().getPropertiesSafely();
269       s_bRequestDispatcherCached = Config.getBooleanProperty(
270                                              prpSettings,
271                                              WEBSESSION_DISPATCHER_CACHED,
272                                              WEBSESSION_DISPATCHER_CACHED_DEFAULT,
273                                              "Request dispatcher caching flag");
274    }
275    
276    // Servlet operations ///////////////////////////////////////////////////////
277

278    /**
279     * {@inheritDoc}
280     */

281    public void init(
282       ServletConfig JavaDoc scConfig
283    ) throws ServletException JavaDoc
284    {
285       super.init(scConfig);
286
287       m_scServletContext = scConfig.getServletContext();
288       
289       String JavaDoc strTemp;
290       
291       strTemp = WebUtils.readProperty(scConfig, WEBSESSION_HANDSHAKE_REQUIRED,
292                                       Boolean.toString(WEBSESSION_HADSHAKE_REQUIRED_DEFAULT),
293                                       false);
294       m_bHandhakeRequired = Boolean.valueOf(strTemp).booleanValue();
295       s_logger.config(WEBSESSION_HANDSHAKE_REQUIRED + " = " + m_bHandhakeRequired);
296       
297       
298       // Empty URL is allowed since that can be the root of the web site
299
m_strHandshakeURL = WebUtils.readProperty(scConfig, WEBSESSION_HANDSHAKE_URL,
300                                             null, true);
301       s_logger.config(WEBSESSION_HANDSHAKE_URL + " = '" + m_strHandshakeURL + "'");
302       if ((m_bHandhakeRequired) && (m_strHandshakeURL == null))
303       {
304          throw new ServletException JavaDoc("Handshake is required, but handshake URL" +
305                                     " is not set using property " + WEBSESSION_HANDSHAKE_URL);
306       }
307       
308
309       strTemp = WebUtils.readProperty(scConfig, WEBSESSION_LOGIN_REQUIRED,
310                                       Boolean.toString(WEBSESSION_LOGIN_REQUIRED_DEFAULT),
311                                       false);
312       m_bLoginRequired = Boolean.valueOf(strTemp).booleanValue();
313       s_logger.config(WEBSESSION_LOGIN_REQUIRED + " = " + m_bLoginRequired);
314
315       
316       // Empty URL is allowed since that can be the root of the web site
317
m_strLoginURL = WebUtils.readProperty(scConfig, WEBSESSION_LOGIN_URL,
318                                             null, true);
319       s_logger.config(WEBSESSION_LOGIN_URL + " = '" + m_strLoginURL + "'");
320       if ((m_bLoginRequired) && (m_strLoginURL == null))
321       {
322          throw new ServletException JavaDoc("Login is required, but login URL is not set" +
323                                     " using property " + WEBSESSION_LOGIN_URL);
324       }
325
326       // Empty sesion validator is allowed since we don't have to validate the session
327
strTemp = WebUtils.readProperty(scConfig, SESSION_VALIDATOR_CLASS,
328                                       null, true);
329       s_logger.config(SESSION_VALIDATOR_CLASS + " = " + strTemp);
330       if ((strTemp != null) && (strTemp.length() > 0))
331       {
332          try
333          {
334             m_sessionValidator = (SessionValidator)ClassUtils.createNewInstance(strTemp);
335             s_logger.finest("Instantiated session validator " + strTemp);
336          }
337          catch (OSSException ossExc)
338          {
339              throw new ServletException JavaDoc("Unexpected exception.", ossExc);
340          }
341       }
342
343       // Load flag signaling if login is secure
344
strTemp = WebUtils.readProperty(scConfig, LOGIN_SECURE,
345                             Boolean.toString(DEFAULT_LOGIN_SECURE), false);
346       s_bLoginSecure = Boolean.valueOf(strTemp).booleanValue();
347       s_logger.config(LOGIN_SECURE + " = " + s_bLoginSecure);
348
349       // Load flag signaling if application has to be running as secure
350
strTemp = WebUtils.readProperty(scConfig, APPLICATION_SECURE,
351                             Boolean.toString(DEFAULT_APPLICATION_SECURE), false);
352       s_bApplicationSecure = Boolean.valueOf(strTemp).booleanValue();
353       s_logger.config(APPLICATION_SECURE + " = " + s_bApplicationSecure);
354    }
355
356    /**
357     * {@inheritDoc}
358     */

359    public void destroy(
360    )
361    {
362       super.destroy();
363    }
364
365    /**
366     * Main service routine for the Servlet.
367     *
368     * Subclasses can't override this method to make sure that the if-modified
369     * logic is handled correctly (when they override getLastModified method).
370     * Only the doXXX method should be overriden. This servlet also makes sure
371     * (if configured that way), that nobody who is not logged in can proceed.
372     *
373     * @param hsrqRequest - the servlet request.
374     * @param hsrpResponse - the servlet response.
375     * @throws ServletException - an error has occured while serving request
376     * @throws IOException - an error has occured while writing response
377     */

378    protected final void service(
379       HttpServletRequest JavaDoc hsrqRequest,
380       HttpServletResponse JavaDoc hsrpResponse
381    ) throws ServletException JavaDoc,
382             IOException JavaDoc
383    {
384       MyTimer timer = new MyTimer();
385       HttpSession JavaDoc hsSession; // http session used to maintain link between
386
// browser and server
387

388       hsSession = hsrqRequest.getSession(true);
389       try
390       {
391          // Set up variable for server port number the application
392
// is currently running on
393
WebUtils.adjust(hsrqRequest);
394          
395          // Capture incoming request, this can help us identify request which
396
// didn't complete
397
// Format is Thread name, time, in or out, time in user readable form, session ID
398
StringBuffer JavaDoc sbBuffer = new StringBuffer JavaDoc();
399
400          sbBuffer.append(Thread.currentThread().getName());
401          sbBuffer.append(",in");
402          sbBuffer.append(",");
403          sbBuffer.append(timer.getStartTime());
404          sbBuffer.append(",");
405          sbBuffer.append((new Date JavaDoc(timer.getStartTime())).toString());
406          sbBuffer.append(",");
407          sbBuffer.append(WebSessionUtils.getSessionId(hsSession));
408          sbBuffer.append(",");
409          sbBuffer.append(hsSession.getId());
410          sbBuffer.append(",");
411          sbBuffer.append("0"); // no initial processing time
412
s_logger.fine(sbBuffer.toString());
413
414          // Save the URL how this servlet was invoked since if we forward it to
415
// JSP, the getServletPath points to the JSP and not to the original
416
// servlet (in Jetty 4.2.9)
417
hsrqRequest.setAttribute(SERVLET_PATH_REQUEST_PARAM,
418                                   hsrqRequest.getContextPath()
419                                   + hsrqRequest.getServletPath());
420          try
421          {
422             // Toggle URL (from http -> https or from https -> http)
423
if (hsrqRequest.isSecure() != shouldRequestBeSecure())
424             {
425                String JavaDoc strOriginal;
426                String JavaDoc stsRedirect;
427                
428                strOriginal = WebUtils.getFullRequestURL(hsrqRequest);
429                stsRedirect = WebUtils.toggleSecure(hsrqRequest,
430                                                          strOriginal,
431                                                          shouldRequestBeSecure());
432                s_logger.finer("Redirecting due to HTTP(S) from " + strOriginal
433                               + " to " + stsRedirect);
434                // redirect to the toggled url
435
hsrpResponse.sendRedirect(stsRedirect);
436             }
437             else
438             {
439                if ((m_bHandhakeRequired) && (hsSession.isNew()))
440                {
441                   s_logger.finest("Session " + hsSession.getId()
442                                   + " is still new and hanshake is required");
443                   handleNewSession(hsSession, hsrqRequest, hsrpResponse);
444                }
445                else
446                {
447                   // The client has accepted session, or handshake wans't
448
// required so proceed with servicing the request
449
Principal JavaDoc userCredentials;
450
451                   // Find out if the client has already logged in. This is also
452
// done if login is not required since some applications
453
// provide optional login and for those we want to establish
454
// user's identity as well if user has already logged in
455
userCredentials = verifyLogin(hsSession, hsrqRequest, hsrpResponse);
456                   if ((m_bLoginRequired) && (userCredentials == null))
457                   {
458                      // User hasn't logged in yet. Store the requested URL in
459
// the session object so that after login user can continue
460
// to the requested page
461
saveLoginRedirect(hsSession,
462                                        WebUtils.getFullRequestURL(hsrqRequest));
463             
464                      // Give derived classes opportunity to handle any
465
// functionality that is common to all requests
466
// We need to call this since if this is already request
467
// to a login page then redirectToLogin would just simply
468
// handle the login page as if it was a normal request
469
preservice(hsSession, hsrqRequest, hsrpResponse, false);
470                      
471                      // We cannot use RequestDispatcher because browser would
472
// cache this login page as the requested page
473
redirectToLogin(hsrqRequest, hsrpResponse);
474                   }
475                   else
476                   {
477                      // If there is one associate user's identity with this
478
// thread so that the app server can find out, who is
479
// the current user Everything is OK, now service the
480
// request We have to have try/finally block here so we
481
// reset current user
482
if (userCredentials != null)
483                      {
484                         CallContext.getInstance().setCurrentUserAndSession(
485                            userCredentials, WebSessionUtils.getSessionId(hsSession));
486                      }
487                   
488                      // Give derived classes opportunity to handle any
489
// functionality that is common to all requests
490
preservice(hsSession, hsrqRequest, hsrpResponse, true);
491          
492                      // Service the request by calling the base class method
493
// so that getLastModified() method is correctly called
494
super.service(hsrqRequest, hsrpResponse);
495                   }
496                }
497             }
498          }
499          finally
500          {
501             CallContext.getInstance().reset();
502          }
503       }
504       finally
505       {
506          StringBuffer JavaDoc sbBuffer = new StringBuffer JavaDoc();
507          timer.stop();
508
509          sbBuffer.append(Thread.currentThread().getName());
510          sbBuffer.append(",out");
511          sbBuffer.append(",");
512          sbBuffer.append(timer.getStopTime());
513          sbBuffer.append(",");
514          sbBuffer.append((new Date JavaDoc(timer.getStopTime())).toString());
515          sbBuffer.append(",");
516          try
517          {
518             sbBuffer.append(WebSessionUtils.getSessionId(hsSession));
519             sbBuffer.append(",");
520             sbBuffer.append(hsSession.getId());
521          }
522          catch (IllegalStateException JavaDoc iseExc)
523          {
524             // This happen when the session was invalidated, don't even record it
525
sbBuffer.append("invalidated,invalidated");
526          }
527          sbBuffer.append(",");
528          sbBuffer.append(timer.getDuration());
529          sbBuffer.append(",");
530          sbBuffer.append(timer.toString());
531          s_logger.fine(sbBuffer.toString());
532       }
533    }
534
535    /**
536     * {@inheritDoc}
537     */

538    public String JavaDoc getServletInfo(
539    )
540    {
541       return this.getClass().getName();
542    }
543    
544    // Helper methods ///////////////////////////////////////////////////////////
545

546    /**
547     * Check if caching of request dispatchers is enabled.
548     * Jetty allows that, Weblogic doesn't.
549     *
550     * @return boolean
551     */

552    protected boolean isDispatcherCachingEnabled(
553    )
554    {
555       return s_bRequestDispatcherCached;
556    }
557
558    /**
559     * This function handles the scenarios, when the HTTP session generated for
560     * the client is still new and the client doesn't know about it yet. By
561     * default it just redirect to the handshake page. This method is called only
562     * when session handshake is required usually specified by configuration
563     * property.
564     *
565     * @param hsSession - HTTP session object
566     * @param hsrqRequest - the servlet request.
567     * @param hsrpResponse - the servlet response.
568     * @throws ServletException - problem has occured while processing request
569     * @throws IOException - problem has occured while processing request
570     * @see #WEBSESSION_HANDSHAKE_REQUIRED
571     */

572    protected void handleNewSession(
573       HttpSession JavaDoc hsSession,
574       HttpServletRequest JavaDoc hsrqRequest,
575       HttpServletResponse JavaDoc hsrpResponse
576    ) throws ServletException JavaDoc,
577              IOException JavaDoc
578    {
579       // TODO: For Miro: Replace the login page with handshake page
580

581       // This is new session, which means that the client visited the site
582
// for the first time or the client decide not to join session.
583
// In both cases redirect client to the login page. The login page
584
// should handle scenario if the client has already logged in to another
585
// node of a cluster if running in clustered environment and now he is
586
// for the first time accessing this node.
587
// Store the requested URL in the session object so that after
588
// login user can continue to the requested page
589

590       // This can be request which was routed to a new server
591
// and therefore the user may have logged in somewhere
592
// else as well. So lets figure out if this is really
593
// a brand new session or if it is an attach, but we let the login
594
// servlet do it and don't worry about it. If it is an attach then
595
// in the login servlet will immidiately redirect us back.
596
// This way also the HTTP session will be established
597
saveLoginRedirect(hsSession, WebUtils.getFullRequestURL(hsrqRequest));
598
599       // We cannot use RequestDispatcher because browser would cache this
600
// login page as the requested page
601
redirectToLogin(hsrqRequest, hsrpResponse);
602    }
603
604    /**
605     * Verify, if user has already logged into this session.
606     *
607     * @param hsSession - HTTP session object
608     * @param hsrqRequest - the servlet request.
609     * @param hsrpResponse - the servlet response.
610     * @return Principal - object representing user's credentials or null,
611     * if user is not logged in yet
612     * @throws ServletException - problem has occured while processing request
613     * @throws IOException - problem has occured while processing request
614     */

615    protected Principal JavaDoc verifyLogin(
616       HttpSession JavaDoc hsSession,
617       HttpServletRequest JavaDoc hsrqRequest,
618       HttpServletResponse JavaDoc hsrpResponse
619    ) throws ServletException JavaDoc,
620             IOException JavaDoc
621    {
622       Principal JavaDoc loggedUser;
623       
624       loggedUser = WebSessionUtils.getLoggedInUserInfo(hsSession);
625
626       if ((loggedUser != null) && (m_sessionValidator != null))
627       {
628          // We thing the user is logged in and we have configured session
629
// validator, therefore check if the user is really logged in because
630
// it may have been logged out meanwhile
631
String JavaDoc strSessionGenCode;
632          
633          strSessionGenCode = WebSessionUtils.getSessionId(hsSession);
634          try
635          {
636             if (!m_sessionValidator.checkSession(strSessionGenCode))
637             {
638                // Not logged in anymore
639
loggedUser = null;
640                saveLoginRedirect(hsSession, WebUtils.getFullRequestURL(hsrqRequest));
641                redirectToLogin(hsrqRequest, hsrpResponse);
642             }
643          }
644          catch (OSSException bfeExc)
645          {
646             throw new ServletException JavaDoc(bfeExc);
647          }
648       }
649       
650       return loggedUser;
651    }
652
653    /**
654     * Get the URL to which user should be redirected after he is successfully
655     * logged into the system.
656     *
657     * @param hsSession - HTTP session object
658     * @param hsrqRequest - the servlet request
659     * @return String - URL to redirect user after login, null if none exists
660     */

661    protected String JavaDoc getLoginRedirect(
662       HttpSession JavaDoc hsSession,
663       HttpServletRequest JavaDoc hsrqRequest
664    )
665    {
666       if (GlobalConstants.ERROR_CHECKING)
667       {
668          assert hsSession != null : "Session cannot be null here";
669       }
670
671       String JavaDoc strLoginRedirect = null;
672       
673       strLoginRedirect = (String JavaDoc)hsSession.getAttribute(LOGIN_FORWARD_SESSION_PARAM);
674       s_logger.finest("Retrieved login redirect to " + strLoginRedirect);
675       
676       if (strLoginRedirect != null)
677       {
678          // there has to be switched from https -> http or from http -> https
679
// so call particular method that will return toggled URL
680
strLoginRedirect = WebUtils.toggleSecure(hsrqRequest,
681                                                   strLoginRedirect,
682                                                   isApplicationSecure());
683       }
684
685       return strLoginRedirect;
686    }
687
688    /**
689     * Save the URL to which user should be redirected after he is successfully
690     * logged in to the system. If there already exist redirection URL and user
691     * has not been redirected there yet, this request will be ignored
692     *
693     * @param hsSession - HTTP session object
694     * @param strFullRedirectURL - URL to redirect user after login
695     * @return boolean - true if URL was set, false if it was ignored
696     */

697    protected boolean saveLoginRedirect(
698       HttpSession JavaDoc hsSession,
699       String JavaDoc strFullRedirectURL
700    )
701    {
702       if (GlobalConstants.ERROR_CHECKING)
703       {
704          assert hsSession != null : "Session cannot be null here";
705       }
706
707       boolean bReturn = false;
708
709       if (hsSession.getAttribute(LOGIN_FORWARD_SESSION_PARAM) == null)
710       {
711          // No previous value exists
712
hsSession.setAttribute(LOGIN_FORWARD_SESSION_PARAM, strFullRedirectURL);
713          s_logger.finest("Saved login redirect " + strFullRedirectURL);
714          bReturn = true;
715       }
716
717       return bReturn;
718    }
719
720    /**
721     * Reset the URL to which user should be redirected after he is successfully
722     * logge to the system to uninitialized value.
723     *
724     * @param hsSession - HTTP session object
725     */

726    protected void resetLoginRedirect(
727       HttpSession JavaDoc hsSession
728    )
729    {
730       if (GlobalConstants.ERROR_CHECKING)
731       {
732          assert hsSession != null : "Session cannot be null here";
733       }
734
735       hsSession.removeAttribute(LOGIN_FORWARD_SESSION_PARAM);
736       s_logger.finest("Reseted login redirect");
737    }
738
739    /**
740     * Redirect client to the login page. This function call has to be the last
741     * thing done in response to client's request.
742     *
743     * @param hsrqRequest - the servlet request.
744     * @param hsrpResponse - the servlet response.
745     * @throws ServletException - problems redirecting to login
746     * @throws IOException - problems redirecting to login
747     */

748    protected void redirectToLogin(
749       HttpServletRequest JavaDoc hsrqRequest,
750       HttpServletResponse JavaDoc hsrpResponse
751    ) throws ServletException JavaDoc,
752             IOException JavaDoc
753    {
754       // We cannot use RequestDispatcher because browser would cache this
755
// login page as the requested page
756
s_logger.finest("Redirecting to login " + hsrqRequest.getContextPath()
757                       + m_strLoginURL);
758       redirect(m_strLoginURL, hsrqRequest, hsrpResponse);
759    }
760
761    /**
762     * Redirect client to the handshake. This function call has to be the
763     * last thing done in response to client's request.
764     *
765     * @param hsrqRequest - the servlet request.
766     * @param hsrpResponse - the servlet response.
767     * @throws ServletException - problems redirecting to login
768     * @throws IOException - problems redirecting to login
769     */

770    protected void redirectToHandshake(
771       HttpServletRequest JavaDoc hsrqRequest,
772       HttpServletResponse JavaDoc hsrpResponse
773    ) throws ServletException JavaDoc,
774             IOException JavaDoc
775    {
776       // We cannot use RequestDispatcher because browser would cache this
777
// login page as the requested page
778
s_logger.finest("Redirecting to handshake " + hsrqRequest.getContextPath()
779                       + m_strLoginURL);
780       redirect(m_strHandshakeURL, hsrqRequest, hsrpResponse);
781    }
782
783    /**
784     * Redirect client to another page propagating the internal session ID if any.
785     * This function call has to be the last thing done in response to client's
786     * request.
787     *
788     * @param strUrl - part of the URL used for constructing final URL
789     * @param hsrqRequest - the servlet request.
790     * @param hsrpResponse - the servlet response.
791     * @throws ServletException - problems redirecting to login
792     * @throws IOException - problems redirecting to login
793     */

794    protected void redirect(
795       String JavaDoc strUrl,
796       HttpServletRequest JavaDoc hsrqRequest,
797       HttpServletResponse JavaDoc hsrpResponse
798    ) throws ServletException JavaDoc,
799             IOException JavaDoc
800    {
801       // We cannot use RequestDispatcher because browser would cache this
802
// page as the requested page
803

804       // This can be request to attach when user has logged in on some other
805
// server and now we just need to verify that he session exists here
806
// If the URL contains the session information we need to send it to login
807
// and let the login decide if it lets the user pass as if it was logged in
808
// or if it will require from user to login again
809
String JavaDoc strAttachSessionId;
810       StringBuffer JavaDoc sbUrl = new StringBuffer JavaDoc();
811
812       sbUrl.append(hsrqRequest.getContextPath());
813       sbUrl.append(strUrl);
814       if (sbUrl.indexOf(ATTACH_INTERNAL_SESSION_ID_URL_PARAM) == -1)
815       {
816          strAttachSessionId = hsrqRequest.getParameter(
817                                  ATTACH_INTERNAL_SESSION_ID_URL_PARAM);
818          if ((strAttachSessionId != null) && (strAttachSessionId.length() > 0))
819          {
820             // The session parameter is not there yet
821
if (sbUrl.indexOf("?") == -1)
822             {
823                // There is no query string yet
824
sbUrl.append("?");
825             }
826             else
827             {
828                // There is already a query string so just add another parameter
829
sbUrl.append("&");
830             }
831             sbUrl.append(ATTACH_INTERNAL_SESSION_ID_URL_PARAM);
832             sbUrl.append("=");
833             sbUrl.append(strAttachSessionId);
834          }
835       }
836
837       hsrpResponse.sendRedirect(sbUrl.toString());
838    }
839
840    /**
841     * This method gives derived servlets execute common logic which needs to be
842     * executed for each request. It is executed right before the service itself
843     * once handshake was established (if required), login was verified (if
844     * required) and identity of user if one is logged in was established.
845     * It can also be called if login is required and we are redirecting to the
846     * login page.
847     *
848     * @param hsSession - HTTP session object
849     * @param hsrqRequest - the servlet request.
850     * @param hsrpResponse - the servlet response.
851     * @param bLoginVerified - true if login was verified or it is not required,
852     * false if we are redirecting to the login page
853     * @throws ServletException - problems redirecting to login
854     * @throws IOException - problems redirecting to login
855     */

856    protected void preservice(
857       HttpSession JavaDoc hsSession,
858       HttpServletRequest JavaDoc hsrqRequest,
859       HttpServletResponse JavaDoc hsrpResponse,
860       boolean bLoginVerified
861    ) throws ServletException JavaDoc,
862             IOException JavaDoc
863    {
864       // Nothing to do for now
865
}
866
867    /**
868     * Return flag if request should be secure. This method returns application
869     * secure flag. Method should be overwtitten within LoginServlet and
870     * will return flag for login page.
871     *
872     * @return boolean - true = request should be secure
873     * - false = request should not be secure
874     */

875    protected boolean shouldRequestBeSecure(
876    )
877    {
878       return isApplicationSecure();
879    }
880
881    /**
882     * Return true if application is running as secure (SSL)
883     *
884     * @return boolean - true = application is secure (using HTTPS)
885     * - false = application is not secure (using HTTP)
886     */

887    protected boolean isApplicationSecure(
888    )
889    {
890       return s_bApplicationSecure;
891    }
892    
893    /**
894     * Return true if login is running as secure (SSL)
895     *
896     * @return boolean - true = login is secure (using HTTPS)
897     * - false = login is not secure (using HTTP)
898     */

899    protected boolean isLoginSecure(
900    )
901    {
902       return s_bLoginSecure;
903    }
904 }
905
Popular Tags