Author: remy.maucherat(a)jboss.com
Date: 2014-01-14 04:37:44 -0500 (Tue, 14 Jan 2014)
New Revision: 2338
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java
Log:
BZ1027272 (part 1): Attempt to set the CCL and thread binding when expiring sessions from
other contexts.
Modified:
branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java
===================================================================
---
branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java 2014-01-10
15:09:14 UTC (rev 2337)
+++
branches/7.4.x/src/main/java/org/apache/catalina/authenticator/SingleSignOn.java 2014-01-14
09:37:44 UTC (rev 2338)
@@ -22,20 +22,26 @@
import static org.jboss.web.CatalinaMessages.MESSAGES;
import java.io.IOException;
+import java.security.AccessController;
import java.security.Principal;
+import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
+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.ThreadBindingListener;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.LifecycleSupport;
@@ -505,7 +511,15 @@
reverse.remove(sessions[i]);
}
// Invalidate this session
- sessions[i].expire();
+ ClassLoader oldContextClassLoader = null;
+ try {
+ oldContextClassLoader = bindThread(sessions[i]);
+ sessions[i].expire();
+ } finally {
+ if (oldContextClassLoader != null) {
+ unbindThread(sessions[i], oldContextClassLoader);
+ }
+ }
}
// NOTE: Clients may still possess the old single sign on cookie,
@@ -515,6 +529,97 @@
}
+ protected ClassLoader bindThread(Session session) {
+
+ Manager manager = session.getManager();
+ Context context = null;
+ ClassLoader contextClassLoader = null;
+ ThreadBindingListener threadBindingListener = null;
+ if (manager != null && manager.getContainer() != null
+ && manager.getContainer() instanceof Context) {
+ context = (Context) manager.getContainer();
+ }
+ if (context != null) {
+ if (context.getLoader() != null &&
context.getLoader().getClassLoader() != null) {
+ contextClassLoader = context.getLoader().getClassLoader();
+ }
+ threadBindingListener = context.getThreadBindingListener();
+ }
+ if (threadBindingListener == null || contextClassLoader == null) {
+ return null;
+ }
+
+ if (Globals.IS_SECURITY_ENABLED) {
+ return AccessController.doPrivileged(new PrivilegedBind(contextClassLoader,
threadBindingListener));
+ } else {
+ ClassLoader oldContextClassLoader =
+ Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ threadBindingListener.bind();
+ return oldContextClassLoader;
+ }
+
+ }
+
+ protected class PrivilegedBind implements PrivilegedAction<ClassLoader> {
+ private ClassLoader contextClassLoader;
+ private ThreadBindingListener threadBindingListener;
+
+ PrivilegedBind(ClassLoader contextClassLoader, ThreadBindingListener
threadBindingListener) {
+ this.contextClassLoader = contextClassLoader;
+ this.threadBindingListener = threadBindingListener;
+ }
+
+ public ClassLoader run() {
+ ClassLoader oldContextClassLoader =
+ Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ threadBindingListener.bind();
+ return oldContextClassLoader;
+ }
+ }
+
+ protected void unbindThread(Session session, ClassLoader oldContextClassLoader) {
+
+ Manager manager = session.getManager();
+ Context context = null;
+ ThreadBindingListener threadBindingListener = null;
+ if (manager != null && manager.getContainer() != null
+ && manager.getContainer() instanceof Context) {
+ context = (Context) manager.getContainer();
+ }
+ if (context != null) {
+ threadBindingListener = context.getThreadBindingListener();
+ }
+ if (threadBindingListener == null) {
+ return;
+ }
+
+ if (Globals.IS_SECURITY_ENABLED) {
+ AccessController.doPrivileged(new PrivilegedUnbind(oldContextClassLoader,
threadBindingListener));
+ } else {
+ threadBindingListener.unbind();
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ }
+
+ }
+
+ protected class PrivilegedUnbind implements PrivilegedAction<Void> {
+ private ClassLoader oldContextClassLoader;
+ private ThreadBindingListener threadBindingListener;
+
+ PrivilegedUnbind(ClassLoader oldContextClassLoader, ThreadBindingListener
threadBindingListener) {
+ this.oldContextClassLoader = oldContextClassLoader;
+ this.threadBindingListener = threadBindingListener;
+ }
+
+ public Void run() {
+ threadBindingListener.unbind();
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ return null;
+ }
+ }
+
/**
* Logout the specified single sign on identifier from all sessions.
*
Show replies by date