1 17 18 19 package org.apache.catalina.authenticator; 20 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.security.Principal ; 25 import java.util.Enumeration ; 26 import java.util.Iterator ; 27 import java.util.Locale ; 28 29 import javax.servlet.RequestDispatcher ; 30 import javax.servlet.http.Cookie ; 31 import javax.servlet.http.HttpServletResponse ; 32 33 import org.apache.catalina.Realm; 34 import org.apache.catalina.Session; 35 import org.apache.catalina.connector.Request; 36 import org.apache.catalina.connector.Response; 37 import org.apache.catalina.deploy.LoginConfig; 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.apache.coyote.ActionCode; 41 import org.apache.tomcat.util.buf.ByteChunk; 42 import org.apache.tomcat.util.buf.CharChunk; 43 import org.apache.tomcat.util.buf.MessageBytes; 44 import org.apache.tomcat.util.http.MimeHeaders; 45 46 47 55 56 public class FormAuthenticator 57 extends AuthenticatorBase { 58 59 private static Log log = LogFactory.getLog(FormAuthenticator.class); 60 61 63 64 67 protected static final String info = 68 "org.apache.catalina.authenticator.FormAuthenticator/1.0"; 69 70 75 protected String characterEncoding = null; 76 77 78 80 81 84 public String getInfo() { 85 86 return (info); 87 88 } 89 90 91 94 public String getCharacterEncoding() { 95 return characterEncoding; 96 } 97 98 99 102 public void setCharacterEncoding(String encoding) { 103 characterEncoding = encoding; 104 } 105 106 107 109 110 123 public boolean authenticate(Request request, 124 Response response, 125 LoginConfig config) 126 throws IOException { 127 128 Session session = null; 130 131 Principal principal = request.getUserPrincipal(); 133 String ssoId = (String ) request.getNote(Constants.REQ_SSOID_NOTE); 134 if (principal != null) { 135 if (log.isDebugEnabled()) 136 log.debug("Already authenticated '" + 137 principal.getName() + "'"); 138 if (ssoId != null) 140 associate(ssoId, request.getSessionInternal(true)); 141 return (true); 142 } 143 144 if (ssoId != null) { 146 if (log.isDebugEnabled()) 147 log.debug("SSO Id " + ssoId + " set; attempting " + 148 "reauthentication"); 149 if (reauthenticateFromSSO(ssoId, request)) 156 return true; 157 } 158 159 if (!cache) { 161 session = request.getSessionInternal(true); 162 if (log.isDebugEnabled()) 163 log.debug("Checking for reauthenticate in session " + session); 164 String username = 165 (String ) session.getNote(Constants.SESS_USERNAME_NOTE); 166 String password = 167 (String ) session.getNote(Constants.SESS_PASSWORD_NOTE); 168 if ((username != null) && (password != null)) { 169 if (log.isDebugEnabled()) 170 log.debug("Reauthenticating username '" + username + "'"); 171 principal = 172 context.getRealm().authenticate(username, password); 173 if (principal != null) { 174 session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); 175 if (!matchRequest(request)) { 176 register(request, response, principal, 177 Constants.FORM_METHOD, 178 username, password); 179 return (true); 180 } 181 } 182 if (log.isDebugEnabled()) 183 log.debug("Reauthentication failed, proceed normally"); 184 } 185 } 186 187 if (matchRequest(request)) { 190 session = request.getSessionInternal(true); 191 if (log.isDebugEnabled()) 192 log.debug("Restore request from session '" 193 + session.getIdInternal() 194 + "'"); 195 principal = (Principal ) 196 session.getNote(Constants.FORM_PRINCIPAL_NOTE); 197 register(request, response, principal, Constants.FORM_METHOD, 198 (String ) session.getNote(Constants.SESS_USERNAME_NOTE), 199 (String ) session.getNote(Constants.SESS_PASSWORD_NOTE)); 200 if (cache) { 203 session.removeNote(Constants.SESS_USERNAME_NOTE); 204 session.removeNote(Constants.SESS_PASSWORD_NOTE); 205 } 206 if (restoreRequest(request, session)) { 207 if (log.isDebugEnabled()) 208 log.debug("Proceed to restored request"); 209 return (true); 210 } else { 211 if (log.isDebugEnabled()) 212 log.debug("Restore of original request failed"); 213 response.sendError(HttpServletResponse.SC_BAD_REQUEST); 214 return (false); 215 } 216 } 217 218 MessageBytes uriMB = MessageBytes.newInstance(); 220 CharChunk uriCC = uriMB.getCharChunk(); 221 uriCC.setLimit(-1); 222 String contextPath = request.getContextPath(); 223 String requestURI = request.getDecodedRequestURI(); 224 response.setContext(request.getContext()); 225 226 boolean loginAction = 228 requestURI.startsWith(contextPath) && 229 requestURI.endsWith(Constants.FORM_ACTION); 230 231 if (!loginAction) { 233 session = request.getSessionInternal(true); 234 if (log.isDebugEnabled()) 235 log.debug("Save request in session '" + session.getIdInternal() + "'"); 236 try { 237 saveRequest(request, session); 238 } catch (IOException ioe) { 239 log.debug("Request body too big to save during authentication"); 240 response.sendError(HttpServletResponse.SC_FORBIDDEN, 241 sm.getString("authenticator.requestBodyTooBig")); 242 return (false); 243 } 244 forwardToLoginPage(request, response, config); 245 return (false); 246 } 247 248 Realm realm = context.getRealm(); 251 if (characterEncoding != null) { 252 request.setCharacterEncoding(characterEncoding); 253 } 254 String username = request.getParameter(Constants.FORM_USERNAME); 255 String password = request.getParameter(Constants.FORM_PASSWORD); 256 if (log.isDebugEnabled()) 257 log.debug("Authenticating username '" + username + "'"); 258 principal = realm.authenticate(username, password); 259 if (principal == null) { 260 forwardToErrorPage(request, response, config); 261 return (false); 262 } 263 264 if (log.isDebugEnabled()) 265 log.debug("Authentication of '" + username + "' was successful"); 266 267 if (session == null) 268 session = request.getSessionInternal(false); 269 if (session == null) { 270 if (containerLog.isDebugEnabled()) 271 containerLog.debug 272 ("User took so long to log on the session expired"); 273 response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT, 274 sm.getString("authenticator.sessionExpired")); 275 return (false); 276 } 277 278 session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); 280 281 session.setNote(Constants.SESS_USERNAME_NOTE, username); 283 session.setNote(Constants.SESS_PASSWORD_NOTE, password); 284 285 requestURI = savedRequestURL(session); 288 if (log.isDebugEnabled()) 289 log.debug("Redirecting to original '" + requestURI + "'"); 290 if (requestURI == null) 291 response.sendError(HttpServletResponse.SC_BAD_REQUEST, 292 sm.getString("authenticator.formlogin")); 293 else 294 response.sendRedirect(response.encodeRedirectURL(requestURI)); 295 return (false); 296 297 } 298 299 300 302 303 311 protected void forwardToLoginPage(Request request, Response response, LoginConfig config) { 312 RequestDispatcher disp = 313 context.getServletContext().getRequestDispatcher 314 (config.getLoginPage()); 315 try { 316 disp.forward(request.getRequest(), response.getResponse()); 317 response.finishResponse(); 318 } catch (Throwable t) { 319 log.warn("Unexpected error forwarding to login page", t); 320 } 321 } 322 323 324 332 protected void forwardToErrorPage(Request request, Response response, LoginConfig config) { 333 RequestDispatcher disp = 334 context.getServletContext().getRequestDispatcher 335 (config.getErrorPage()); 336 try { 337 disp.forward(request.getRequest(), response.getResponse()); 338 } catch (Throwable t) { 339 log.warn("Unexpected error forwarding to error page", t); 340 } 341 } 342 343 344 350 protected boolean matchRequest(Request request) { 351 352 Session session = request.getSessionInternal(false); 354 if (session == null) 355 return (false); 356 357 SavedRequest sreq = (SavedRequest) 359 session.getNote(Constants.FORM_REQUEST_NOTE); 360 if (sreq == null) 361 return (false); 362 363 if (session.getNote(Constants.FORM_PRINCIPAL_NOTE) == null) 365 return (false); 366 367 String requestURI = request.getRequestURI(); 369 if (requestURI == null) 370 return (false); 371 return (requestURI.equals(request.getRequestURI())); 372 373 } 374 375 376 385 protected boolean restoreRequest(Request request, Session session) 386 throws IOException { 387 388 SavedRequest saved = (SavedRequest) 390 session.getNote(Constants.FORM_REQUEST_NOTE); 391 session.removeNote(Constants.FORM_REQUEST_NOTE); 392 session.removeNote(Constants.FORM_PRINCIPAL_NOTE); 393 if (saved == null) 394 return (false); 395 396 request.clearCookies(); 398 Iterator cookies = saved.getCookies(); 399 while (cookies.hasNext()) { 400 request.addCookie((Cookie ) cookies.next()); 401 } 402 403 MimeHeaders rmh = request.getCoyoteRequest().getMimeHeaders(); 404 rmh.recycle(); 405 Iterator names = saved.getHeaderNames(); 406 while (names.hasNext()) { 407 String name = (String ) names.next(); 408 Iterator values = saved.getHeaderValues(name); 409 while (values.hasNext()) { 410 rmh.addValue(name).setString( (String )values.next() ); 411 } 412 } 413 414 request.clearLocales(); 415 Iterator locales = saved.getLocales(); 416 while (locales.hasNext()) { 417 request.addLocale((Locale ) locales.next()); 418 } 419 420 request.getCoyoteRequest().getParameters().recycle(); 421 422 if ("POST".equalsIgnoreCase(saved.getMethod())) { 423 ByteChunk body = saved.getBody(); 424 425 if (body != null) { 426 request.getCoyoteRequest().action 427 (ActionCode.ACTION_REQ_SET_BODY_REPLAY, body); 428 429 MessageBytes contentType = MessageBytes.newInstance(); 431 contentType.setString("application/x-www-form-urlencoded"); 432 request.getCoyoteRequest().setContentType(contentType); 433 } 434 } 435 request.getCoyoteRequest().method().setString(saved.getMethod()); 436 437 request.getCoyoteRequest().queryString().setString 438 (saved.getQueryString()); 439 440 request.getCoyoteRequest().requestURI().setString 441 (saved.getRequestURI()); 442 return (true); 443 444 } 445 446 447 454 protected void saveRequest(Request request, Session session) 455 throws IOException { 456 457 SavedRequest saved = new SavedRequest(); 459 Cookie cookies[] = request.getCookies(); 460 if (cookies != null) { 461 for (int i = 0; i < cookies.length; i++) 462 saved.addCookie(cookies[i]); 463 } 464 Enumeration names = request.getHeaderNames(); 465 while (names.hasMoreElements()) { 466 String name = (String ) names.nextElement(); 467 Enumeration values = request.getHeaders(name); 468 while (values.hasMoreElements()) { 469 String value = (String ) values.nextElement(); 470 saved.addHeader(name, value); 471 } 472 } 473 Enumeration locales = request.getLocales(); 474 while (locales.hasMoreElements()) { 475 Locale locale = (Locale ) locales.nextElement(); 476 saved.addLocale(locale); 477 } 478 479 if ("POST".equalsIgnoreCase(request.getMethod())) { 480 ByteChunk body = new ByteChunk(); 481 body.setLimit(request.getConnector().getMaxSavePostSize()); 482 483 byte[] buffer = new byte[4096]; 484 int bytesRead; 485 InputStream is = request.getInputStream(); 486 487 while ( (bytesRead = is.read(buffer) ) >= 0) { 488 body.append(buffer, 0, bytesRead); 489 } 490 saved.setBody(body); 491 } 492 493 saved.setMethod(request.getMethod()); 494 saved.setQueryString(request.getQueryString()); 495 saved.setRequestURI(request.getRequestURI()); 496 497 session.setNote(Constants.FORM_REQUEST_NOTE, saved); 499 500 } 501 502 503 509 protected String savedRequestURL(Session session) { 510 511 SavedRequest saved = 512 (SavedRequest) session.getNote(Constants.FORM_REQUEST_NOTE); 513 if (saved == null) 514 return (null); 515 StringBuffer sb = new StringBuffer (saved.getRequestURI()); 516 if (saved.getQueryString() != null) { 517 sb.append('?'); 518 sb.append(saved.getQueryString()); 519 } 520 return (sb.toString()); 521 522 } 523 524 525 } 526 | Popular Tags |