1 7 package org.jboss.web.tomcat.tc5.sso; 8 9 10 import org.jboss.web.tomcat.tc5.Tomcat5; 11 12 import java.io.IOException ; 13 import java.security.Principal ; 14 15 import javax.servlet.ServletException ; 16 import javax.servlet.http.Cookie ; 17 18 import org.apache.catalina.LifecycleException; 19 import org.apache.catalina.Session; 20 import org.apache.catalina.Realm; 21 import org.apache.catalina.SessionEvent; 22 import org.apache.catalina.authenticator.Constants; 23 import org.apache.catalina.connector.Request; 24 import org.apache.catalina.connector.Response; 25 26 27 47 public class ClusteredSingleSignOn 48 extends org.apache.catalina.authenticator.SingleSignOn 49 { 50 51 static 53 { 54 info = ClusteredSingleSignOn.class.getName(); 55 } 56 57 59 60 65 private String clusterManagerClass = 66 TreeCacheSSOClusterManager.class.getName(); 67 68 71 private SSOClusterManager ssoClusterManager = null; 72 73 78 private String treeCacheName = Tomcat5.DEFAULT_CACHE_NAME; 79 80 82 88 public SSOClusterManager getClusterManager() 89 { 90 return this.ssoClusterManager; 91 } 92 93 94 101 public void setClusterManager(SSOClusterManager clusterManager) 102 { 103 if (started && (clusterManager != ssoClusterManager)) 104 { 105 throw new IllegalStateException ("already started -- cannot set a " + 106 "new SSOClusterManager"); 107 } 108 109 this.ssoClusterManager = clusterManager; 110 111 if (clusterManager != null) 112 { 113 clusterManagerClass = clusterManager.getClass().getName(); 114 } 115 } 116 117 118 128 public String getClusterManagerClass() 129 { 130 return clusterManagerClass; 131 } 132 133 134 147 public void setClusterManagerClass(String managerClass) 148 { 149 if (!started) 150 { 151 clusterManagerClass = managerClass; 152 } 153 else if (ssoClusterManager == null) 154 { 155 try 156 { 157 createClusterManager(managerClass); 158 } 159 catch (LifecycleException e) 160 { 161 getContainer().getLogger().error("Exception creating SSOClusterManager " + 162 managerClass, e); 163 } 164 } 165 else 166 { 167 getContainer().getLogger().error("Cannot set clusterManagerClass to " + managerClass + 168 "; already started using " + clusterManagerClass); 169 } 170 } 171 172 177 public String getTreeCacheName() 178 { 179 return treeCacheName; 180 } 181 182 187 public void setTreeCacheName(String cacheName) 188 throws Exception 189 { 190 this.treeCacheName = cacheName; 191 if (ssoClusterManager != null 192 && ssoClusterManager instanceof TreeCacheSSOClusterManager) 193 { 194 ((TreeCacheSSOClusterManager) ssoClusterManager).setCacheName(cacheName); 195 } 196 } 197 198 199 201 202 210 public void start() throws LifecycleException 211 { 212 if (started) 214 { 215 throw new LifecycleException 216 (sm.getString("authenticator.alreadyStarted")); 217 } 218 219 createClusterManager(getClusterManagerClass()); 221 222 lifecycle.fireLifecycleEvent(START_EVENT, null); 223 started = true; 224 225 if (ssoClusterManager != null) 226 { 227 ssoClusterManager.start(); 228 } 229 230 } 231 232 233 241 public void stop() throws LifecycleException 242 { 243 if (!started) 245 { 246 throw new LifecycleException 247 (sm.getString("authenticator.notStarted")); 248 } 249 250 if (ssoClusterManager != null) 251 { 252 ssoClusterManager.stop(); 253 } 254 255 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 256 started = false; 257 258 } 259 260 261 263 264 276 public void sessionEvent(SessionEvent event) 277 { 278 if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())) 280 return; 281 282 Session session = event.getSession(); 284 if (getContainer().getLogger().isDebugEnabled()) 285 getContainer().getLogger().debug("Process session destroyed on " + session); 286 287 String ssoId = null; 288 synchronized (reverse) 289 { 290 ssoId = (String ) reverse.get(session); 291 } 292 if (ssoId == null) 293 return; 294 295 if ((session.getMaxInactiveInterval() > 0) 300 && (System.currentTimeMillis() - session.getLastAccessedTime() >= 301 session.getMaxInactiveInterval() * 1000)) 302 { 303 removeSession(ssoId, session); 304 } 305 else 306 { 307 logout(ssoId); 309 } 310 311 } 312 313 314 316 317 332 public void invoke(Request request, Response response) 333 throws IOException , ServletException 334 { 335 request.removeNote(Constants.REQ_SSOID_NOTE); 336 337 if (getContainer().getLogger().isDebugEnabled()) 339 getContainer().getLogger().debug("Process request for '" + request.getRequestURI() + "'"); 340 if (request.getUserPrincipal() != null) 341 { 342 if (getContainer().getLogger().isDebugEnabled()) 343 getContainer().getLogger().debug(" Principal '" + request.getUserPrincipal().getName() + 344 "' has already been authenticated"); 345 getNext().invoke(request, response); 346 return; 347 } 348 349 Cookie cookie = null; 351 Cookie cookies[] = request.getCookies(); 352 if (cookies == null) 353 cookies = new Cookie [0]; 354 for (int i = 0; i < cookies.length; i++) 355 { 356 if (Constants.SINGLE_SIGN_ON_COOKIE.equals(cookies[i].getName())) 357 { 358 cookie = cookies[i]; 359 break; 360 } 361 } 362 if (cookie == null) 363 { 364 if (getContainer().getLogger().isDebugEnabled()) 365 getContainer().getLogger().debug(" SSO cookie is not present"); 366 getNext().invoke(request, response); 367 return; 368 } 369 370 if (getContainer().getLogger().isDebugEnabled()) 372 getContainer().getLogger().debug(" Checking for cached principal for " + cookie.getValue()); 373 SingleSignOnEntry entry = getSingleSignOnEntry(cookie.getValue()); 374 if (entry != null) 375 { 376 Principal ssoPrinc = entry.getPrincipal(); 377 if (getContainer().getLogger().isDebugEnabled()) 381 { 382 getContainer().getLogger().debug(" Found cached principal '" + 383 (ssoPrinc == null ? "NULL" : ssoPrinc.getName()) + 384 "' with auth type '" + entry.getAuthType() + "'"); 385 } 386 request.setNote(Constants.REQ_SSOID_NOTE, cookie.getValue()); 387 if (!getRequireReauthentication() && ssoPrinc != null) 390 { 391 request.setAuthType(entry.getAuthType()); 392 request.setUserPrincipal(ssoPrinc); 393 } 394 } 395 else 396 { 397 if (getContainer().getLogger().isDebugEnabled()) 398 getContainer().getLogger().debug(" No cached principal found, erasing SSO cookie"); 399 cookie.setMaxAge(0); 400 response.addCookie(cookie); 401 } 402 403 getNext().invoke(request, response); 405 } 406 407 408 410 411 421 protected void associate(String ssoId, Session session) 422 { 423 if (getContainer().getLogger().isDebugEnabled()) 424 getContainer().getLogger().debug("Associate sso id " + ssoId + " with session " + session); 425 426 SingleSignOnEntry sso = getSingleSignOnEntry(ssoId); 427 boolean added = false; 428 if (sso != null) 429 added = sso.addSession(this, session); 430 431 synchronized (reverse) 432 { 433 reverse.put(session, ssoId); 434 } 435 436 if (added && ssoClusterManager != null) 438 ssoClusterManager.addSession(ssoId, session); 439 } 440 441 442 452 protected void deregister(String ssoId, Session session) 453 { 454 synchronized (reverse) 455 { 456 reverse.remove(session); 457 } 458 459 SingleSignOnEntry sso = getSingleSignOnEntry(ssoId); 460 if (sso == null) 461 return; 462 463 boolean removed = sso.removeSession(session); 464 if (removed && ssoClusterManager != null) 466 { 467 ssoClusterManager.removeSession(ssoId, session); 468 } 469 470 if (sso.getSessionCount() == 0) 473 { 474 synchronized (cache) 475 { 476 sso = (SingleSignOnEntry) cache.remove(ssoId); 477 } 478 } 479 } 480 481 482 488 protected void deregister(String ssoId) 489 { 490 if (getContainer().getLogger().isDebugEnabled()) 491 getContainer().getLogger().debug("Deregistering sso id '" + ssoId + "'"); 492 493 SingleSignOnEntry sso = null; 495 synchronized (cache) 496 { 497 sso = (SingleSignOnEntry) cache.remove(ssoId); 498 } 499 500 if (sso == null) 501 return; 502 503 Session sessions[] = sso.findSessions(); 505 for (int i = 0; i < sessions.length; i++) 506 { 507 if (getContainer().getLogger().isTraceEnabled()) 508 getContainer().getLogger().trace(" Invalidating session " + sessions[i]); 509 synchronized (reverse) 511 { 512 reverse.remove(sessions[i]); 513 } 514 sessions[i].expire(); 516 } 517 518 } 522 523 524 530 protected void logout(String ssoId) 531 { 532 deregister(ssoId); 533 if (ssoClusterManager != null) 535 ssoClusterManager.logout(ssoId); 536 } 537 538 539 545 protected SingleSignOnEntry getSingleSignOnEntry(String ssoId) 546 { 547 SingleSignOnEntry sso = localLookup(ssoId); 548 if (sso == null && ssoClusterManager != null) 551 { 552 sso = ssoClusterManager.lookup(ssoId); 553 if (sso != null) 554 { 555 synchronized (cache) 557 { 558 cache.put(ssoId, sso); 559 } 560 } 561 } 562 563 return sso; 564 } 565 566 567 587 protected boolean reauthenticate(String ssoId, Realm realm, 588 Request request) 589 { 590 if (ssoId == null || realm == null) 591 return false; 592 593 boolean reauthenticated = false; 594 595 SingleSignOnEntry entry = getSingleSignOnEntry(ssoId); 596 if (entry != null && entry.getCanReauthenticate()) 597 { 598 599 String username = entry.getUsername(); 600 if (username != null) 601 { 602 Principal reauthPrincipal = 603 realm.authenticate(username, entry.getPassword()); 604 if (reauthPrincipal != null) 605 { 606 reauthenticated = true; 607 request.setAuthType(entry.getAuthType()); 609 request.setUserPrincipal(reauthPrincipal); 610 } 611 } 612 } 613 614 return reauthenticated; 615 } 616 617 618 632 protected void register(String ssoId, Principal principal, String authType, 633 String username, String password) 634 { 635 registerLocal(ssoId, principal, authType, username, password); 636 637 if (ssoClusterManager != null) 639 ssoClusterManager.register(ssoId, authType, username, password); 640 } 641 642 643 653 protected void removeSession(String ssoId, Session session) 654 { 655 if (getContainer().getLogger().isDebugEnabled()) 656 getContainer().getLogger().debug("Removing session " + session.toString() + 657 " from sso id " + ssoId); 658 659 SingleSignOnEntry entry = getSingleSignOnEntry(ssoId); 661 if (entry == null) 662 return; 663 664 boolean removed = entry.removeSession(session); 666 if (removed && ssoClusterManager != null) 668 { 669 ssoClusterManager.removeSession(ssoId, session); 670 } 671 672 synchronized (reverse) 674 { 675 reverse.remove(session); 676 } 677 678 if (entry.getSessionCount() == 0) 681 { 682 deregister(ssoId); 683 } 684 } 685 686 687 715 protected void update(String ssoId, Principal principal, String authType, 716 String username, String password) 717 { 718 boolean needToBroadcast = updateLocal(ssoId, principal, authType, 719 username, password); 720 721 if (needToBroadcast && ssoClusterManager != null) 723 { 724 ssoClusterManager.updateCredentials(ssoId, authType, 725 username, password); 726 } 727 } 728 729 731 738 SingleSignOnEntry localLookup(String ssoId) 739 { 740 synchronized (cache) 741 { 742 return ((SingleSignOnEntry) cache.get(ssoId)); 743 } 744 745 } 746 747 759 void registerLocal(String ssoId, Principal principal, String authType, 760 String username, String password) 761 { 762 if (getContainer().getLogger().isDebugEnabled()) 763 { 764 getContainer().getLogger().debug("Registering sso id '" + ssoId + "' for user '" + 765 principal.getName() + "' with auth type '" + authType + "'"); 766 } 767 768 synchronized (cache) 769 { 770 cache.put(ssoId, new SingleSignOnEntry(principal, authType, 771 username, password)); 772 } 773 } 774 775 789 boolean updateLocal(String ssoId, Principal principal, String authType, 790 String username, String password) 791 { 792 boolean shouldBroadcast = false; 793 794 SingleSignOnEntry sso = getSingleSignOnEntry(ssoId); 795 if (sso != null) 797 { 798 if (sso.getCanReauthenticate() == false) 799 { 800 if (getContainer().getLogger().isDebugEnabled()) 801 getContainer().getLogger().debug("Update sso id " + ssoId + " to auth type " + authType); 802 803 synchronized (sso) 804 { 805 shouldBroadcast = sso.updateCredentials(principal, authType, 806 username, password); 807 } 808 } 809 else if (sso.getPrincipal() == null && principal != null) 810 { 811 if (getContainer().getLogger().isDebugEnabled()) 812 getContainer().getLogger().debug("Update sso id " + ssoId + " with principal " + 813 principal.getName()); 814 815 synchronized (sso) 816 { 817 sso.setPrincipal(principal); 818 } 820 } 821 822 } 823 824 return shouldBroadcast; 825 826 } 827 828 void remoteUpdate(String ssoId, String authType, 829 String username, String password) 830 { 831 SingleSignOnEntry sso = getSingleSignOnEntry(ssoId); 832 if (sso != null && sso.getCanReauthenticate() == false) 834 { 835 if (getContainer().getLogger().isDebugEnabled()) 836 getContainer().getLogger().debug("Update sso id " + ssoId + " to auth type " + authType); 837 838 synchronized (sso) 839 { 840 Principal p = sso.getPrincipal(); 842 sso.updateCredentials(p, authType, username, password); 843 } 844 } 845 846 } 847 848 849 851 852 866 private void createClusterManager(String className) 867 throws LifecycleException 868 { 869 if (ssoClusterManager != null) 870 return; 871 872 if (className != null) 873 { 874 SSOClusterManager mgr = null; 875 try 876 { 877 ClassLoader tcl = 878 Thread.currentThread().getContextClassLoader(); 879 Class clazz = tcl.loadClass(className); 880 mgr = (SSOClusterManager) clazz.newInstance(); 881 mgr.setSingleSignOnValve(this); 882 if (mgr instanceof TreeCacheSSOClusterManager) 883 { 884 ((TreeCacheSSOClusterManager) mgr).setCacheName(getTreeCacheName()); 885 } 886 ssoClusterManager = mgr; 887 clusterManagerClass = className; 888 } 889 catch (Throwable t) 890 { 891 throw new LifecycleException("Cannot create " + 892 "SSOClusterManager using " + 893 className, t); 894 } 895 896 if (started) 897 { 898 ssoClusterManager.start(); 899 } 900 } 901 } 902 903 } | Popular Tags |