e.g. Calendar Search Help
You must enter a value before pressing Search
tomcat

Class: org.apache.catalina.authenticator.FormAuthenticator   ©

 OK to copy?
001 /*
002  * Copyright 1999,2004 The Apache Software Foundation.
003  * 
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  * 
008  *      http://www.apache.org/licenses/LICENSE-2.0
009  * 
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 
017 
018 package org.apache.catalina.authenticator;
019 
020 
021 import java.io.IOException;
022 import java.security.Principal;
023 import java.util.Enumeration;
024 import java.util.Iterator;
025 import java.util.Locale;
026 import java.util.Map;
027 
028 import javax.servlet.RequestDispatcher;
029 import javax.servlet.http.Cookie;
030 import javax.servlet.http.HttpServletResponse;
031 
032 import org.apache.catalina.Realm;
033 import org.apache.catalina.Session;
034 import org.apache.catalina.connector.Request;
035 import org.apache.catalina.connector.Response;
036 import org.apache.catalina.deploy.LoginConfig;
037 import org.apache.commons.logging.Log;
038 import org.apache.commons.logging.LogFactory;
039 import org.apache.tomcat.util.buf.CharChunk;
040 import org.apache.tomcat.util.buf.MessageBytes;
041 
042 
043 
044 /**
045  * An <b>Authenticator</b> and <b>Valve</b> implementation of FORM BASED
046  * Authentication, as described in the Servlet API Specification, Version 2.2.
047  *
048  * @author Craig R. McClanahan
049  * @author Remy Maucherat
050  * @version $Revision: 1.13 $ $Date: 2004/07/07 16:39:46 $
051  */
052 
053 public class FormAuthenticator
054     extends AuthenticatorBase {
055     private static Log log = LogFactory.getLog(FormAuthenticator.class);
056 
057 
058 
059     // ----------------------------------------------------- Instance Variables
060 
061 
062     /**
063      * Descriptive information about this implementation.
064      */
065     protected static final String info =
066         "org.apache.catalina.authenticator.FormAuthenticator/1.0";
067 
068 
069     // ------------------------------------------------------------- Properties
070 
071 
072     /**
073      * Return descriptive information about this Valve implementation.
074      */
075     public String getInfo() {
076 
077         return (info);
078 
079     }
080 
081 
082     // --------------------------------------------------------- Public Methods
083 
084 
085     /**
086      * Authenticate the user making this request, based on the specified
087      * login configuration.  Return <code>true</code> if any specified
088      * constraint has been satisfied, or <code>false</code> if we have
089      * created a response challenge already.
090      *
091      * @param request Request we are processing
092      * @param response Response we are creating
093      * @param config    Login configuration describing how authentication
094      *              should be performed
095      *
096      * @exception IOException if an input/output error occurs
097      */
098     public boolean authenticate(Request request,
099                                 Response response,
100                                 LoginConfig config)
101         throws IOException {
102 
103         // References to objects we will need later
104         Session session = null;
105 
106         // Have we already authenticated someone?
107         Principal principal = request.getUserPrincipal();
108         String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
109         if (principal != null) {
110             if (log.isDebugEnabled())
111                 log.debug("Already authenticated '" +
112                     principal.getName() + "'");
113             // Associate the session with any existing SSO session
114             if (ssoId != null)
115                 associate(ssoId, request.getSessionInternal(true));
116             return (true);
117         }
118 
119         // Is there an SSO session against which we can try to reauthenticate?
120         if (ssoId != null) {
121             if (log.isDebugEnabled())
122                 log.debug("SSO Id " + ssoId + " set; attempting " +
123                           "reauthentication");
124             // Try to reauthenticate using data cached by SSO.  If this fails,
125             // either the original SSO logon was of DIGEST or SSL (which
126             // we can't reauthenticate ourselves because there is no
127             // cached username and password), or the realm denied
128             // the user's reauthentication for some reason.
129             // In either case we have to prompt the user for a logon */
130             if (reauthenticateFromSSO(ssoId, request))
131                 return true;
132         }
133 
134         // Have we authenticated this user before but have caching disabled?
135         if (!cache) {
136             session = request.getSessionInternal(true);
137             if (log.isDebugEnabled())
138                 log.debug("Checking for reauthenticate in session " + session);
139             String username =
140                 (String) session.getNote(Constants.SESS_USERNAME_NOTE);
141             String password =
142                 (String) session.getNote(Constants.SESS_PASSWORD_NOTE);
143             if ((username != null) && (password != null)) {
144                 if (log.isDebugEnabled())
145                     log.debug("Reauthenticating username '" + username + "'");
146                 principal =
147                     context.getRealm().authenticate(username, password);
148                 if (principal != null) {
149                     session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
150                     if (!matchRequest(request)) {
151                         register(request, response, principal,
152                                  Constants.FORM_METHOD,
153                                  username, password);
154                         return (true);
155                     }
156                 }
157                 if (log.isDebugEnabled())
158                     log.debug("Reauthentication failed, proceed normally");
159             }
160         }
161 
162         // Is this the re-submit of the original request URI after successful
163         // authentication?  If so, forward the *original* request instead.
164         if (matchRequest(request)) {
165             session = request.getSessionInternal(true);
166             if (log.isDebugEnabled())
167                 log.debug("Restore request from session '" + session.getId() 
168                           + "'");
169             principal = (Principal)
170                 session.getNote(Constants.FORM_PRINCIPAL_NOTE);
171             register(request, response, principal, Constants.FORM_METHOD,
172                      (String) session.getNote(Constants.SESS_USERNAME_NOTE),
173                      (String) session.getNote(Constants.SESS_PASSWORD_NOTE));
174             if (restoreRequest(request, session)) {
175                 if (log.isDebugEnabled())
176                     log.debug("Proceed to restored request");
177                 return (true);
178             } else {
179                 if (log.isDebugEnabled())
180                     log.debug("Restore of original request failed");
181                 response.sendError(HttpServletResponse.SC_BAD_REQUEST);
182                 return (false);
183             }
184         }
185 
186         // Acquire references to objects we will need to evaluate
187         MessageBytes uriMB = MessageBytes.newInstance();
188         CharChunk uriCC = uriMB.getCharChunk();
189         uriCC.setLimit(-1);
190         String contextPath = request.getContextPath();
191         String requestURI = request.getDecodedRequestURI();
192         response.setContext(request.getContext());
193 
194         // Is this the action request from the login page?
195         boolean loginAction =
196             requestURI.startsWith(contextPath) &&
197             requestURI.endsWith(Constants.FORM_ACTION);
198 
199         // No -- Save this request and redirect to the form login page
200         if (!loginAction) {
201             session = request.getSessionInternal(true);
202             if (log.isDebugEnabled())
203                 log.debug("Save request in session '" + session.getId() + "'");
204             saveRequest(request, session);
205             RequestDispatcher disp =
206                 context.getServletContext().getRequestDispatcher
207                 (config.getLoginPage());
208             try {
209                 disp.forward(request.getRequest(), response.getResponse());
210                 response.finishResponse();
211             } catch (Throwable t) {
212                 log.warn("Unexpected error forwarding to login page", t);
213             }
214             return (false);
215         }
216 
217         // Yes -- Validate the specified credentials and redirect
218         // to the error page if they are not correct
219         Realm realm = context.getRealm();
220         String username = request.getParameter(Constants.FORM_USERNAME);
221         String password = request.getParameter(Constants.FORM_PASSWORD);
222         if (log.isDebugEnabled())
223             log.debug("Authenticating username '" + username + "'");
224         principal = realm.authenticate(username, password);
225         if (principal == null) {
Rate226             RequestDispatcher disp =
Rate227                 context.getServletContext().getRequestDispatcher
228                 (config.getErrorPage());
229             try {
230                 disp.forward(request.getRequest(), response.getResponse());
231             } catch (Throwable t) {
232                 log.warn("Unexpected error forwarding to error page", t);
233             }
234             return (false);
235         }
236 
237         if (log.isDebugEnabled())
238             log.debug("Authentication of '" + username + "' was successful");
239 
240         if (session == null)
241             session = request.getSessionInternal(false);
242         if (session == null) {
243             if (container.getLogger().isDebugEnabled())
244                 container.getLogger().debug("User took so long to log on the session expired");
245             response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT,
246                                sm.getString("authenticator.sessionExpired"));
247             return (false);
248         }
249 
250         // Save the authenticated Principal in our session
251         session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
252 
253         // If we are not caching, save the username and password as well
254         if (!cache) {
255             session.setNote(Constants.SESS_USERNAME_NOTE, username);
256             session.setNote(Constants.SESS_PASSWORD_NOTE, password);
257         }
258 
259         // Redirect the user to the original request URI (which will cause
260         // the original request to be restored)
261         requestURI = savedRequestURL(session);
262         if (log.isDebugEnabled())
263             log.debug("Redirecting to original '" + requestURI + "'");
264         if (requestURI == null)
265             response.sendError(HttpServletResponse.SC_BAD_REQUEST,
266                                sm.getString("authenticator.formlogin"));
267         else
268             response.sendRedirect(response.encodeRedirectURL(requestURI));
269         return (false);
270 
271     }
272 
273 
274     // ------------------------------------------------------ Protected Methods
275 
276 
277     /**
278      * Does this request match the saved one (so that it must be the redirect
279      * we signalled after successful authentication?
280      *
281      * @param request The request to be verified
282      */
283     protected boolean matchRequest(Request request) {
284 
285       // Has a session been created?
286       Session session = request.getSessionInternal(false);
287       if (session == null)
288           return (false);
289 
290       // Is there a saved request?
291       SavedRequest sreq = (SavedRequest)
292           session.getNote(Constants.FORM_REQUEST_NOTE);
293       if (sreq == null)
294           return (false);
295 
296       // Is there a saved principal?
297       if (session.getNote(Constants.FORM_PRINCIPAL_NOTE) == null)
298           return (false);
299 
300       // Does the request URI match?
301       String requestURI = request.getRequestURI();
302       if (requestURI == null)
303           return (false);
304       return (requestURI.equals(request.getRequestURI()));
305 
306     }
307 
308 
309     /**
310      * Restore the original request from information stored in our session.
311      * If the original request is no longer present (because the session
312      * timed out), return <code>false</code>; otherwise, return
313      * <code>true</code>.
314      *
315      * @param request The request to be restored
316      * @param session The session containing the saved information
317      */
318     protected boolean restoreRequest(Request request, Session session) {
319 
320         // Retrieve and remove the SavedRequest object from our session
321         SavedRequest saved = (SavedRequest)
322             session.getNote(Constants.FORM_REQUEST_NOTE);
323         session.removeNote(Constants.FORM_REQUEST_NOTE);
324         session.removeNote(Constants.FORM_PRINCIPAL_NOTE);
325         if (saved == null)
326             return (false);
327 
328         // Modify our current request to reflect the original one
329         request.clearCookies();
330         Iterator cookies = saved.getCookies();
331         while (cookies.hasNext()) {
332             request.addCookie((Cookie) cookies.next());
333         }
334         request.clearHeaders();
335         Iterator names = saved.getHeaderNames();
336         while (names.hasNext()) {
337             String name = (String) names.next();
338             Iterator values = saved.getHeaderValues(name);
339             while (values.hasNext()) {
340                 request.addHeader(name, (String) values.next());
341             }
342         }
343         request.clearLocales();
344         Iterator locales = saved.getLocales();
345         while (locales.hasNext()) {
346             request.addLocale((Locale) locales.next());
347         }
348         request.clearParameters();
349         if ("POST".equalsIgnoreCase(saved.getMethod())) {
350             Iterator paramNames = saved.getParameterNames();
351             while (paramNames.hasNext()) {
352                 String paramName = (String) paramNames.next();
353                 String paramValues[] =
354                     saved.getParameterValues(paramName);
355                 request.addParameter(paramName, paramValues);
356             }
357         }
358         request.setMethod(saved.getMethod());
359         request.setQueryString(saved.getQueryString());
360         request.setRequestURI(saved.getRequestURI());
361         return (true);
362 
363     }
364 
365 
366     /**
367      * Save the original request information into our session.
368      *
369      * @param request The request to be saved
370      * @param session The session to contain the saved information
371      */
372     private void saveRequest(Request request, Session session) {
373 
374         // Create and populate a SavedRequest object for this request
375         SavedRequest saved = new SavedRequest();
376         Cookie cookies[] = request.getCookies();
377         if (cookies != null) {
378             for (int i = 0; i < cookies.length; i++)
379                 saved.addCookie(cookies[i]);
380         }
381         Enumeration names = request.getHeaderNames();
382         while (names.hasMoreElements()) {
383             String name = (String) names.nextElement();
384             Enumeration values = request.getHeaders(name);
385             while (values.hasMoreElements()) {
386                 String value = (String) values.nextElement();
387                 saved.addHeader(name, value);
388             }
389         }
390         Enumeration locales = request.getLocales();
391         while (locales.hasMoreElements()) {
392             Locale locale = (Locale) locales.nextElement();
393             saved.addLocale(locale);
394         }
395         Map parameters = request.getParameterMap();
396         Iterator paramNames = parameters.keySet().iterator();
397         while (paramNames.hasNext()) {
398             String paramName = (String) paramNames.next();
399             String paramValues[] = (String[]) parameters.get(paramName);
400             saved.addParameter(paramName, paramValues);
401         }
402         saved.setMethod(request.getMethod());
403         saved.setQueryString(request.getQueryString());
404         saved.setRequestURI(request.getRequestURI());
405 
406         // Stash the SavedRequest in our session for later use
407         session.setNote(Constants.FORM_REQUEST_NOTE, saved);
408 
409     }
410 
411 
412     /**
413      * Return the request URI (with the corresponding query string, if any)
414      * from the saved request so that we can redirect to it.
415      *
416      * @param session Our current session
417      */
418     private String savedRequestURL(Session session) {
419 
420         SavedRequest saved =
421             (SavedRequest) session.getNote(Constants.FORM_REQUEST_NOTE);
422         if (saved == null)
423             return (null);
424         StringBuffer sb = new StringBuffer(saved.getRequestURI());
425         if (saved.getQueryString() != null) {
426             sb.append('?');
427             sb.append(saved.getQueryString());
428         }
429         return (sb.toString());
430 
431     }
432 
433 
434 }

            
All Examples in File:
Example
Line
Rating (found
useful by...)
226 0% of 0
227 0% of 0