View Javadoc

1   package com.panogenesis.webapp.action;
2   
3   import java.io.IOException;
4   import java.util.HashMap;
5   import java.util.Map;
6   
7   import javax.servlet.ServletContext;
8   import javax.servlet.ServletException;
9   import javax.servlet.http.HttpServlet;
10  import javax.servlet.http.HttpServletRequest;
11  import javax.servlet.http.HttpServletResponse;
12  
13  import org.apache.commons.logging.Log;
14  import org.apache.commons.logging.LogFactory;
15  import com.panogenesis.Constants;
16  import com.panogenesis.util.StringUtil;
17  import com.panogenesis.webapp.util.SslUtil;
18  
19  
20  /***
21   * Implementation of <strong>HttpServlet</strong> that is used
22   * to get a username and password and encrypt the password
23   * before sending to container-managed authentication.
24   *
25   * <p><a href="LoginServlet.java.html"><i>View Source</i></a></p>
26   *
27   * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
28   *
29   * @web.servlet
30   *     display-name="Login Servlet"
31   *     load-on-startup="1"
32   *     name="login"
33   *
34   * @web.servlet-init-param
35   *     name="authURL"
36   *     value="${form.auth.action}"
37   *
38   * Change the following value to false if you don't require SSL for login
39   *
40   * @web.servlet-init-param
41   *     name="isSecure"
42   *     value="${secure.login}"
43   *
44   * If you're not using Tomcat, change encrypt-password to true
45   *
46   * @web.servlet-init-param
47   *     name="encrypt-password"
48   *     value="${encrypt.password}"
49   *
50   * @web.servlet-init-param
51   *     name="algorithm"
52   *     value="${encrypt.algorithm}"
53   *
54   * @web.servlet-mapping
55   *     url-pattern="/authorize/*"
56   */
57  public final class LoginServlet extends HttpServlet {
58      private static String authURL = "j_security_check";
59      private static String httpsPort = null;
60      private static String httpPort = null;
61      private static Boolean secure = Boolean.FALSE;
62      private static String algorithm = "SHA";
63      private static Boolean encrypt = Boolean.FALSE;
64      private transient final Log log = LogFactory.getLog(LoginServlet.class);
65  
66      /***
67       * Initializes the port numbers based on the port init parameters as defined
68       * in web.xml
69       */
70      private static void initializeSchemePorts(ServletContext servletContext) {
71          if (httpPort == null) {
72              String portNumber =
73                  servletContext.getInitParameter(SslUtil.HTTP_PORT_PARAM);
74              httpPort = ((portNumber == null) ? SslUtil.STD_HTTP_PORT : portNumber);
75          }
76  
77          if (httpsPort == null) {
78              String portNumber =
79                  servletContext.getInitParameter(SslUtil.HTTPS_PORT_PARAM);
80              httpsPort = ((portNumber == null) ? SslUtil.STD_HTTPS_PORT
81                                                : portNumber);
82          }
83      }
84  
85      // --------------------------------------------------------- Public Methods
86  
87      /***
88       * Validates the Init and Context parameters, configures authentication URL
89       *
90       * @throws ServletException if the init parameters are invalid or any
91       * other problems occur during initialisation
92       */
93      public void init() throws ServletException {
94          // Get the container authentication URL for FORM-based Authentication
95          // J2EE spec says should be j_security_check
96          authURL = getInitParameter(Constants.AUTH_URL);
97  
98          // Get the encryption algorithm to use for encrypting passwords before
99          // storing in database
100         algorithm = getInitParameter(Constants.ENC_ALGORITHM);
101 
102         /* This determines if the login uses SSL or not */
103         secure = Boolean.valueOf(getInitParameter("isSecure"));
104 
105         /* This determines if the password should be encrypted programmatically */
106         encrypt = Boolean.valueOf(getInitParameter("encrypt-password"));
107 
108         if (log.isDebugEnabled()) {
109             log.debug("Authentication URL: " + authURL);
110             log.debug("Use SSL for login? " + secure);
111             log.debug("Programmatic encryption of password? " + encrypt);
112             log.debug("Encryption algorithm: " + algorithm);
113         }
114 
115         ServletContext ctx = getServletContext();
116         initializeSchemePorts(ctx);
117 
118         if (log.isDebugEnabled()) {
119             log.debug("HTTP Port: " + httpPort);
120             log.debug("HTTPS Port: " + httpsPort);
121         }
122 
123         // Orion starts Servlets before Listeners, so check if the config
124         // object already exists
125         Map config = (HashMap) ctx.getAttribute(Constants.CONFIG);
126 
127         if (config == null) {
128             config = new HashMap();
129         }
130 
131         // update the config object with the init-params from this servlet
132         config.put(Constants.HTTP_PORT, httpPort);
133         config.put(Constants.HTTPS_PORT, httpsPort);
134         config.put(Constants.SECURE_LOGIN, secure);
135         config.put(Constants.ENC_ALGORITHM, algorithm);
136         config.put(Constants.ENCRYPT_PASSWORD, encrypt);
137         ctx.setAttribute(Constants.CONFIG, config);
138     }
139 
140     /***
141      * Route the user to the execute method
142      *
143      * @param request The HTTP request we are processing
144      * @param response The HTTP response we are creating
145      *
146      * @exception IOException if an input/output error occurs
147      * @exception ServletException if a servlet exception occurs
148      */
149     public void doGet(HttpServletRequest request, HttpServletResponse response)
150     throws IOException, ServletException {
151         execute(request, response);
152     }
153 
154     /***
155      * Route the user to the execute method
156      *
157      * @param request The HTTP request we are processing
158      * @param response The HTTP response we are creating
159      *
160      * @exception IOException if an input/output error occurs
161      * @exception ServletException if a servlet exception occurs
162      */
163     public void doPost(HttpServletRequest request, HttpServletResponse response)
164     throws IOException, ServletException {
165         execute(request, response);
166     }
167 
168     /***
169      * Process the specified HTTP request, and create the corresponding HTTP
170      * response (or forward to another web component that will create it).
171      *
172      * @param request The HTTP request we are processing
173      * @param response The HTTP response we are creating
174      *
175      * @exception IOException if an input/output error occurs
176      * @exception ServletException if a servlet exception occurs
177      */
178     public void execute(HttpServletRequest request, HttpServletResponse response)
179     throws IOException, ServletException {
180         // if user is already authenticated, it means they probably bookmarked
181         // or typed in the URL to login.jsp directly, route them to the main
182         // menu is this is the case
183         if (request.getRemoteUser() != null) {
184             if (log.isDebugEnabled()) {
185                 log.debug("User '" + request.getRemoteUser() +
186                           "' already logged in, routing to mainMenu");
187             }
188 
189             response.sendRedirect(request.getContextPath() + "/mainMenu.html");
190 
191             return;
192         }
193 
194         String redirectString =
195             SslUtil.getRedirectString(request, getServletContext(),
196                                       secure.booleanValue());
197 
198         if (redirectString != null) {
199             // Redirect the page to the desired URL
200             response.sendRedirect(response.encodeRedirectURL(redirectString));
201 
202             if (log.isDebugEnabled()) {
203                 log.debug("switching protocols, redirecting user");
204             }
205         }
206 
207         // Extract attributes we will need
208         String username = request.getParameter("j_username");
209         String password = request.getParameter("j_password");
210 
211         if (request.getParameter("rememberMe") != null) {
212             request.getSession().setAttribute(Constants.LOGIN_COOKIE, "true");
213         }
214 
215         String encryptedPassword = "";
216 
217         if (encrypt.booleanValue() &&
218                 (request.getAttribute("encrypt") == null)) {
219             if (log.isDebugEnabled()) {
220                 log.debug("Encrypting password for user '" + username + "'");
221             }
222 
223             encryptedPassword = StringUtil.encodePassword(password, algorithm);
224         } else {
225             encryptedPassword = password;
226         }
227 
228         if (redirectString == null) {
229             // signifies already correct protocol
230             if (log.isDebugEnabled()) {
231                 log.debug("Authenticating user '" + username + "'");
232             }
233 
234             String req =
235                 request.getContextPath() + "/" + authURL + "?j_username=" +
236                 username + "&j_password=" + encryptedPassword + "&j_uri=" +
237                 request.getParameter("j_uri");
238 
239             response.sendRedirect(response.encodeRedirectURL(req));
240         }
241     }
242 }