Author: markt Date: Tue Jul 7 16:33:02 2009 New Revision: 791900 URL: http://svn.apache.org/viewvc?rev=791900&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=39231 The JAAS contract for LoginModule says we have to call logout(). This won't always work (eg if there is no session) but is a reasonable effort.
Modified: tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java tomcat/trunk/java/org/apache/catalina/realm/JAASRealm.java tomcat/trunk/java/org/apache/catalina/session/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/session/StandardSession.java Modified: tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java?rev=791900&r1=791899&r2=791900&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/GenericPrincipal.java Tue Jul 7 16:33:02 2009 @@ -22,6 +22,9 @@ import java.security.Principal; import java.util.Arrays; import java.util.List; + +import javax.security.auth.login.LoginContext; + import org.apache.catalina.Realm; @@ -83,7 +86,26 @@ */ public GenericPrincipal(Realm realm, String name, String password, List<String> roles, Principal userPrincipal) { - + this(realm, name, password, roles, userPrincipal, null); + } + + /** + * Construct a new Principal, associated with the specified Realm, for the + * specified username and password, with the specified role names + * (as Strings). + * + * @param realm The Realm that owns this principal + * @param name The username of the user represented by this Principal + * @param password Credentials used to authenticate this user + * @param roles List of roles (must be Strings) possessed by this user + * @param userPrincipal - the principal to be returned from the request + * getUserPrincipal call if not null; if null, this will be returned + * @param loginContext - If provided, this will be used to log out the user + * at the appropriate time + */ + public GenericPrincipal(Realm realm, String name, String password, + List<String> roles, Principal userPrincipal, + LoginContext loginContext) { super(); this.realm = realm; this.name = name; @@ -95,6 +117,7 @@ if (this.roles.length > 0) Arrays.sort(this.roles); } + this.loginContext = loginContext; } @@ -159,6 +182,17 @@ } } + + /** + * The JAAS LoginContext, if any, used to authenticate this Principal. + * Kept so we can call logout(). + */ + protected LoginContext loginContext = null; + + public LoginContext getLoginContext() { + return loginContext; + } + // --------------------------------------------------------- Public Methods Modified: tomcat/trunk/java/org/apache/catalina/realm/JAASRealm.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/JAASRealm.java?rev=791900&r1=791899&r2=791900&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/JAASRealm.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/JAASRealm.java Tue Jul 7 16:33:02 2009 @@ -427,7 +427,7 @@ log.debug(sm.getString("jaasRealm.loginContextCreated", username)); // Return the appropriate Principal for this authenticated Subject - Principal principal = createPrincipal(username, subject); + Principal principal = createPrincipal(username, subject, loginContext); if (principal == null) { log.debug(sm.getString("jaasRealm.authenticateFailure", username)); return (null); @@ -488,8 +488,11 @@ * roles, but only if their respective classes match one of the "role class" classes. * If a user Principal cannot be constructed, return <code>null</code>. * @param subject The <code>Subject</code> representing the logged-in user + * @param loginContext Associated with th Princpal so + * {...@link LoginContext#logout()} can be called later */ - protected Principal createPrincipal(String username, Subject subject) { + protected Principal createPrincipal(String username, Subject subject, + LoginContext loginContext) { // Prepare to scan the Principals for this Subject List<String> roles = new ArrayList<String>(); @@ -536,7 +539,8 @@ } // Return the resulting Principal for our authenticated user - return new GenericPrincipal(this, username, null, roles, userPrincipal); + return new GenericPrincipal(this, username, null, roles, userPrincipal, + loginContext); } /** Modified: tomcat/trunk/java/org/apache/catalina/session/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/LocalStrings.properties?rev=791900&r1=791899&r2=791900&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/session/LocalStrings.properties Tue Jul 7 16:33:02 2009 @@ -61,6 +61,7 @@ standardSession.getId.ise=getId: Session already invalidated standardSession.getMaxInactiveInterval.ise=getMaxInactiveInterval: Session already invalidated standardSession.getValueNames.ise=getValueNames: Session already invalidated +standardSession.jaaslogoutfail=Exception logging out user when expiring session standardSession.notSerializable=Cannot serialize session attribute {0} for session {1} standardSession.removeAttribute.ise=removeAttribute: Session already invalidated standardSession.sessionEvent=Session event listener threw exception Modified: tomcat/trunk/java/org/apache/catalina/session/StandardSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/StandardSession.java?rev=791900&r1=791899&r2=791900&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/StandardSession.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/StandardSession.java Tue Jul 7 16:33:02 2009 @@ -37,6 +37,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import javax.security.auth.login.LoginException; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionActivationListener; @@ -57,6 +58,7 @@ import org.apache.catalina.util.StringManager; import org.apache.catalina.core.StandardContext; +import org.apache.catalina.realm.GenericPrincipal; import org.apache.catalina.security.SecurityUtil; /** @@ -758,6 +760,20 @@ fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null); } + // Call the JAAS logout method if necessary + if (principal instanceof GenericPrincipal) { + GenericPrincipal gp = (GenericPrincipal) principal; + if (gp.getLoginContext() != null) { + try { + gp.getLoginContext().logout(); + } catch (LoginException e) { + manager.getContainer().getLogger().error( + sm.getString("standardSession.jaaslogoutfail"), + e); + } + } + } + // We have completed expire of this session expiring = false; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org