1 16 package org.jboss.web.tomcat.security; 17 18 import java.io.IOException ; 19 import java.security.Principal ; 20 import java.util.Enumeration ; 21 import java.util.Iterator ; 22 import java.util.Locale ; 23 import java.util.Map ; 24 25 import javax.servlet.RequestDispatcher ; 26 import javax.servlet.http.Cookie ; 27 import javax.servlet.http.HttpServletResponse ; 28 29 import org.apache.catalina.Realm; 30 import org.apache.catalina.Session; 31 import org.apache.catalina.authenticator.AuthenticatorBase; 32 import org.apache.catalina.authenticator.Constants; 33 import org.apache.catalina.authenticator.SavedRequest; 34 import org.apache.catalina.connector.Request; 35 import org.apache.catalina.connector.Response; 36 import org.apache.catalina.deploy.LoginConfig; 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import org.apache.tomcat.util.buf.CharChunk; 40 import org.apache.tomcat.util.buf.MessageBytes; 41 42 43 54 55 public class FormAuthenticator 56 extends AuthenticatorBase { 57 private static Log log = LogFactory.getLog(FormAuthenticator.class); 58 59 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 '" + session.getId() 193 + "'"); 194 principal = (Principal ) 195 session.getNote(Constants.FORM_PRINCIPAL_NOTE); 196 register(request, response, principal, Constants.FORM_METHOD, 197 (String ) session.getNote(Constants.SESS_USERNAME_NOTE), 198 (String ) session.getNote(Constants.SESS_PASSWORD_NOTE)); 199 if (cache) { 202 session.removeNote(Constants.SESS_USERNAME_NOTE); 203 session.removeNote(Constants.SESS_PASSWORD_NOTE); 204 } 205 if (restoreRequest(request, session)) { 206 if (log.isDebugEnabled()) 207 log.debug("Proceed to restored request"); 208 return (true); 209 } else { 210 if (log.isDebugEnabled()) 211 log.debug("Restore of original request failed"); 212 response.sendError(HttpServletResponse.SC_BAD_REQUEST); 213 return (false); 214 } 215 } 216 217 MessageBytes uriMB = MessageBytes.newInstance(); 219 CharChunk uriCC = uriMB.getCharChunk(); 220 uriCC.setLimit(-1); 221 String contextPath = request.getContextPath(); 222 String requestURI = request.getDecodedRequestURI(); 223 response.setContext(request.getContext()); 224 225 boolean loginAction = 227 requestURI.startsWith(contextPath) && 228 requestURI.endsWith(Constants.FORM_ACTION); 229 230 if (!loginAction) { 232 session = request.getSessionInternal(true); 233 if (log.isDebugEnabled()) 234 log.debug("Save request in session '" + session.getId() + "'"); 235 saveRequest(request, session); 236 forwardToLoginPage(request, response, config); 237 return (false); 238 } 239 240 Realm realm = context.getRealm(); 243 if (characterEncoding != null) { 244 request.setCharacterEncoding(characterEncoding); 245 } 246 String username = request.getParameter(Constants.FORM_USERNAME); 247 String password = request.getParameter(Constants.FORM_PASSWORD); 248 if (log.isDebugEnabled()) 249 log.debug("Authenticating username '" + username + "'"); 250 principal = realm.authenticate(username, password); 251 if (principal == null) { 252 forwardToErrorPage(request, response, config); 253 return (false); 254 } 255 256 if (log.isDebugEnabled()) 257 log.debug("Authentication of '" + username + "' was successful"); 258 259 if (session == null) 260 session = request.getSessionInternal(false); 261 if (session == null) { 262 if (containerLog.isDebugEnabled()) 263 containerLog.debug("User took so long to log on the session expired"); 264 response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT, 265 sm.getString("authenticator.sessionExpired")); 266 return (false); 267 } 268 269 session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); 271 272 session.setNote(Constants.SESS_USERNAME_NOTE, username); 274 session.setNote(Constants.SESS_PASSWORD_NOTE, password); 275 276 requestURI = savedRequestURL(session); 279 if (log.isDebugEnabled()) 280 log.debug("Redirecting to original '" + requestURI + "'"); 281 if (requestURI == null) 282 response.sendError(HttpServletResponse.SC_BAD_REQUEST, 283 sm.getString("authenticator.formlogin")); 284 else 285 response.sendRedirect(response.encodeRedirectURL(requestURI)); 286 return (false); 287 288 } 289 290 292 293 protected void forwardToErrorPage(Request request, Response response, LoginConfig config) 294 { 295 RequestDispatcher disp = 296 context.getServletContext().getRequestDispatcher 297 (config.getErrorPage()); 298 try { 299 disp.forward(request.getRequest(), response.getResponse()); 300 } catch (Throwable t) { 301 log.warn("Unexpected error forwarding to error page", t); 302 } 303 } 304 305 protected void forwardToLoginPage(Request request, Response response, LoginConfig config) 306 { 307 RequestDispatcher disp = 308 context.getServletContext().getRequestDispatcher 309 (config.getLoginPage()); 310 try { 311 disp.forward(request.getRequest(), response.getResponse()); 312 response.finishResponse(); 313 } catch (Throwable t) { 314 log.warn("Unexpected error forwarding to login page", t); 315 } 316 } 317 318 324 protected boolean matchRequest(Request request) { 325 326 Session session = request.getSessionInternal(false); 328 if (session == null) 329 return (false); 330 331 SavedRequest sreq = (SavedRequest) 333 session.getNote(Constants.FORM_REQUEST_NOTE); 334 if (sreq == null) 335 return (false); 336 337 if (session.getNote(Constants.FORM_PRINCIPAL_NOTE) == null) 339 return (false); 340 341 String requestURI = request.getRequestURI(); 343 if (requestURI == null) 344 return (false); 345 return (requestURI.equals(sreq.getRequestURI())); 346 347 } 348 349 350 359 protected boolean restoreRequest(Request request, Session session) { 360 361 SavedRequest saved = (SavedRequest) 363 session.getNote(Constants.FORM_REQUEST_NOTE); 364 session.removeNote(Constants.FORM_REQUEST_NOTE); 365 session.removeNote(Constants.FORM_PRINCIPAL_NOTE); 366 if (saved == null) 367 return (false); 368 369 request.clearCookies(); 371 Iterator cookies = saved.getCookies(); 372 while (cookies.hasNext()) { 373 request.addCookie((Cookie ) cookies.next()); 374 } 375 request.clearHeaders(); 376 Iterator names = saved.getHeaderNames(); 377 while (names.hasNext()) { 378 String name = (String ) names.next(); 379 Iterator values = saved.getHeaderValues(name); 380 while (values.hasNext()) { 381 request.addHeader(name, (String ) values.next()); 382 } 383 } 384 request.clearLocales(); 385 Iterator locales = saved.getLocales(); 386 while (locales.hasNext()) { 387 request.addLocale((Locale ) locales.next()); 388 } 389 request.clearParameters(); 390 if ("POST".equalsIgnoreCase(saved.getMethod())) { 391 Iterator paramNames = saved.getParameterNames(); 392 while (paramNames.hasNext()) { 393 String paramName = (String ) paramNames.next(); 394 String paramValues[] = 395 saved.getParameterValues(paramName); 396 request.addParameter(paramName, paramValues); 397 } 398 } 399 request.setMethod(saved.getMethod()); 400 request.setQueryString(saved.getQueryString()); 401 request.setRequestURI(saved.getRequestURI()); 402 return (true); 403 404 } 405 406 407 413 private void saveRequest(Request request, Session session) { 414 415 SavedRequest saved = new SavedRequest(); 417 Cookie cookies[] = request.getCookies(); 418 if (cookies != null) { 419 for (int i = 0; i < cookies.length; i++) 420 saved.addCookie(cookies[i]); 421 } 422 Enumeration names = request.getHeaderNames(); 423 while (names.hasMoreElements()) { 424 String name = (String ) names.nextElement(); 425 Enumeration values = request.getHeaders(name); 426 while (values.hasMoreElements()) { 427 String value = (String ) values.nextElement(); 428 saved.addHeader(name, value); 429 } 430 } 431 Enumeration locales = request.getLocales(); 432 while (locales.hasMoreElements()) { 433 Locale locale = (Locale ) locales.nextElement(); 434 saved.addLocale(locale); 435 } 436 Map parameters = request.getParameterMap(); 437 Iterator paramNames = parameters.keySet().iterator(); 438 while (paramNames.hasNext()) { 439 String paramName = (String ) paramNames.next(); 440 String paramValues[] = (String []) parameters.get(paramName); 441 saved.addParameter(paramName, paramValues); 442 } 443 saved.setMethod(request.getMethod()); 444 saved.setQueryString(request.getQueryString()); 445 saved.setRequestURI(request.getRequestURI()); 446 447 session.setNote(Constants.FORM_REQUEST_NOTE, saved); 449 450 } 451 452 453 459 private String savedRequestURL(Session session) { 460 461 SavedRequest saved = 462 (SavedRequest) session.getNote(Constants.FORM_REQUEST_NOTE); 463 if (saved == null) 464 return (null); 465 StringBuffer sb = new StringBuffer (saved.getRequestURI()); 466 if (saved.getQueryString() != null) { 467 sb.append('?'); 468 sb.append(saved.getQueryString()); 469 } 470 return (sb.toString()); 471 472 } 473 474 475 } 476 | Popular Tags |