KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > security > FormLoginServlet


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.server.security;
30
31 import com.caucho.log.Log;
32 import com.caucho.server.connection.CauchoResponse;
33 import com.caucho.server.webapp.Application;
34 import com.caucho.server.webapp.RequestDispatcherImpl;
35 import com.caucho.util.L10N;
36
37 import javax.servlet.GenericServlet JavaDoc;
38 import javax.servlet.RequestDispatcher JavaDoc;
39 import javax.servlet.ServletException JavaDoc;
40 import javax.servlet.ServletRequest JavaDoc;
41 import javax.servlet.ServletResponse JavaDoc;
42 import javax.servlet.http.HttpServletRequest JavaDoc;
43 import javax.servlet.http.HttpServletResponse JavaDoc;
44 import javax.servlet.http.HttpSession JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.security.Principal JavaDoc;
47 import java.util.logging.Level JavaDoc;
48 import java.util.logging.Logger JavaDoc;
49
50 public class FormLoginServlet extends GenericServlet JavaDoc {
51   private final Logger JavaDoc log = Log.open(FormLoginServlet.class);
52   static final L10N L = new L10N(FormLoginServlet.class);
53   
54   public void service(ServletRequest JavaDoc request, ServletResponse JavaDoc response)
55     throws ServletException JavaDoc, IOException JavaDoc
56   {
57     HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) request;
58     HttpServletResponse JavaDoc res = (HttpServletResponse JavaDoc) response;
59
60     Application app = (Application) getServletContext();
61     FormLogin login;
62
63     if (! (app.getLogin() instanceof FormLogin))
64       throw new ServletException JavaDoc(L.l("FormLoginServlet requires a form login auth-type configuration at `{0}'",
65                                      app.getLogin().getAuthType()));
66     login = (FormLogin) app.getLogin();
67
68     if (login == null)
69       throw new ServletException JavaDoc(L.l("j_security_check requires a login"));
70
71     String JavaDoc username = request.getParameter("j_username");
72     String JavaDoc password = request.getParameter("j_password");
73
74     ServletAuthenticator auth = login.getAuthenticator();
75
76     Principal JavaDoc user = auth.login(req, res, app, username, password);
77
78     if (log.isLoggable(Level.FINE))
79       log.fine("auth: " + user);
80
81     if (user == null) {
82       // A failure internally redirects to the error page (not redirect)
83
String JavaDoc errorPage = login.getFormErrorPage();
84       RequestDispatcherImpl disp;
85       disp = (RequestDispatcherImpl) app.getRequestDispatcher(errorPage);
86
87       // req.setAttribute("caucho.login", "login");
88
if (res instanceof CauchoResponse) {
89         ((CauchoResponse) res).killCache();
90         ((CauchoResponse) res).setNoCache(true);
91       }
92       else {
93         res.setDateHeader("Expires", 0);
94         res.setHeader("Cache-Control", "no-cache");
95       }
96       
97       disp.error(req, res);
98       return;
99     }
100     
101     HttpSession JavaDoc session = req.getSession();
102     
103     String JavaDoc uri = (String JavaDoc) session.getValue(FormLogin.LOGIN_SAVED_PATH);
104     String JavaDoc query = (String JavaDoc) session.getValue(FormLogin.LOGIN_SAVED_QUERY);
105
106     session.removeAttribute(FormLogin.LOGIN_SAVED_PATH);
107     session.removeAttribute(FormLogin.LOGIN_SAVED_QUERY);
108
109     if (log.isLoggable(Level.FINE)) {
110       log.fine("old path:" + uri + " query:" + query + " j_uri:" +
111                req.getParameter("j_uri"));
112     }
113
114     boolean formURIPriority = login.getFormURIPriority();
115
116     // The saved uri has priority.
117
if ((uri == null || formURIPriority) && req.getParameter("j_uri") != null)
118       uri = req.getParameter("j_uri");
119     else if (uri != null && query != null)
120       uri = uri + "?" + query;
121
122     if (uri == null)
123       throw new ServletException JavaDoc(L.l("No forwarding URI for form authentication. Either the login form must specify j_uri or the session must have a saved URI."));
124
125     if (uri.indexOf('\n') >= 0 || uri.indexOf('\r') >= 0)
126       throw new ServletException JavaDoc(L.l("Forwarding URI '{0}' is invalid.",
127                      uri));
128
129     String JavaDoc uriPwd = req.getRequestURI();
130     int p = uriPwd.indexOf("/j_security_check");
131     if (p >= 0)
132       uriPwd = uriPwd.substring(0, p + 1);
133     
134     if (uri.length() == 0) {
135     }
136     else if (uri.charAt(0) == '/')
137       uri = req.getContextPath() + uri;
138     else if (uri.indexOf(':') >= 0 &&
139              (uri.indexOf(':') < uri.indexOf('/') ||
140               uri.indexOf('/') < 0)) {
141     }
142     else {
143       uri = uriPwd + uri;
144     }
145
146     // The spec says that a successful login uses a redirect. Resin
147
// adds a configuration option to allow an internal forward
148
// if the URL is in the same directory.
149

150     // Logins to POST pages need to use an internal forward.
151
// Most GETs will want a redirect.
152
boolean useInternalForward = login.getInternalForward();
153     
154     if (useInternalForward &&
155         uri.startsWith(uriPwd) && uri.indexOf('/', uriPwd.length() + 1) < 0) {
156       Application newApp = (Application) app.getContext(uri);
157       String JavaDoc suffix = uri.substring(newApp.getContextPath().length());
158       
159       // force authorization of the page because the normal forward()
160
// bypasses authorization
161
RequestDispatcher JavaDoc disp = newApp.getLoginDispatcher(suffix);
162       if (disp != null) {
163     disp.forward(req, res);
164     return;
165       }
166     }
167       
168     res.sendRedirect(res.encodeRedirectURL(uri));
169   }
170 }
171
Popular Tags