Author: markt
Date: Fri Dec 19 13:55:24 2014
New Revision: 1646721
URL: http://svn.apache.org/r1646721
Log:
Refactor to replace reverse map with dedicated session listener that
contains a reference to the SSO ID.
This refactoring is in support of the fix for BZ 57338.
Added:
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java
Modified:
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
Modified: tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java?rev=1646721&r1=1646720&r2=1646721&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java Fri
Dec 19 13:55:24 2014
@@ -31,7 +31,6 @@ import org.apache.catalina.LifecycleExce
import org.apache.catalina.Manager;
import org.apache.catalina.Realm;
import org.apache.catalina.Session;
-import org.apache.catalina.SessionEvent;
import org.apache.catalina.SessionListener;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
@@ -57,7 +56,7 @@ import org.apache.tomcat.util.res.String
*
* @author Craig R. McClanahan
*/
-public class SingleSignOn extends ValveBase implements SessionListener {
+public class SingleSignOn extends ValveBase {
private static final StringManager sm =
StringManager.getManager(SingleSignOn.class);
@@ -90,13 +89,6 @@ public class SingleSignOn extends ValveB
private boolean requireReauthentication = false;
/**
- * The cache of single sign on identifiers, keyed by the Session that is
- * associated with them.
- */
- protected Map<SingleSignOnSessionKey,String> reverse = new
ConcurrentHashMap<>();
-
-
- /**
* Optional SSO cookie domain.
*/
private String cookieDomain;
@@ -196,55 +188,6 @@ public class SingleSignOn extends ValveB
}
- // ------------------------------------------------ SessionListener Methods
-
- /**
- * Acknowledge the occurrence of the specified event.
- *
- * @param event SessionEvent that has occurred
- */
- @Override
- public void sessionEvent(SessionEvent event) {
-
- if (!getState().isAvailable()) {
- return;
- }
-
- // We only care about session destroyed events
- if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())) {
- return;
- }
-
- // Look up the single session id associated with this session (if any)
- Session session = event.getSession();
- if (containerLog.isDebugEnabled()) {
- containerLog.debug("Process session destroyed on " + session);
- }
-
- String ssoId = null;
- ssoId = reverse.get(new SingleSignOnSessionKey(session));
- if (ssoId == null) {
- return;
- }
-
- // Was the session destroyed as the result of a timeout or context
stop?
- // If so, we'll just remove the expired session from the SSO. If the
- // session was logged out, we'll log out of all session associated with
- // the SSO.
- if (((session.getMaxInactiveInterval() > 0)
- && (System.currentTimeMillis() -
session.getThisAccessedTimeInternal() >=
- session.getMaxInactiveInterval() * 1000))
- || (!session.getManager().getContext().getState().isAvailable())) {
- removeSession(ssoId, session);
- } else {
- // The session was logged out.
- // Deregister this single session id, invalidating
- // associated sessions
- deregister(ssoId);
- }
- }
-
-
// ---------------------------------------------------------- Valve Methods
/**
@@ -349,6 +292,43 @@ public class SingleSignOn extends ValveB
// ------------------------------------------------------ Protected Methods
/**
+ * Process a session destroyed event by removing references to that session
+ * from the caches and - if the session destruction is the result of a
+ * logout - destroy the associated SSO session.
+ *
+ * @param ssoId The ID of the SSO session which which the destroyed
+ * session was associated
+ * @param session The session that has been destroyed
+ */
+ public void sessionDestroyed(String ssoId, Session session) {
+
+ if (!getState().isAvailable()) {
+ return;
+ }
+
+ if (containerLog.isDebugEnabled()) {
+ containerLog.debug("Process session destroyed on " + session);
+ }
+
+ // Was the session destroyed as the result of a timeout or context
stop?
+ // If so, we'll just remove the expired session from the SSO. If the
+ // session was logged out, we'll log out of all session associated with
+ // the SSO.
+ if (((session.getMaxInactiveInterval() > 0)
+ && (System.currentTimeMillis() -
session.getThisAccessedTimeInternal() >=
+ session.getMaxInactiveInterval() * 1000))
+ || (!session.getManager().getContext().getState().isAvailable())) {
+ removeSession(ssoId, session);
+ } else {
+ // The session was logged out.
+ // Deregister this single session id, invalidating
+ // associated sessions
+ deregister(ssoId);
+ }
+ }
+
+
+ /**
* Associate the specified single sign on identifier with the
* specified Session.
*
@@ -368,8 +348,7 @@ public class SingleSignOn extends ValveB
if (sso == null) {
return false;
} else {
- sso.addSession(this, session);
- reverse.put(new SingleSignOnSessionKey(session), ssoId);
+ sso.addSession(this, ssoId, session);
return true;
}
}
@@ -399,8 +378,6 @@ public class SingleSignOn extends ValveB
if (containerLog.isTraceEnabled()) {
containerLog.trace(" Invalidating session " + ssoKey);
}
- // Remove from reverse cache first to avoid recursion
- reverse.remove(ssoKey);
// Invalidate this session
expire(ssoKey);
}
@@ -586,9 +563,6 @@ public class SingleSignOn extends ValveB
// Remove the inactive session from SingleSignOnEntry
entry.removeSession(session);
- // Remove the inactive session from the 'reverse' Map.
- reverse.remove(new SingleSignOnSessionKey(session));
-
// If there are not sessions left in the SingleSignOnEntry,
// deregister the entry.
if (entry.findSessions().size() == 0) {
@@ -597,6 +571,11 @@ public class SingleSignOn extends ValveB
}
+ protected SessionListener getSessionListener(String ssoId) {
+ return new SingleSignOnListener(ssoId);
+ }
+
+
@Override
protected synchronized void startInternal() throws LifecycleException {
Container c = getContainer();
Modified:
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java?rev=1646721&r1=1646720&r2=1646721&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
Fri Dec 19 13:55:24 2014
@@ -87,12 +87,12 @@ public class SingleSignOnEntry implement
* the SSO session.
* @param session The <code>Session</code> being associated with the SSO.
*/
- public void addSession(SingleSignOn sso, Session session) {
+ public void addSession(SingleSignOn sso, String ssoId, Session session) {
SingleSignOnSessionKey key = new SingleSignOnSessionKey(session);
SingleSignOnSessionKey currentKey = sessionKeys.putIfAbsent(key, key);
if (currentKey == null) {
// Session not previously added
- session.addSessionListener(sso);
+ session.addSessionListener(sso.getSessionListener(ssoId));
}
}
Added:
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java?rev=1646721&view=auto
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java
(added)
+++
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java
Fri Dec 19 13:55:24 2014
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.authenticator;
+
+import java.io.Serializable;
+
+import org.apache.catalina.Authenticator;
+import org.apache.catalina.Context;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.SessionEvent;
+import org.apache.catalina.SessionListener;
+
+public class SingleSignOnListener implements SessionListener, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String ssoId;
+
+ public SingleSignOnListener(String ssoId) {
+ this.ssoId = ssoId;
+ }
+
+
+ @Override
+ public void sessionEvent(SessionEvent event) {
+ if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())) {
+ return;
+ }
+
+ Session session = event.getSession();
+ Manager manager = session.getManager();
+ if (manager == null) {
+ return;
+ }
+ Context context = manager.getContext();
+ if (context == null) {
+ return;
+ }
+ Authenticator authenticator = context.getAuthenticator();
+ if (!(authenticator instanceof AuthenticatorBase)) {
+ return;
+ }
+ SingleSignOn sso = ((AuthenticatorBase) authenticator).sso;
+ if (sso == null) {
+ return;
+ }
+ sso.sessionDestroyed(ssoId, session);
+ }
+}
Modified:
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java?rev=1646721&r1=1646720&r2=1646721&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
(original)
+++
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
Fri Dec 19 13:55:24 2014
@@ -24,7 +24,6 @@ import org.apache.catalina.LifecycleExce
import org.apache.catalina.Session;
import org.apache.catalina.authenticator.SingleSignOn;
import org.apache.catalina.authenticator.SingleSignOnEntry;
-import org.apache.catalina.authenticator.SingleSignOnSessionKey;
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.catalina.ha.ClusterValve;
import org.apache.catalina.tribes.Channel;
@@ -157,12 +156,6 @@ public class ClusterSingleSignOn extends
cls, terminateOnStartFailure);
cache.setChannelSendOptions(mapSendOptions);
this.cache = cache;
-
- ReplicatedMap<SingleSignOnSessionKey,String> reverse = new
ReplicatedMap<>(
- this, cluster.getChannel(), rpcTimeout,
cluster.getClusterName() + "-SSO-reverse",
- cls, terminateOnStartFailure);
- reverse.setChannelSendOptions(mapSendOptions);
- this.reverse = reverse;
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
throw new LifecycleException(
@@ -187,7 +180,6 @@ public class ClusterSingleSignOn extends
if (getCluster() != null) {
((ReplicatedMap<?,?>) cache).breakdown();
- ((ReplicatedMap<?,?>) reverse).breakdown();
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]