KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > AuthenticationServlet


1 /* *****************************************************************************
2  * AuthenticationServlet.java
3 * ****************************************************************************/

4
5 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
6 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
7 * Use is subject to license terms. *
8 * J_LZ_COPYRIGHT_END *********************************************************/

9
10 import java.io.File JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.util.Enumeration JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.List JavaDoc;
15 import javax.servlet.ServletConfig JavaDoc;
16 import javax.servlet.ServletConfig JavaDoc.*;
17 import javax.servlet.ServletContext JavaDoc;
18 import javax.servlet.ServletException JavaDoc;
19 import javax.servlet.ServletOutputStream JavaDoc;
20 import javax.servlet.http.Cookie JavaDoc;
21 import javax.servlet.http.HttpServlet JavaDoc;
22 import javax.servlet.http.HttpServletRequest JavaDoc;
23 import javax.servlet.http.HttpServletResponse JavaDoc;
24 import javax.servlet.http.HttpSession JavaDoc;
25 import javax.xml.parsers.DocumentBuilder JavaDoc;
26 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
27 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
28 import javax.xml.parsers.ParserConfigurationException JavaDoc;
29 import org.apache.log4j.Logger;
30 import org.apache.log4j.PropertyConfigurator;
31 import org.jdom.Document;
32 import org.jdom.Element;
33 import org.jdom.JDOMException;
34 import org.jdom.input.SAXBuilder;
35 import org.jdom.output.XMLOutputter;
36
37 public class AuthenticationServlet extends HttpServlet JavaDoc
38 {
39     //----------------------------------------------------------------------
40
// Parameters
41
//----------------------------------------------------------------------
42
public static final String JavaDoc PARAM_REQUEST = "rt";
43     public static final String JavaDoc PARAM_USER = "usr";
44     public static final String JavaDoc PARAM_PASSWORD = "pwd";
45
46     //----------------------------------------------------------------------
47
// Request types
48
//----------------------------------------------------------------------
49
public static final String JavaDoc REQ_UNKNOWN = "unknown";
50     public static final String JavaDoc REQ_LOGIN = "login";
51     public static final String JavaDoc REQ_LOGINGUEST = "loginguest";
52     public static final String JavaDoc REQ_LOGOUT = "logout";
53     public static final String JavaDoc REQ_GETUSERNAME = "getusername";
54
55     //----------------------------------------------------------------------
56
// Status code types
57
//----------------------------------------------------------------------
58
public static final int STAT_OK = 0;
59     public static final int STAT_UNKNOWN = 1;
60     public static final int STAT_ERROR = 2;
61     public static final int STAT_INVALID = 3;
62     public static final int STAT_INVALID_SESSION = 4;
63     public static final int STAT_FORBIDDEN = 5;
64
65     //----------------------------------------------------------------------
66
// XML tag names
67
//----------------------------------------------------------------------
68
public static final String JavaDoc TAG_ROOT = "authentication";
69     public static final String JavaDoc TAG_STATUS = "status";
70     public static final String JavaDoc TAG_RESPONSE = "response";
71     public static final String JavaDoc TAG_USER = "user";
72     public static final String JavaDoc TAG_USERNAME = "username";
73
74
75     /** Static counter for guest name. */
76     private static int sGuestCounter = 0;
77     private static Object JavaDoc sLock = new Object JavaDoc();
78
79     /** Attribute session for username. */
80     static public String JavaDoc ATTR_USERNAME = "username";
81
82     /** Default authentication initialization file; this file is assumed to
83      * exist in the WEB-INF directory. */

84     private String JavaDoc DEFAULT_USERS_FILE = "lzusers.xml";
85
86     /** Map to store user information */
87     private HashMap JavaDoc mUserMap = new HashMap JavaDoc();
88
89     /** Flag to allow get guest interface. */
90     private boolean mAllowLoginGuest = true;
91
92     /** Logger */
93     private static Logger mLogger = Logger.getLogger(AuthenticationServlet.class);
94
95
96     /**
97      * Initialize servlet.
98      * @param config configuration file object
99      */

100     public void init(ServletConfig JavaDoc config)
101         throws ServletException JavaDoc
102     {
103         super.init (config);
104
105         log("Initializing AuthenticationServlet!");
106         ServletContext JavaDoc ctxt = config.getServletContext();
107
108         // Sanity check the servlet context version
109
if (ctxt.getMajorVersion() < 2 || ctxt.getMinorVersion() < 2)
110             throw new ServletException JavaDoc("must be at least servlet 2.2");
111
112         //------------------------------------------------------------
113
// Create internal name, password table
114
//------------------------------------------------------------
115
// Figure out where lps config directory is.
116
String JavaDoc ctxtPath = ctxt.getRealPath("/");
117         String JavaDoc delim =
118             (ctxtPath.lastIndexOf(File.separator) == ctxtPath.length()-1 ? "" : File.separator);
119         String JavaDoc lpsConfigDir = getInitParameter("lps.config.dir");
120         if (lpsConfigDir == null) {
121             lpsConfigDir = System.getProperty("lps.config.dir");
122             if (lpsConfigDir == null) {
123                 lpsConfigDir = "config";
124             }
125         }
126         String JavaDoc configDir = ctxtPath + delim + "WEB-INF"
127             + File.separator + "lps"
128             + File.separator + lpsConfigDir;
129
130
131         // Get connection parameter.
132
String JavaDoc usersFile = config.getInitParameter("LZ_USERS_FILE");
133         if (usersFile == null)
134             usersFile = DEFAULT_USERS_FILE;
135
136
137         String JavaDoc fullPath = getFullPath(configDir, usersFile);
138         try {
139             SAXBuilder builder = new SAXBuilder();
140             Document document = builder.build(new File JavaDoc(fullPath));
141             Element root = document.getRootElement();
142             List JavaDoc userList = root.getChildren(TAG_USER);
143                 
144             // Create user information map.
145
int userListLen = userList.size();
146             for (int i = 0; i < userListLen; i++) {
147                 Element userTag = (Element)userList.get(i);
148                 String JavaDoc name = userTag.getAttributeValue("name");
149                 String JavaDoc password = userTag.getAttributeValue("password");
150                 if (name!=null && password!=null)
151                     mUserMap.put(name, password);
152             }
153         } catch (JDOMException e) {
154             String JavaDoc info = "init exception: " + e.getMessage();
155             mLogger.debug(info);
156             throw new ServletException JavaDoc(info);
157         }
158
159         //------------------------------------------------------------
160
// Flag to allow guest naming interface.
161
//------------------------------------------------------------
162
String JavaDoc loginGuestStr = config.getInitParameter("ALLOW_GUEST_LOGIN");
163         if (loginGuestStr!=null)
164             mAllowLoginGuest = loginGuestStr.equals("true");
165     }
166
167
168     /**
169      * @param req @see HttpServletRequest
170      * @param res @see HttpServletResponse
171      */

172     public void doGet(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
173         throws ServletException JavaDoc, IOException JavaDoc
174     {
175         mLogger.debug("doGet(req, res)");
176
177         mLogger.debug("Request: uri " + req.getRequestURI());
178         mLogger.debug("Request: query string " + req.getQueryString());
179
180         Enumeration JavaDoc headers = req.getHeaderNames();
181         while(headers.hasMoreElements()) {
182             String JavaDoc h = (String JavaDoc)headers.nextElement();
183             mLogger.debug(" Header: " + h + " : " + req.getHeader(h));
184         }
185
186         Element root = new Element(TAG_ROOT);
187
188         // Request type
189
String JavaDoc rt = req.getParameter(PARAM_REQUEST);
190         boolean isOk = false;
191         if (rt == null)
192             doUnknown(req, root);
193         else if (rt.equals(REQ_LOGIN))
194             doLogin(req, res, root);
195         else if (rt.equals(REQ_LOGINGUEST))
196             if (mAllowLoginGuest)
197                 doLoginGuest(req, res, root);
198             else
199                 doForbidden(req, rt, root);
200         else if (rt.equals(REQ_LOGOUT))
201             doLogout(req, res, root);
202         else if (rt.equals(REQ_GETUSERNAME))
203             doGetUsername(req, root);
204         else
205             doUnknown(req, root);
206
207         res.setHeader ("Pragma", "no-cache");
208         res.setHeader ("Cache-Control", "no-cache");
209         String JavaDoc xml = new XMLOutputter().outputString(new Document(root));
210         ServletOutputStream JavaDoc out = res.getOutputStream();
211         out.println(xml);
212     }
213
214     /**
215      * Handle post request.
216      *
217      * @param req @see HttpServletRequest
218      * @param res @see HttpServletResponse
219      */

220     public void doPost(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
221         throws ServletException JavaDoc, IOException JavaDoc
222     {
223         mLogger.debug("doPost(req, res)");
224
225         doGet(req, res);
226     }
227
228
229     /**
230      * Login user and create session.
231      * @param req @see HttpServletRequest
232      * @param res @see HttpServletResponse
233      */

234     private void doLogin(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res,
235                          Element root)
236     {
237         mLogger.debug("doLogin(req, res, root)");
238
239         String JavaDoc username = req.getParameter(PARAM_USER);
240         if ( username != null && username.equals("guest") ) {
241             if (mAllowLoginGuest)
242                 doLoginGuest(req, res, root);
243             else
244                 doForbidden(req, REQ_LOGIN, root);
245             return;
246         }
247
248         int code = STAT_INVALID;
249         Element eRequest = getRequestElement(REQ_LOGIN);
250
251         Element eUsername = null;
252         String JavaDoc password = req.getParameter(PARAM_PASSWORD);
253         if ( username != null && ! username.equals("") &&
254              password != null && ! password.equals("") ) {
255
256             String JavaDoc checkPassword = (String JavaDoc)mUserMap.get(username);
257             if (checkPassword != null && !checkPassword.equals("")) {
258                 if (password.equals(checkPassword)) {
259                     HttpSession JavaDoc sess = req.getSession();
260                     sess.setAttribute(ATTR_USERNAME, username);
261                     eUsername = new Element(TAG_USERNAME)
262                         .addContent(username);
263                     code = STAT_OK;
264                 }
265             }
266         }
267
268         Element eStatus = getStatusElement(code);
269         eRequest.addContent(eStatus);
270         if (eUsername != null)
271             eRequest.addContent(eUsername);
272
273         root.addContent(eRequest);
274     }
275
276
277     /**
278      * Fetch a guest name.
279      * @param req @see HttpServletRequest
280      * @param res @see HttpServletResponse
281      */

282     private void doLoginGuest(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res,
283                               Element root)
284     {
285         mLogger.debug("doLoginGuest(req, res, root)");
286
287         String JavaDoc guest;
288         synchronized (sLock) {
289             guest = "guest" + sGuestCounter++;
290         }
291         HttpSession JavaDoc sess = req.getSession();
292         sess.setAttribute(ATTR_USERNAME, guest);
293
294         Element eRequest = getRequestElement(REQ_LOGINGUEST);
295         eRequest.addContent(getStatusElement(STAT_OK));
296         Element eUsername = new Element(TAG_USERNAME)
297             .addContent(guest);
298         eRequest.addContent(eUsername);
299         root.addContent(eRequest);
300     }
301
302
303     /**
304      * Remove session.
305      * @param req @see HttpServletRequest
306      * @param res @see HttpServletResponse
307      */

308     private void doLogout(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res,
309                           Element root)
310     {
311         mLogger.debug("doLogout(req, res, root)");
312
313         Element eRequest = getRequestElement(REQ_LOGOUT);
314         HttpSession JavaDoc sess = req.getSession();
315         if (sess.getAttribute(ATTR_USERNAME) != null) {
316             sess.invalidate();
317             eRequest.addContent(getStatusElement(STAT_OK));
318         } else {
319             eRequest.addContent(getStatusElement(STAT_INVALID_SESSION));
320         }
321
322         root.addContent(eRequest);
323     }
324
325
326     /**
327      * Get username of current session, if any.
328      * @param req @see HttpServletRequest
329      * @param res @see HttpServletResponse
330      */

331     private void doGetUsername(HttpServletRequest JavaDoc req , Element root)
332     {
333         mLogger.debug("doGetUsername(req, root)");
334
335         Element eRequest = getRequestElement(REQ_GETUSERNAME);
336         HttpSession JavaDoc sess = req.getSession();
337         // Session is only valid if we have a username
338
String JavaDoc username = (String JavaDoc)sess.getAttribute(ATTR_USERNAME);
339         if (username != null) {
340             eRequest.addContent(getStatusElement(STAT_OK));
341             Element eUsername = new Element(TAG_USERNAME)
342                 .addContent(username);
343             eRequest.addContent(eUsername);
344         } else {
345             eRequest.addContent(getStatusElement(STAT_INVALID_SESSION));
346         }
347
348         root.addContent(eRequest);
349     }
350
351
352     /**
353      * Return unknown response.
354      * @param req @see HttpServletRequest
355      * @param res @see HttpServletResponse
356      */

357     private void doUnknown(HttpServletRequest JavaDoc req, Element root)
358     {
359         mLogger.debug("doUnknown(req, root)");
360
361         Element eRequest = getRequestElement(REQ_UNKNOWN);
362         eRequest.addContent(getStatusElement(STAT_UNKNOWN));
363         root.addContent(eRequest);
364     }
365
366
367     /**
368      * Return forbidden response.
369      * @param req @see HttpServletRequest
370      * @param res @see HttpServletResponse
371      */

372     private void doForbidden(HttpServletRequest JavaDoc req, String JavaDoc rt, Element root)
373     {
374         mLogger.debug("doForbidden(req, root)");
375         Element eRequest = getRequestElement(rt);
376         eRequest.addContent(getStatusElement(STAT_FORBIDDEN));
377         root.addContent(eRequest);
378     }
379
380
381     /**
382      * Get a status element with a particular message attached.
383      * @param code code of status
384      * @param message status message
385      * @return an element with status information
386      */

387     private Element getStatusElement(int code, String JavaDoc msg)
388     {
389         mLogger.debug("getStatusElement(code=" + code + ", msg=" + msg + ")");
390
391         return new Element(TAG_STATUS)
392             .setAttribute("code", Integer.toString(code))
393             .setAttribute("msg", msg);
394     }
395
396     /**
397      * Get a status element.
398      * @param code code of status
399      * @return an element with status information
400      */

401     private Element getStatusElement(int code)
402     {
403         mLogger.debug("getStatusElement(code=" + code + ")");
404
405         return getStatusElement(code, getStatusCodeMessage(code));
406     }
407
408     /**
409      * Get a request element.
410      * @param type type of request
411      * @return an element with request information
412      */

413     private Element getRequestElement(String JavaDoc type)
414     {
415         mLogger.debug("getRequestElement(type=" + type + ")");
416
417         return new Element(TAG_RESPONSE)
418             .setAttribute("type", type);
419     }
420
421     /**
422      * Get status code of message.
423      * @param code integer code
424      * @return string representation of code
425      */

426     private String JavaDoc getStatusCodeMessage(int code)
427     {
428         mLogger.debug("getStatusCodeMessage(code=" + code + ")");
429
430         if (code == STAT_INVALID)
431             return "invalid";
432         if (code == STAT_ERROR)
433             return "error";
434         if (code == STAT_OK)
435             return "ok";
436         if (code == STAT_INVALID_SESSION)
437             return "invalid session";
438         if (code == STAT_FORBIDDEN)
439             return "forbidden";
440
441         return "unknown"; // STAT_UNKNOWN
442
}
443
444
445     /**
446      * Create a full path based by appending file to dir. File has to be of
447      * relative path or null is returned.
448      * @param dir directory name
449      * @param file file name
450      * @return string concatenated with dir and file or null if file is of
451      * absolute path
452      */

453     static public String JavaDoc getFullPath(String JavaDoc dir, String JavaDoc file)
454     {
455         mLogger.debug("getFullPath(dir=" + dir + ", file=" + file + ")");
456
457         final String JavaDoc fileSeparator = System.getProperty("file.separator");
458
459         String JavaDoc fullPath = "";
460         if (dir != null && dir.length() != 0) {
461             fullPath = dir;
462             boolean dirHasLastSeparator =
463                 dir.lastIndexOf(fileSeparator) == dir.length()-1;
464             if (! dirHasLastSeparator)
465                 fullPath += fileSeparator;
466         }
467         fullPath += file;
468
469         return fullPath;
470     }
471
472     /**
473      * Replace real path forward slash characters to back-slash for Windows.
474      * This is to get around a WebSphere problem where calling getRealPath()
475      * returns path with mixed file separators.
476      * @param ctxt servlet context
477      * @param path virtual webapp path to resolve into a real path
478      * @return the real path, or null if the translation cannot be performed
479      */

480     public String JavaDoc getRealPath(ServletContext JavaDoc ctxt, String JavaDoc path)
481     {
482         String JavaDoc realPath = ctxt.getRealPath(path);
483         if ( realPath != null && File.separatorChar == '\\' )
484             realPath = realPath.replace('/', '\\');
485         return realPath;
486     }
487 }
488
Popular Tags