1 28 29 package com.caucho.server.security; 30 31 import com.caucho.config.types.Period; 32 import com.caucho.log.Log; 33 import com.caucho.server.connection.CauchoRequest; 34 import com.caucho.server.dispatch.ServletConfigException; 35 import com.caucho.server.session.SessionManager; 36 import com.caucho.server.webapp.Application; 37 import com.caucho.util.CharBuffer; 38 import com.caucho.util.L10N; 39 40 import javax.annotation.PostConstruct; 41 import javax.naming.Context ; 42 import javax.naming.InitialContext ; 43 import javax.servlet.ServletContext ; 44 import javax.servlet.ServletException ; 45 import javax.servlet.http.Cookie ; 46 import javax.servlet.http.HttpServletRequest ; 47 import javax.servlet.http.HttpServletResponse ; 48 import javax.sql.DataSource ; 49 import java.security.Principal ; 50 import java.sql.Connection ; 51 import java.sql.PreparedStatement ; 52 import java.sql.ResultSet ; 53 import java.sql.SQLException ; 54 import java.util.logging.Level ; 55 import java.util.logging.Logger ; 56 57 70 71 public class JdbcAuthenticator extends AbstractAuthenticator { 72 private static final Logger log = Log.open(JdbcAuthenticator.class); 73 private static final L10N L = new L10N(JdbcAuthenticator.class); 74 75 private DataSource _dataSource; 76 77 private String _passwordQuery = "SELECT password FROM LOGIN WHERE username=?"; 78 79 private String _cookieUpdate = "UPDATE LOGIN SET cookie=? WHERE username=?"; 80 81 private String _cookieQuery = "SELECT username FROM LOGIN where cookie=?"; 82 private boolean _cookieLogout; 83 84 private String _roleQuery; 85 86 protected boolean _useCookie; 87 protected int _cookieVersion = -1; 88 protected String _cookieDomain; 89 protected long _cookieMaxAge = 365L * 24L * 3600L * 1000L; 90 91 private CharBuffer _cb = new CharBuffer(); 92 93 96 public DataSource getDataSource() 97 { 98 return _dataSource; 99 } 100 101 104 public void setDataSource(DataSource dataSource) 105 { 106 _dataSource = dataSource; 107 } 108 109 117 public String getPasswordQuery() 118 { 119 return _passwordQuery; 120 } 121 122 125 public void setPasswordQuery(String query) 126 { 127 _passwordQuery = query; 128 } 129 130 133 public String getCookieAuthQuery() 134 { 135 return _cookieQuery; 136 } 137 138 141 public void setCookieAuthQuery(String query) 142 { 143 _cookieQuery = query; 144 } 145 146 149 public String getCookieAuthUpdate() 150 { 151 return _cookieUpdate; 152 } 153 154 157 public void setCookieAuthUpdate(String query) 158 { 159 _cookieUpdate = query; 160 } 161 162 165 public void setCookieLogout(boolean cookieLogout) 166 { 167 _cookieLogout = cookieLogout; 168 } 169 170 173 public String getRoleQuery() 174 { 175 return _roleQuery; 176 } 177 178 181 public void setRoleQuery(String query) 182 { 183 _roleQuery = query; 184 } 185 186 189 public boolean getUseCookie() 190 { 191 return _useCookie; 192 } 193 194 197 public void setUseCookie(boolean useCookie) 198 { 199 _useCookie = useCookie; 200 } 201 202 205 public int getCookieVersion() 206 { 207 return _cookieVersion; 208 } 209 210 213 public void setCookieVersion(int version) 214 { 215 _cookieVersion = version; 216 } 217 218 221 public String getCookieDomain() 222 { 223 return _cookieDomain; 224 } 225 226 229 public void setCookieDomain(String cookieDomain) 230 { 231 _cookieDomain = cookieDomain; 232 } 233 234 237 public long getCookieMaxAge() 238 { 239 return _cookieMaxAge; 240 } 241 242 245 public void setCookieMaxAge(Period cookieMaxAge) 246 { 247 _cookieMaxAge = cookieMaxAge.getPeriod(); 248 } 249 250 253 @PostConstruct 254 public void init() 255 throws ServletException 256 { 257 super.init(); 258 259 if (_dataSource == null) { 260 try { 261 Context ic = new InitialContext (); 262 263 _dataSource = (DataSource ) ic.lookup("java:comp/env/jdbc/db-pool"); 264 } catch (Exception e) { 265 log.log(Level.FINE, e.toString(), e); 266 } 267 268 if (_dataSource == null) 269 throw new ServletConfigException(L.l("Unknown database pool jdbc/db-pool.")); 270 } 271 272 int i = _passwordQuery.indexOf('?'); 273 if (i < 0) 274 throw new ServletConfigException(L.l("`{0}' expects a parameter", 275 "password-query")); 276 277 if (_cookieQuery != null) { 278 i = _cookieQuery.indexOf('?'); 279 if (i < 0) 280 throw new ServletConfigException(L.l("`{0}' expects a parameter", 281 "cookie-auth-query")); 282 } 283 284 if (_cookieUpdate != null) { 285 i = _cookieUpdate.indexOf('?'); 286 if (i < 0) 287 throw new ServletConfigException(L.l("`{0}' expects two parameters", 288 "cookie-auth-update")); 289 int j = _cookieUpdate.indexOf('?', i + 1); 290 if (j < 0) 291 throw new ServletConfigException(L.l("`{0}' expects two parameters", 292 "cookie-auth-update")); 293 } 294 295 if ((_cookieUpdate != null) && (_cookieQuery == null)) 296 throw new ServletConfigException(L.l("<{0}> expects `{1}'", 297 "cookie-auth-update", "cookie-query")); 298 299 if (_roleQuery != null) { 300 i = _roleQuery.indexOf('?'); 301 if (i < 0) 302 throw new ServletConfigException(L.l("`{0}' expects a parameter", 303 "role-query")); 304 } 305 } 306 307 315 public Principal loginImpl(HttpServletRequest request, 316 HttpServletResponse response, 317 ServletContext application, 318 String username, String password) 319 throws ServletException 320 { 321 Principal user = loginImpl(username, password); 322 323 if (_cookieQuery == null || user == null) 324 return user; 325 326 String cookieAuth = (String ) request.getAttribute("j_use_cookie_auth"); 327 if (cookieAuth == null) 328 cookieAuth = (String ) request.getParameter("j_use_cookie_auth"); 329 330 if ("true".equals(cookieAuth) || "on".equals(cookieAuth) || 331 _useCookie && cookieAuth == null) 332 addAuthCookie(request, response, application, user); 333 334 return user; 335 } 336 337 340 protected void addAuthCookie(HttpServletRequest request, 341 HttpServletResponse response, 342 ServletContext application, 343 Principal user) 344 345 { 346 Application app = (Application) application; 347 SessionManager sm = app.getSessionManager(); 348 String id; 349 350 id = sm.createSessionId(request); 351 352 if (updateCookie(user, id)) { 353 Cookie cookie = new Cookie ("resinauthid", id); 354 cookie.setPath("/"); 355 356 if (getCookieVersion() >= 0) 357 cookie.setVersion(getCookieVersion()); 358 else 359 cookie.setVersion(sm.getCookieVersion()); 360 361 if (_cookieDomain != null) 362 cookie.setDomain(_cookieDomain); 363 else if (getCookieDomain() != null) 364 cookie.setDomain(getCookieDomain()); 365 else 366 cookie.setDomain(sm.getCookieDomain()); 367 368 if (_cookieMaxAge > 0) 369 cookie.setMaxAge((int) (_cookieMaxAge / 1000L)); 370 371 response.addCookie(cookie); 372 } 373 } 374 375 383 public Principal loginImpl(String username, String password) 384 throws ServletException 385 { 386 Connection conn = null; 387 PreparedStatement stmt = null; 388 ResultSet rs = null; 389 390 try { 391 conn = _dataSource.getConnection(); 392 stmt = conn.prepareStatement(_passwordQuery); 393 394 stmt.setString(1, username); 395 396 rs = stmt.executeQuery(); 397 if (! rs.next()) { 398 if (log.isLoggable(Level.FINE)) 399 log.fine("no such user:" + username); 400 401 return null; 402 } 403 404 String dbPassword = rs.getString(1); 405 406 if (dbPassword != null && dbPassword.equals(password)) { 407 return new CachingPrincipal(username); 408 } 409 else { 410 if (log.isLoggable(Level.FINE)) 411 log.fine("mismatched password:" + username); 412 413 return null; 414 } 415 } catch (Exception e) { 416 e.printStackTrace(); 417 throw new ServletException (e); 418 } finally { 419 try { 420 if (rs != null) 421 rs.close(); 422 } catch (SQLException e) { 423 } 424 try { 425 if (stmt != null) 426 stmt.close(); 427 } catch (SQLException e) { 428 } 429 try { 430 if (conn != null) 431 conn.close(); 432 } catch (SQLException e) { 433 } 434 } 435 } 436 437 441 protected String getDigestPassword(HttpServletRequest request, 442 HttpServletResponse response, 443 ServletContext application, 444 String username, String realm) 445 throws ServletException 446 { 447 Connection conn = null; 448 PreparedStatement stmt = null; 449 ResultSet rs = null; 450 451 try { 452 conn = _dataSource.getConnection(); 453 stmt = conn.prepareStatement(_passwordQuery); 454 455 stmt.setString(1, username); 456 457 rs = stmt.executeQuery(); 458 if (! rs.next()) { 459 if (log.isLoggable(Level.FINE)) 460 log.fine("no such user:" + username); 461 462 return null; 463 } 464 465 String dbPassword = rs.getString(1); 466 467 return dbPassword; 468 } catch (Exception e) { 469 throw new ServletException (e); 470 } finally { 471 try { 472 if (rs != null) 473 rs.close(); 474 } catch (SQLException e) { 475 } 476 try { 477 if (stmt != null) 478 stmt.close(); 479 } catch (SQLException e) { 480 } 481 try { 482 if (conn != null) 483 conn.close(); 484 } catch (SQLException e) { 485 } 486 } 487 } 488 489 protected Principal getUserPrincipalImpl(HttpServletRequest request, 490 ServletContext application) 491 throws ServletException 492 { 493 if (_cookieQuery == null) 494 return null; 495 496 Cookie cookie = null; 497 498 if (request instanceof CauchoRequest) 499 cookie = ((CauchoRequest) request).getCookie("resinauthid"); 500 else { 501 Cookie []cookies = request.getCookies(); 502 for (int i = 0; cookies != null && i < cookies.length; i++) { 503 if (cookies[i].getName().equals("resinauthid")) { 504 cookie = cookies[i]; 505 break; 506 } 507 } 508 } 509 510 if (cookie == null) 511 return null; 512 513 return authenticateCookie(cookie.getValue()); 514 } 515 516 523 public Principal authenticateCookie(String cookieValue) 524 throws ServletException 525 { 526 if (_cookieQuery == null) 527 return null; 528 529 Connection conn = null; 530 PreparedStatement stmt = null; 531 ResultSet rs = null; 532 533 try { 534 conn = _dataSource.getConnection(); 535 stmt = conn.prepareStatement(_cookieQuery); 536 stmt.setString(1, cookieValue); 537 538 rs = stmt.executeQuery(); 539 if (! rs.next()) 540 return null; 541 542 String user = rs.getString(1); 543 544 if (user != null) 545 return new CachingPrincipal(user); 546 else 547 return null; 548 } catch (Exception e) { 549 throw new ServletException (e); 550 } finally { 551 try { 552 if (rs != null) 553 rs.close(); 554 } catch (SQLException e) { 555 } 556 try { 557 if (stmt != null) 558 stmt.close(); 559 } catch (SQLException e) { 560 } 561 try { 562 if (conn != null) 563 conn.close(); 564 } catch (SQLException e) { 565 } 566 } 567 } 568 569 577 public boolean updateCookie(Principal user, String cookieValue) 578 { 579 if (_cookieUpdate == null || user == null || cookieValue == null) 580 return true; 581 582 Connection conn = null; 583 PreparedStatement stmt = null; 584 585 try { 586 conn = _dataSource.getConnection(); 587 stmt = conn.prepareStatement(_cookieUpdate); 588 stmt.setString(1, cookieValue); 589 stmt.setString(2, user.getName()); 590 591 stmt.executeUpdate(); 592 } catch (Exception e) { 593 log.log(Level.FINE, e.toString(), e); 594 } finally { 595 try { 596 if (stmt != null) 597 stmt.close(); 598 } catch (SQLException e) { 599 } 600 try { 601 if (conn != null) 602 conn.close(); 603 } catch (SQLException e) { 604 } 605 } 606 607 return true; 608 } 609 610 public boolean isUserInRole(HttpServletRequest request, 611 HttpServletResponse response, 612 ServletContext application, 613 Principal principal, String role) 614 { 615 if (_roleQuery == null) 616 return principal != null && "user".equals(role); 617 else if (principal == null || role == null) 618 return false; 619 620 CachingPrincipal cachingPrincipal = null; 621 622 if (principal instanceof CachingPrincipal) { 623 cachingPrincipal = (CachingPrincipal) principal; 624 625 Boolean isInRole = cachingPrincipal.isInRole(role); 626 627 if (isInRole != null) 628 return isInRole.equals(Boolean.TRUE); 629 } 630 631 Connection conn = null; 632 PreparedStatement stmt = null; 633 ResultSet rs = null; 634 635 try { 636 conn = _dataSource.getConnection(); 637 stmt = conn.prepareStatement(_roleQuery); 638 stmt.setString(1, principal.getName()); 639 640 boolean inRole = false; 641 642 rs = stmt.executeQuery(); 643 while (rs.next()) { 644 String dbRole = rs.getString(1); 645 646 if (cachingPrincipal != null) 647 cachingPrincipal.addRole(dbRole); 648 649 if (role.equals(dbRole)) 650 inRole = true; 651 } 652 653 return inRole; 654 } catch (Exception e) { 655 log.log(Level.FINE, e.toString(), e); 656 657 return false; 658 } finally { 659 try { 660 if (rs != null) 661 rs.close(); 662 } catch (SQLException e) { 663 } 664 try { 665 if (stmt != null) 666 stmt.close(); 667 } catch (SQLException e) { 668 } 669 try { 670 if (conn != null) 671 conn.close(); 672 } catch (SQLException e) { 673 } 674 } 675 } 676 677 682 public void logout(HttpServletRequest request, 683 HttpServletResponse response, 684 ServletContext application, 685 Principal user) 686 throws ServletException 687 { 688 super.logout(request, response, application, user); 689 690 if (_cookieLogout) 692 updateCookie(user, ""); 693 } 694 } 695 | Popular Tags |