You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2010/05/19 04:39:26 UTC

svn commit: r945999 [2/2] - in /incubator/shiro/trunk: ./ core/src/ core/src/main/java/org/apache/shiro/mgt/ core/src/main/java/org/apache/shiro/session/ core/src/main/java/org/apache/shiro/session/mgt/ core/src/main/java/org/apache/shiro/subject/suppo...

Modified: incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java (original)
+++ incubator/shiro/trunk/core/src/test/java/org/apache/shiro/session/mgt/DelegatingSessionTest.java Wed May 19 02:39:25 2010
@@ -41,7 +41,7 @@ public class DelegatingSessionTest {
     public void setup() {
         ThreadContext.remove();
         sm = new DefaultSessionManager();
-        this.session = new DelegatingSession(sm, sm.start(null).getId());
+        this.session = new DelegatingSession(sm, new DefaultSessionKey(sm.start(null).getId()));
     }
 
     @After

Modified: incubator/shiro/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/pom.xml?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/pom.xml (original)
+++ incubator/shiro/trunk/pom.xml Wed May 19 02:39:25 2010
@@ -92,7 +92,7 @@
         </mailingList>
     </mailingLists>
 
-    
+
     <developers>
         <developer>
             <id>kaosko</id>
@@ -102,6 +102,15 @@
             <organization>Apache Software Foundation</organization>
             <timezone>-8</timezone>
         </developer>
+        <developer>
+            <id>lhazlewood</id>
+            <name>Les Hazlewood</name>
+            <email>lhazlewood@apache.org</email>
+            <url>http://www.leshazlewood.com</url>
+            <organization>Katasoft</organization>
+            <organizationUrl>http://www.katasoft.com</organizationUrl>
+            <timezone>-8</timezone>
+        </developer>
     </developers>
 
     <modules>
@@ -456,87 +465,87 @@
                     </reportSet>
                 </reportSets>
             </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>cobertura-maven-plugin</artifactId>
-            <version>2.4</version>
-            <configuration>
-              <formats>
-                <format>xml</format>
-                <format>html</format>
-              </formats>
-            </configuration>
-          </plugin>
-          <plugin>
-            <artifactId>maven-jxr-plugin</artifactId>
-            <version>2.1</version>
-            <configuration>
-              <aggregate>true</aggregate>
-            </configuration>
-          </plugin>
-          <plugin>
-            <artifactId>maven-pmd-plugin</artifactId>
-            <version>2.5</version>
-            <configuration>
-              <linkXref>true</linkXref>
-              <sourceEncoding>utf-8</sourceEncoding>
-              <targetJdk>1.5</targetJdk>
-            </configuration>
-          </plugin>
-          <plugin>
-            <artifactId>maven-project-info-reports-plugin</artifactId>
-            <!-- Disable, just to make it go faster --> 
-            <configuration>
-              <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
-            </configuration>
-          </plugin>
-          <plugin>
-            <artifactId>maven-surefire-report-plugin</artifactId>
-            <version>2.5</version>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>taglist-maven-plugin</artifactId>
-            <version>2.4</version>
-            <configuration>
-              <tagListOptions>
-                <tagClasses>
-                  <tagClass>
-                    <displayName>Todo Work</displayName>
-                    <tags>
-                      <tag>
-                        <matchString>todo</matchString>
-                        <matchType>ignoreCase</matchType>
-                      </tag>
-                      <tag>
-                        <matchString>FIXME</matchString>
-                        <matchType>exact</matchType>
-                      </tag>
-                    </tags>
-                  </tagClass>
-                  <tagClass>
-                    <displayName>Deprecated</displayName>
-                    <tags>
-                      <tag>
-                        <matchString>@Deprecated</matchString>
-                        <matchType>exact</matchType>
-                      </tag>
-                    </tags>
-                  </tagClass>
-                </tagClasses>
-              </tagListOptions>
-            </configuration>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>jdepend-maven-plugin</artifactId>
-            <version>2.0-beta-2</version>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>dashboard-maven-plugin</artifactId>
-            <version>1.0.0-beta-1</version>
-          </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>2.4</version>
+                <configuration>
+                    <formats>
+                        <format>xml</format>
+                        <format>html</format>
+                    </formats>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <version>2.1</version>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-pmd-plugin</artifactId>
+                <version>2.5</version>
+                <configuration>
+                    <linkXref>true</linkXref>
+                    <sourceEncoding>utf-8</sourceEncoding>
+                    <targetJdk>1.5</targetJdk>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <!-- Disable, just to make it go faster -->
+                <configuration>
+                    <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-report-plugin</artifactId>
+                <version>2.5</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>taglist-maven-plugin</artifactId>
+                <version>2.4</version>
+                <configuration>
+                    <tagListOptions>
+                        <tagClasses>
+                            <tagClass>
+                                <displayName>Todo Work</displayName>
+                                <tags>
+                                    <tag>
+                                        <matchString>todo</matchString>
+                                        <matchType>ignoreCase</matchType>
+                                    </tag>
+                                    <tag>
+                                        <matchString>FIXME</matchString>
+                                        <matchType>exact</matchType>
+                                    </tag>
+                                </tags>
+                            </tagClass>
+                            <tagClass>
+                                <displayName>Deprecated</displayName>
+                                <tags>
+                                    <tag>
+                                        <matchString>@Deprecated</matchString>
+                                        <matchType>exact</matchType>
+                                    </tag>
+                                </tags>
+                            </tagClass>
+                        </tagClasses>
+                    </tagListOptions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>jdepend-maven-plugin</artifactId>
+                <version>2.0-beta-2</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>dashboard-maven-plugin</artifactId>
+                <version>1.0.0-beta-1</version>
+            </plugin>
         </plugins>
     </reporting>
 
@@ -577,14 +586,14 @@
             </build>
         </profile>
         <profile>
-          <id>apache-release</id>
-          <distributionManagement>
-              <site>
-                  <id>incubator.website</id>
-                  <name>Apache Incubator Site</name>
-                  <url>scp://people.apache.org/www/incubator.apache.org/shiro/site/${project.version}</url>
-              </site>
-          </distributionManagement>
+            <id>apache-release</id>
+            <distributionManagement>
+                <site>
+                    <id>incubator.website</id>
+                    <name>Apache Incubator Site</name>
+                    <url>scp://people.apache.org/www/incubator.apache.org/shiro/site/${project.version}</url>
+                </site>
+            </distributionManagement>
         </profile>
     </profiles>
 </project>

Modified: incubator/shiro/trunk/samples/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/samples/pom.xml?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/samples/pom.xml (original)
+++ incubator/shiro/trunk/samples/pom.xml Wed May 19 02:39:25 2010
@@ -36,11 +36,11 @@
         <module>aspectj</module>
         <module>quickstart</module>
         <module>web</module>
-        <module>spring-client</module>        
-        <module>spring</module>        
+        <module>spring-client</module>
+        <module>spring</module>
         <module>spring-hibernate</module>
     </modules>
-    
+
     <reporting>
         <plugins>
             <plugin>

Propchange: incubator/shiro/trunk/samples/spring-hibernate/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 19 02:39:25 2010
@@ -1 +1,2 @@
 /incubator/jsecurity/import/trunk/samples/spring-hibernate:720066-749338
+/incubator/shiro/branches/session_manager_API_change/samples/spring-hibernate:945409-945995

Modified: incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactory.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactory.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactory.java (original)
+++ incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactory.java Wed May 19 02:39:25 2010
@@ -21,6 +21,8 @@ package org.apache.shiro.spring.remoting
 import org.aopalliance.intercept.MethodInvocation;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.NativeSessionManager;
+import org.apache.shiro.session.mgt.SessionKey;
 import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.subject.Subject;
 import org.slf4j.Logger;
@@ -53,13 +55,14 @@ public class SecureRemoteInvocationFacto
     private static final String SESSION_ID_SYSTEM_PROPERTY_NAME = "shiro.session.id";
 
     private String sessionId;
-    
+
+    public SecureRemoteInvocationFactory() {
+    }
+
     public SecureRemoteInvocationFactory(String sessionId) {
         this();
         this.sessionId = sessionId;
     }
-    
-    public SecureRemoteInvocationFactory() {}
 
     /**
      * Creates a {@link RemoteInvocation} with the current session ID as an
@@ -76,24 +79,26 @@ public class SecureRemoteInvocationFacto
 
         //If the calling MI is for a remoting SessionManager delegate, we need to acquire the session ID from the method
         //argument and NOT interact with SecurityUtils/subject.getSession to avoid a stack overflow
-        if (SessionManager.class.equals(mi.getMethod().getDeclaringClass())) {
+        Class miDeclaringClass = mi.getMethod().getDeclaringClass();
+        if (SessionManager.class.equals(miDeclaringClass) || NativeSessionManager.class.equals(miDeclaringClass)) {
             sessionManagerMethodInvocation = true;
-            //for SessionManager calls, all method calls except the 'start' methods require the session id
+            //for SessionManager calls, all method calls except the 'start' methods require a SessionKey
             // as the first argument, so just get it from there:
             if (!mi.getMethod().getName().equals("start")) {
-                sessionId = (Serializable) mi.getArguments()[0];
+                SessionKey key = (SessionKey) mi.getArguments()[0];
+                sessionId = key.getSessionId();
             }
         }
 
         //tried the delegate. Use the injected session id if given
         if (sessionId == null) sessionId = this.sessionId;
-        
+
         // If sessionId is null, only then try the Subject:
         if (sessionId == null) {
             try {
                 // HACK Check if can get the securityManager - this'll cause an exception if it's not set 
                 SecurityUtils.getSecurityManager();
-                if (sessionId == null && !sessionManagerMethodInvocation) {
+                if (!sessionManagerMethodInvocation) {
                     Subject subject = SecurityUtils.getSubject();
                     Session session = subject.getSession(false);
                     if (session != null) {

Modified: incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/package-info.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/package-info.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/package-info.java (original)
+++ incubator/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/web/package-info.java Wed May 19 02:39:25 2010
@@ -18,7 +18,7 @@
  */
 /**
  * Spring-specific components for use in Spring-based web applications.
- * 
+ *
  * @see ShiroFilterFactoryBean ShiroFilterFactoryBean
  */
 package org.apache.shiro.spring.web;
\ No newline at end of file

Modified: incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactoryTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactoryTest.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactoryTest.java (original)
+++ incubator/shiro/trunk/support/spring/src/test/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationFactoryTest.java Wed May 19 02:39:25 2010
@@ -19,8 +19,9 @@
 package org.apache.shiro.spring.remoting;
 
 import org.aopalliance.intercept.MethodInvocation;
+import org.apache.shiro.session.mgt.DefaultSessionKey;
+import org.apache.shiro.session.mgt.SessionKey;
 import org.apache.shiro.session.mgt.SessionManager;
-import org.apache.shiro.subject.Subject;
 import org.apache.shiro.util.ThreadContext;
 import org.junit.After;
 import org.junit.Before;
@@ -46,10 +47,6 @@ public class SecureRemoteInvocationFacto
         ThreadContext.remove();
     }
 
-    protected void bind(Subject subject) {
-        ThreadContext.bind(subject);
-    }
-
     @After
     public void tearDown() {
         ThreadContext.remove();
@@ -92,11 +89,12 @@ public class SecureRemoteInvocationFacto
         SecureRemoteInvocationFactory factory = new SecureRemoteInvocationFactory();
 
         MethodInvocation mi = createMock(MethodInvocation.class);
-        Method method = getMethod("isValid", SessionManager.class);
+        Method method = getMethod("getSession", SessionManager.class);
         expect(mi.getMethod()).andReturn(method).anyTimes();
 
         String dummySessionId = UUID.randomUUID().toString();
-        Object[] args = {dummySessionId};
+        SessionKey sessionKey = new DefaultSessionKey(dummySessionId);
+        Object[] args = {sessionKey};
         expect(mi.getArguments()).andReturn(args).anyTimes();
 
         replay(mi);

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/DefaultWebSecurityManager.java Wed May 19 02:39:25 2010
@@ -20,17 +20,19 @@ package org.apache.shiro.web;
 
 import org.apache.shiro.mgt.DefaultSecurityManager;
 import org.apache.shiro.realm.Realm;
-import org.apache.shiro.session.InvalidSessionException;
-import org.apache.shiro.session.Session;
-import org.apache.shiro.session.mgt.DelegatingSession;
 import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.session.mgt.SessionKey;
+import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.subject.SubjectContext;
 import org.apache.shiro.util.LifecycleUtils;
 import org.apache.shiro.web.mgt.CookieRememberMeManager;
 import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
 import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
-import org.apache.shiro.web.session.*;
+import org.apache.shiro.web.session.DefaultWebSessionContext;
+import org.apache.shiro.web.session.DefaultWebSessionManager;
+import org.apache.shiro.web.session.ServletContainerSessionManager;
+import org.apache.shiro.web.session.WebSessionKey;
 import org.apache.shiro.web.subject.WebSubject;
 import org.apache.shiro.web.subject.WebSubjectContext;
 import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
@@ -116,7 +118,7 @@ public class DefaultWebSecurityManager e
         this.sessionMode = mode;
         if (recreate) {
             LifecycleUtils.destroy(getSessionManager());
-            WebSessionManager sessionManager = createSessionManager(mode);
+            SessionManager sessionManager = createSessionManager(mode);
             setSessionManager(sessionManager);
         }
     }
@@ -128,7 +130,7 @@ public class DefaultWebSecurityManager e
         return this.sessionMode == null || this.sessionMode.equals(HTTP_SESSION_MODE);
     }
 
-    protected WebSessionManager createSessionManager(String sessionMode) {
+    protected SessionManager createSessionManager(String sessionMode) {
         if (sessionMode == null || sessionMode.equalsIgnoreCase(HTTP_SESSION_MODE)) {
             if (log.isInfoEnabled()) {
                 log.info(HTTP_SESSION_MODE + " mode - enabling ServletContainerSessionManager (HTTP-only Sessions)");
@@ -143,62 +145,39 @@ public class DefaultWebSecurityManager e
     }
 
     @Override
-    protected Session resolveContextSession(SubjectContext context) throws InvalidSessionException {
-        Session session = null;
-        if (context instanceof WebSubjectContext) {
-            WebSubjectContext wsc = (WebSubjectContext) context;
-            ServletRequest request = wsc.resolveServletRequest();
-            ServletResponse response = wsc.resolveServletResponse();
-            if (request != null && response != null) {
-                session = ((WebSessionManager) getSessionManager()).getSession(request, response);
-            }
-        } else {
-            session = super.resolveContextSession(context);
-        }
-
-        if (session != null && !isHttpSessionMode()) {
-            //don't expose the EIS-tier session instance to the SubjectFactory
-            session = new DelegatingSession(this, session.getId());
-        }
-
-        return session;
-    }
-
-    @Override
-    protected Serializable getSessionId(SubjectContext subjectContext) {
-        Serializable sessionId = super.getSessionId(subjectContext);
-        if (sessionId == null && subjectContext instanceof WebSubjectContext) {
-            WebSubjectContext wsc = (WebSubjectContext) subjectContext;
-            ServletRequest request = wsc.resolveServletRequest();
-            ServletResponse response = wsc.resolveServletResponse();
-            if (request != null && response != null) {
-                sessionId = ((WebSessionManager) getSessionManager()).getSessionId(request, response);
-            }
-        }
-
-        return sessionId;
-    }
-
-    @Override
     protected SessionContext createSessionContext(SubjectContext subjectContext) {
         SessionContext sessionContext = super.createSessionContext(subjectContext);
         if (subjectContext instanceof WebSubjectContext) {
             WebSubjectContext wsc = (WebSubjectContext) subjectContext;
             ServletRequest request = wsc.resolveServletRequest();
             ServletResponse response = wsc.resolveServletResponse();
-            WebSessionContext webSessionContext = new DefaultWebSessionContext(sessionContext);
+            DefaultWebSessionContext webSessionContext = new DefaultWebSessionContext(sessionContext);
             if (request != null) {
                 webSessionContext.setServletRequest(request);
             }
             if (response != null) {
                 webSessionContext.setServletResponse(response);
             }
+
             sessionContext = webSessionContext;
         }
         return sessionContext;
     }
 
     @Override
+    protected SessionKey getSessionKey(SubjectContext context) {
+        if (WebUtils.isWeb(context)) {
+            Serializable sessionId = context.getSessionId();
+            ServletRequest request = WebUtils.getRequest(context);
+            ServletResponse response = WebUtils.getResponse(context);
+            return new WebSessionKey(sessionId, request, response);
+        } else {
+            return super.getSessionKey(context);
+
+        }
+    }
+
+    @Override
     protected void beforeLogout(Subject subject) {
         super.beforeLogout(subject);
         removeRequestIdentity(subject);

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java Wed May 19 02:39:25 2010
@@ -21,12 +21,9 @@ package org.apache.shiro.web;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.subject.Subject;
-import org.apache.shiro.subject.SubjectContext;
 import org.apache.shiro.util.StringUtils;
-import org.apache.shiro.util.ThreadContext;
 import org.apache.shiro.web.filter.AccessControlFilter;
-import org.apache.shiro.web.subject.WebSubject;
-import org.apache.shiro.web.subject.WebSubjectContext;
+import org.apache.shiro.web.util.RequestPairSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,14 +54,6 @@ public class WebUtils {
 
     private static final Logger log = LoggerFactory.getLogger(WebUtils.class);
 
-
-    /**
-     * Message displayed when a servlet request or response is not bound to the current thread context when expected.
-     */
-    private static final String NOT_BOUND_ERROR_MESSAGE =
-            "Make sure WebUtils.bind() is being called. (typically called by AbstractShiroFilter)  " +
-                    "This could also happen when running integration tests that don't properly call WebUtils.bind().";
-
     public static final String SERVLET_REQUEST_KEY = ServletRequest.class.getName() + "_SHIRO_THREAD_CONTEXT_KEY";
     public static final String SERVLET_RESPONSE_KEY = ServletResponse.class.getName() + "_SHIRO_THREAD_CONTEXT_KEY";
 
@@ -74,7 +63,6 @@ public class WebUtils {
      */
     public static final String SAVED_REQUEST_KEY = "shiroSavedRequest";
 
-
     /**
      * Standard Servlet 2.3+ spec request attributes for include URI and paths.
      * <p>If included via a RequestDispatcher, the current resource will see the
@@ -234,7 +222,7 @@ public class WebUtils {
         return enc;
     }
 
-    /**
+    /*
      * Returns {@code true} IFF the specified {@code SubjectContext}:
      * <ol>
      * <li>A {@link WebSubjectContext} instance</li>
@@ -247,151 +235,55 @@ public class WebUtils {
      * @return {@code true} IFF the specified context has HTTP request/response objects, {@code false} otherwise.
      * @since 1.0
      */
-    public static boolean isHttp(SubjectContext context) {
-        if (context instanceof WebSubjectContext) {
-            WebSubjectContext wsc = (WebSubjectContext) context;
-            ServletRequest request = wsc.resolveServletRequest();
-            ServletResponse response = wsc.resolveServletResponse();
-            return request != null && request instanceof HttpServletRequest &&
-                    response != null && response instanceof HttpServletResponse;
-        }
-        return false;
+
+    public static boolean isWeb(Object requestPairSource) {
+        return requestPairSource instanceof RequestPairSource && isWeb((RequestPairSource) requestPairSource);
     }
 
-    /**
-     * Returns {@code true} IFF the specified {@code Subject}:
-     * <ol>
-     * <li>A {@link WebSubject} instance</li>
-     * <li>The {@code WebSubject}'s request/response pair are not null</li>
-     * <li>The request is an {@link HttpServletRequest} instance</li>
-     * <li>The response is an {@link HttpServletResponse} instance</li>
-     * </ol>
-     *
-     * @param subject the {@code Subject} instance to check to see if it is HTTP compatible
-     * @return {@code true} IFF the specified subject has HTTP request/response objects, {@code false} otherwise.
-     * @since 1.0
-     */
-    public static boolean isHttp(Subject subject) {
-        if (subject instanceof WebSubject) {
-            WebSubject ws = (WebSubject) subject;
-            ServletRequest request = ws.getServletRequest();
-            ServletResponse response = ws.getServletResponse();
-            return request != null && request instanceof HttpServletRequest &&
-                    response != null && response instanceof HttpServletResponse;
-        }
-        return false;
+    public static boolean isHttp(Object requestPairSource) {
+        return requestPairSource instanceof RequestPairSource && isHttp((RequestPairSource) requestPairSource);
     }
 
-    /**
-     * Returns the {@code Subject}'s associated {@link HttpServletRequest} instance.  This method will
-     * throw an {@link IllegalArgumentException} if the Subject is not a {@link WebSubject} instance or that
-     * {@code WebSubject} does not have an HTTP-compatible request object.  Callers will usually want to call
-     * the {@link #isHttp(Subject) isHttp(subject)} method first to ensure this method can be called successfully.
-     *
-     * @param subject the subject instance from which to retrieve the {@code Subject}'s associated
-     *                {@link HttpServletRequest} instance
-     * @return the subject's associated {@link HttpServletRequest} object.
-     * @throws IllegalArgumentException if the {@code Subject} is not a {@link WebSubject} or that {@code WebSubject}'s
-     *                                  request is not an {@link HttpServletRequest}.
-     * @since 1.0
-     */
-    public static HttpServletRequest getHttpRequest(Subject subject) throws IllegalArgumentException {
-        if (!(subject instanceof WebSubject)) {
-            String msg = "Subject instance is not a " + WebSubject.class.getName() + " instance.  This is required " +
-                    "to obtain a ServletRequest and ServletResponse";
-            throw new IllegalArgumentException(msg);
-        }
-        WebSubject ws = (WebSubject) subject;
-        ServletRequest request = ws.getServletRequest();
-        if (request == null || !(request instanceof HttpServletRequest)) {
-            String msg = "WebSubject's ServletRequest is null or not an instance of HttpServletRequest.";
-            throw new IllegalArgumentException(msg);
+    public static ServletRequest getRequest(Object requestPairSource) {
+        if (requestPairSource instanceof RequestPairSource) {
+            return ((RequestPairSource) requestPairSource).getServletRequest();
         }
-        return (HttpServletRequest) request;
+        return null;
     }
 
-    /**
-     * Returns the {@code Subject}'s associated {@link HttpServletResponse} instance.  This method will
-     * throw an {@link IllegalArgumentException} if the Subject is not a {@link WebSubject} instance or that
-     * {@code WebSubject} does not have an HTTP-compatible response object.  Callers will usually want to call
-     * the {@link #isHttp(Subject) isHttp(subject)} method first to ensure this method can be called successfully.
-     *
-     * @param subject the subject instance from which to retrieve the {@code Subject}'s associated
-     *                {@link HttpServletResponse} instance
-     * @return the subject's associated {@link HttpServletResponse} object.
-     * @throws IllegalArgumentException if the {@code Subject} is not a {@link WebSubject} or that {@code WebSubject}'s
-     *                                  response is not an {@link HttpServletResponse}.
-     * @since 1.0
-     */
-    public static HttpServletResponse getHttpResponse(Subject subject) {
-        if (!(subject instanceof WebSubject)) {
-            String msg = "Subject instance is not a " + WebSubject.class.getName() + " instance.  This is required " +
-                    "to obtain a ServletRequest and ServletResponse";
-            throw new IllegalArgumentException(msg);
-        }
-        WebSubject ws = (WebSubject) subject;
-        ServletResponse response = ws.getServletResponse();
-        if (response == null || !(response instanceof HttpServletResponse)) {
-            String msg = "WebSubject's ServletResponse is null or not an instance of HttpServletResponse.";
-            throw new IllegalArgumentException(msg);
+    public static ServletResponse getResponse(Object requestPairSource) {
+        if (requestPairSource instanceof RequestPairSource) {
+            return ((RequestPairSource) requestPairSource).getServletResponse();
         }
-        return (HttpServletResponse) response;
+        return null;
     }
 
-    /**
-     * Returns the {@code SubjectContext}'s {@link HttpServletRequest} instance.  This method will
-     * throw an {@link IllegalArgumentException} if the context is not a {@link WebSubjectContext} instance or that
-     * {@code WebSubjectContext} does not have an HTTP-compatible request object.  Callers will usually want to call
-     * the {@link #isHttp(SubjectContext) isHttp(subjectContext)} method first to ensure this method can be called
-     * successfully.
-     *
-     * @param context the subjectContext instance from which to retrieve the associated {@link HttpServletRequest}
-     * @return the context's {@link HttpServletRequest} object.
-     * @throws IllegalArgumentException if the {@code SubjectContext} is not a {@link WebSubjectContext} or that
-     *                                  {@code WebSubjectContext}'s request is not an {@link HttpServletRequest}.
-     * @since 1.0
-     */
-    public static HttpServletRequest getHttpRequest(SubjectContext context) {
-        if (!(context instanceof WebSubjectContext)) {
-            String msg = "SubjectContext instance is not a " + WebSubjectContext.class.getName() + " instance.  " +
-                    "This is required to obtain a ServletRequest and ServletResponse";
-            throw new IllegalArgumentException(msg);
-        }
-        WebSubjectContext wsc = (WebSubjectContext) context;
-        ServletRequest request = wsc.resolveServletRequest();
-        if (request == null || !(request instanceof HttpServletRequest)) {
-            String msg = "WebSubjectContext's ServletRequest is null or not an instance of HttpServletRequest.";
-            throw new IllegalArgumentException(msg);
+    public static HttpServletRequest getHttpRequest(Object requestPairSource) {
+        ServletRequest request = getRequest(requestPairSource);
+        if (request instanceof HttpServletRequest) {
+            return (HttpServletRequest) request;
         }
-        return (HttpServletRequest) request;
+        return null;
     }
 
-    /**
-     * Returns the {@code SubjectContext}'s {@link HttpServletResponse} instance.  This method will
-     * throw an {@link IllegalArgumentException} if the context is not a {@link WebSubjectContext} instance or that
-     * {@code WebSubjectContext} does not have an HTTP-compatible response object.  Callers will usually want to call
-     * the {@link #isHttp(SubjectContext) isHttp(subjectContext)} method first to ensure this method can be called
-     * successfully.
-     *
-     * @param context the subjectContext instance from which to retrieve the associated {@link HttpServletResponse}
-     * @return the context's {@link HttpServletResponse} object.
-     * @throws IllegalArgumentException if the {@code SubjectContext} is not a {@link WebSubjectContext} or that
-     *                                  {@code WebSubjectContext}'s response is not an {@link HttpServletResponse}.
-     * @since 1.0
-     */
-    public static HttpServletResponse getHttpResponse(SubjectContext context) {
-        if (!(context instanceof WebSubjectContext)) {
-            String msg = "SubjectContext instance is not a " + WebSubjectContext.class.getName() + " instance.  " +
-                    "This is required to obtain a ServletRequest and ServletResponse";
-            throw new IllegalArgumentException(msg);
-        }
-        WebSubjectContext wsc = (WebSubjectContext) context;
-        ServletResponse response = wsc.resolveServletResponse();
-        if (response == null || !(response instanceof HttpServletResponse)) {
-            String msg = "WebSubjectContext's ServletResponse is null or not an instance of HttpServletResponse.";
-            throw new IllegalArgumentException(msg);
+    public static HttpServletResponse getHttpResponse(Object requestPairSource) {
+        ServletResponse response = getResponse(requestPairSource);
+        if (response instanceof HttpServletResponse) {
+            return (HttpServletResponse) response;
         }
-        return (HttpServletResponse) response;
+        return null;
+    }
+
+    private static boolean isWeb(RequestPairSource source) {
+        ServletRequest request = source.getServletRequest();
+        ServletResponse response = source.getServletResponse();
+        return request != null && response != null;
+    }
+
+    private static boolean isHttp(RequestPairSource source) {
+        ServletRequest request = source.getServletRequest();
+        ServletResponse response = source.getServletResponse();
+        return request instanceof HttpServletRequest && response instanceof HttpServletResponse;
     }
 
     /**
@@ -427,96 +319,6 @@ public class WebUtils {
     }
 
     /**
-     * Returns the current thread-bound {@code ServletRequest} or {@code null} if there is not one bound.
-     * <p/>
-     * It is the case in certain enterprise environments where a web-enabled SecurityManager (and its internal mechanisms)
-     * is the primary SecurityManager but also serves as a 'central' coordinator for security operations in a cluster.
-     * In these environments, it is possible for a web-enabled SecurityManager to receive remote method invocations that
-     * are not HTTP based.  In such an environment this method would return {@code null}.
-     * <p/>
-     * <b>THIS IS NOT PART OF APACHE SHIRO'S PUBLIC API.</b>  It exists for Shiro implementation requirements only.
-     *
-     * @return the current thread-bound {@code ServletRequest} or {@code null} if there is not one bound.
-     * @since 1.0
-     */
-    public static ServletRequest getServletRequest() {
-        ServletRequest request = (ServletRequest) ThreadContext.get(SERVLET_REQUEST_KEY);
-        if (request == null) {
-            Subject subject = ThreadContext.getSubject();
-            if (subject instanceof WebSubject) {
-                WebSubject webSubject = (WebSubject) subject;
-                request = webSubject.getServletRequest();
-            }
-        }
-        return request;
-    }
-
-    /**
-     * Convenience method that simplifies binding a ServletRequest to the current thread (via the ThreadContext).
-     * <p/>
-     * <p>The method's existence is to help reduce casting in your own code and to simplify remembering of
-     * ThreadContext key names.  The implementation is simple in that, if the servletRequest is not <tt>null</tt>,
-     * it binds it to the thread, i.e.:
-     * <p/>
-     * <pre>
-     * if (servletRequest != null) {
-     *     ThreadContext.put( SERVLET_REQUEST_KEY, servletRequest );
-     * }</pre>
-     *
-     * @param servletRequest the ServletRequest object to bind to the thread.  If the argument is null, nothing will be done.
-     */
-    public static void bind(ServletRequest servletRequest) {
-        if (servletRequest != null) {
-            ThreadContext.put(SERVLET_REQUEST_KEY, servletRequest);
-        }
-    }
-
-    /**
-     * Returns the current thread-bound {@code ServletResponse} or {@code null} if there is not one bound.
-     * <p/>
-     * It is the case in certain enterprise environments where a web-enabled SecurityManager (and its internal mechanisms)
-     * is the primary SecurityManager but also serves as a 'central' coordinator for security operations in a cluster.
-     * In these environments, it is possible for a web-enabled SecurityManager to receive remote method invocations that
-     * are not HTTP based.  In such an environment this method would return {@code null}.
-     * <p/>
-     * <b>THIS IS NOT PART OF APACHE SHIRO'S PUBLIC API.</b>  It exists for Shiro implementation requirements only.
-     *
-     * @return the current thread-bound {@code ServletResponse} or {@code null} if there is not one bound.
-     * @since 1.0
-     */
-    public static ServletResponse getServletResponse() {
-        ServletResponse response = (ServletResponse) ThreadContext.get(SERVLET_RESPONSE_KEY);
-        if (response == null) {
-            Subject subject = ThreadContext.getSubject();
-            if (subject instanceof WebSubject) {
-                WebSubject webSubject = (WebSubject) subject;
-                response = webSubject.getServletResponse();
-            }
-        }
-        return response;
-    }
-
-    /**
-     * Convenience method that simplifies binding a ServletResponse to the thread via the ThreadContext.
-     * <p/>
-     * <p>The method's existence is to help reduce casting in your own code and to simplify remembering of
-     * ThreadContext key names.  The implementation is simple in that, if the servletResponse is not <tt>null</tt>,
-     * it binds it to the thread, i.e.:
-     * <p/>
-     * <pre>
-     * if (servletResponse != null) {
-     *     ThreadContext.put( SERVLET_RESPONSE_KEY, servletResponse );
-     * }</pre>
-     *
-     * @param servletResponse the ServletResponse object to bind to the thread.  If the argument is null, nothing will be done.
-     */
-    public static void bind(ServletResponse servletResponse) {
-        if (servletResponse != null) {
-            ThreadContext.put(SERVLET_RESPONSE_KEY, servletResponse);
-        }
-    }
-
-    /**
      * Redirects the current request to a new URL based on the given parameters.
      *
      * @param request          the servlet request.

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java Wed May 19 02:39:25 2010
@@ -18,9 +18,13 @@
  */
 package org.apache.shiro.web.session;
 
+import org.apache.shiro.session.ExpiredSessionException;
+import org.apache.shiro.session.InvalidSessionException;
 import org.apache.shiro.session.Session;
-import org.apache.shiro.session.SessionException;
 import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.DelegatingSession;
+import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.session.mgt.SessionKey;
 import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.servlet.Cookie;
 import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
@@ -32,6 +36,7 @@ import org.slf4j.LoggerFactory;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.Serializable;
 
 
@@ -41,9 +46,7 @@ import java.io.Serializable;
  * @author Les Hazlewood
  * @since 0.9
  */
-public class DefaultWebSessionManager extends DefaultSessionManager implements WebSessionManager {
-
-    //TODO - complete JavaDoc
+public class DefaultWebSessionManager extends DefaultSessionManager {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultWebSessionManager.class);
 
@@ -75,33 +78,21 @@ public class DefaultWebSessionManager ex
         this.sessionIdCookieEnabled = sessionIdCookieEnabled;
     }
 
-    private void storeSessionId(Serializable currentId, ServletRequest request, ServletResponse response) {
+    private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
         if (currentId == null) {
             String msg = "sessionId cannot be null when persisting for subsequent requests.";
             throw new IllegalArgumentException(msg);
         }
-        if (!(request instanceof HttpServletRequest)) {
-            log.debug("Current request is not an HttpServletRequest - cannot save session id cookie. Returning.");
-            return;
-        }
         Cookie template = getSessionIdCookie();
         Cookie cookie = new SimpleCookie(template);
         String idString = currentId.toString();
         cookie.setValue(idString);
-        cookie.saveTo(WebUtils.toHttp(request), WebUtils.toHttp(response));
+        cookie.saveTo(request, response);
         log.trace("Set session ID cookie for session with id {}", idString);
     }
 
-    private void markSessionIdValid(ServletRequest request) {
-        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
-    }
-
-    private void markSessionIdInvalid(ServletRequest request) {
-        request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID);
-    }
-
-    private void removeSessionIdCookie(ServletRequest request, ServletResponse response) {
-        getSessionIdCookie().removeFrom(WebUtils.toHttp(request), WebUtils.toHttp(response));
+    private void removeSessionIdCookie(HttpServletRequest request, HttpServletResponse response) {
+        getSessionIdCookie().removeFrom(request, response);
     }
 
     private String getSessionIdCookieValue(ServletRequest request, ServletResponse response) {
@@ -139,78 +130,113 @@ public class DefaultWebSessionManager ex
             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
             //automatically mark it valid here.  If it is invalid, the
             //onUnknownSession method below will be invoked and we'll remove the attribute at that time.
-            markSessionIdValid(request);
+            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
         }
         return id;
     }
 
+    protected Session createExposedSession(Session session, SessionContext context) {
+        if (!WebUtils.isWeb(context)) {
+            return super.createExposedSession(session, context);
+        }
+        ServletRequest request = WebUtils.getRequest(context);
+        ServletResponse response = WebUtils.getResponse(context);
+        SessionKey key = new WebSessionKey(session.getId(), request, response);
+        return new DelegatingSession(this, key);
+    }
+
+    protected Session createExposedSession(Session session, SessionKey key) {
+        if (!WebUtils.isWeb(key)) {
+            return super.createExposedSession(session, key);
+        }
+
+        ServletRequest request = WebUtils.getRequest(key);
+        ServletResponse response = WebUtils.getResponse(key);
+        SessionKey sessionKey = new WebSessionKey(session.getId(), request, response);
+        return new DelegatingSession(this, sessionKey);
+    }
+
     /**
      * Stores the Session's ID, usually as a Cookie, to associate with future requests.
      *
      * @param session the session that was just {@link #createSession created}.
      */
     @Override
-    protected void onStart(Session session) {
-        ServletRequest request = WebUtils.getServletRequest();
-        ServletResponse response = WebUtils.getServletResponse();
-        if (request == null || response == null) {
-            log.debug("Request or response object is not bound to the thread.  Assuming this session start " +
-                    "activity is due to a non web request (possible in a web application that also services " +
-                    "non web clients.");
+    protected void onStart(Session session, SessionContext context) {
+        super.onStart(session, context);
+
+        if (!WebUtils.isHttp(context)) {
+            log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response " +
+                    "pair. No session ID cookie will be set.");
             return;
+
         }
+        HttpServletRequest request = WebUtils.getHttpRequest(context);
+        HttpServletResponse response = WebUtils.getHttpResponse(context);
+
         if (isSessionIdCookieEnabled()) {
             Serializable sessionId = session.getId();
             storeSessionId(sessionId, request, response);
         } else {
-            log.debug("Session ID cookie is disabled.  No cookie has been set for new session with id {}",
-                    session.getId());
+            log.debug("Session ID cookie is disabled.  No cookie has been set for new session with id {}", session.getId());
         }
 
         request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
         request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
     }
 
-    public Session getSession(ServletRequest request, ServletResponse response) throws SessionException {
-        Serializable id = getReferencedSessionId(request, response);
-        Session session = null;
-        if ( id != null ) {
-            session = getSession(id);
+    @Override
+    public Serializable getSessionId(SessionKey key) {
+        Serializable id = super.getSessionId(key);
+        if (id == null && WebUtils.isWeb(key)) {
+            ServletRequest request = WebUtils.getRequest(key);
+            ServletResponse response = WebUtils.getResponse(key);
+            id = getSessionId(request, response);
         }
-        return session;
+        return id;
     }
 
-    public Serializable getSessionId(ServletRequest request, ServletResponse response) {
+    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
         return getReferencedSessionId(request, response);
     }
 
     @Override
-    public void onUnknownSession(Serializable sessionId) {
-        ServletRequest request = WebUtils.getServletRequest();
-        if (request != null) {
-            markSessionIdInvalid(request);
-        }
-        removeSessionIdCookie();
+    protected void onExpiration(Session s, ExpiredSessionException ese, SessionKey key) {
+        super.onExpiration(s, ese, key);
+        onInvalidation(key);
     }
 
-    protected void onStop(Session session) {
-        super.onStop(session);
-        removeSessionIdCookie();
+    @Override
+    protected void onInvalidation(Session session, InvalidSessionException ise, SessionKey key) {
+        super.onInvalidation(session, ise, key);
+        onInvalidation(key);
     }
 
-    protected void onExpiration(Session session) {
-        super.onExpiration(session);
-        removeSessionIdCookie();
+    private void onInvalidation(SessionKey key) {
+        ServletRequest request = WebUtils.getRequest(key);
+        if (request != null) {
+            request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID);
+        }
+        if (WebUtils.isHttp(key)) {
+            log.debug("Referenced session was invalid.  Removing session ID cookie.");
+            removeSessionIdCookie(WebUtils.getHttpRequest(key), WebUtils.getHttpResponse(key));
+        } else {
+            log.debug("SessionKey argument is not HTTP compatible or does not have an HTTP request/response " +
+                    "pair. Session ID cookie will not be removed due to invalidated session.");
+        }
     }
 
-    private void removeSessionIdCookie() {
-        ServletRequest request = WebUtils.getServletRequest();
-        ServletResponse response = WebUtils.getServletResponse();
-        if (request == null || response == null) {
-            log.debug("No request or response bound to the thread.  Session ID cookie cannot be removed.  This could " +
-                    "occur in a web application that also services non web clients (e.g. RMI remoting).");
-            return;
+    @Override
+    protected void onStop(Session session, SessionKey key) {
+        super.onStop(session, key);
+        if (WebUtils.isHttp(key)) {
+            HttpServletRequest request = WebUtils.getHttpRequest(key);
+            HttpServletResponse response = WebUtils.getHttpResponse(key);
+            log.debug("Session has been stopped (subject logout or explicit stop).  Removing session ID cookie.");
+            removeSessionIdCookie(request, response);
+        } else {
+            log.debug("SessionKey argument is not HTTP compatible or does not have an HTTP request/response " +
+                    "pair. Session ID cookie will not be removed due to stopped session.");
         }
-        removeSessionIdCookie(request, response);
     }
 }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java Wed May 19 02:39:25 2010
@@ -19,16 +19,16 @@
 package org.apache.shiro.web.session;
 
 import org.apache.shiro.authz.AuthorizationException;
-import org.apache.shiro.session.InvalidSessionException;
 import org.apache.shiro.session.Session;
+import org.apache.shiro.session.SessionException;
 import org.apache.shiro.session.mgt.AbstractSessionManager;
 import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.session.mgt.SessionKey;
+import org.apache.shiro.web.WebUtils;
 
 import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
-import java.io.Serializable;
 
 
 /**
@@ -51,7 +51,7 @@ import java.io.Serializable;
  * @author Les Hazlewood
  * @since 0.9
  */
-public class ServletContainerSessionManager extends AbstractSessionManager implements WebSessionManager {
+public class ServletContainerSessionManager extends AbstractSessionManager {
 
     //TODO - complete JavaDoc
 
@@ -60,92 +60,60 @@ public class ServletContainerSessionMana
     public ServletContainerSessionManager() {
     }
 
-    @Override
-    public Session start(SessionContext initData) throws AuthorizationException {
-        return createSession(initData);
+    public Session start(SessionContext context) throws AuthorizationException {
+        return createSession(context);
     }
 
-    /**
-     * This method exists only to satisfy the parent's abstract method signature.  It should never be called since
-     * there is no way to obtain a Session instance from a Servlet Container by id (in a system independent
-     * manner).
-     * <p/>
-     * This method will always throw an exception if called since the
-     * {@link #getSession(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method should be used in all
-     * cases instead.
-     *
-     * @param sessionId
-     * @return
-     * @throws InvalidSessionException
-     */
-    protected Session doGetSession(Serializable sessionId) throws InvalidSessionException {
-        //Ignore session id since there is no way to acquire a session based on an id in a servlet container
-        //(that is implementation agnostic)
-        String msg = "Cannot retrieve sessions by ID when Sessions are managed by the Servlet Container.  This " +
-                "feature is available for Shiro 'native' session SessionManager implementations only.";
-        throw new IllegalStateException(msg);
-        /*ServletRequest request = WebUtils.getServletRequest();
-        ServletResponse response = WebUtils.getServletResponse();
-        if (request == null) {
-            String msg = "Thread-bound ServletRequest cannot be null in ServletContainer-managed Session environments.";
-            throw new IllegalStateException(msg);
+    public Session getSession(SessionKey key) throws SessionException {
+        if (!WebUtils.isHttp(key)) {
+            String msg = "SessionKey must be an HTTP compatible implementation.";
+            throw new IllegalArgumentException(msg);
         }
-        return getSession(request, response);*/
-    }
 
-    /**
-     * @since 1.0
-     */
-    public Session getSession(ServletRequest request, ServletResponse response) {
+        HttpServletRequest request = WebUtils.getHttpRequest(key);
+
         Session session = null;
-        HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
+
+        HttpSession httpSession = request.getSession(false);
         if (httpSession != null) {
             session = createSession(httpSession, request.getRemoteHost());
         }
+
         return session;
     }
 
-    /**
-     * @since 1.0
-     */
-    public Serializable getSessionId(ServletRequest request, ServletResponse response) {
-        HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
-        return httpSession != null ? httpSession.getId() : null;
+    private String getHost(SessionContext context) {
+        String host = context.getHost();
+        if (host == null) {
+            ServletRequest request = WebUtils.getRequest(context);
+            if (request != null) {
+                host = request.getRemoteHost();
+            }
+        }
+        return host;
+
     }
 
     /**
      * @since 1.0
      */
     protected Session createSession(SessionContext sessionContext) throws AuthorizationException {
-        if (!(sessionContext instanceof WebSessionContext)) {
-            String msg = "SessionContext must be a " + WebSessionContext.class.getName() + " instance.";
+        if (!WebUtils.isHttp(sessionContext)) {
+            String msg = "SessionContext must be an HTTP compatible implementation.";
             throw new IllegalArgumentException(msg);
         }
 
-        WebSessionContext wsc = (WebSessionContext) sessionContext;
+        HttpServletRequest request = WebUtils.getHttpRequest(sessionContext);
 
-        ServletRequest request = wsc.getServletRequest();
-        if (request == null) {
-            String msg = "WebSessionContext must contain a ServletRequest.";
-            throw new IllegalStateException(msg);
-        }
-        ServletResponse response = wsc.getServletResponse();
-        if (response == null) {
-            String msg = "WebSessionContext must contain a ServletResponse.";
-            throw new IllegalStateException(msg);
-        }
-
-        HttpSession httpSession = ((HttpServletRequest) request).getSession();
+        HttpSession httpSession = request.getSession();
 
         //ensure that the httpSession timeout reflects what is configured:
         long timeoutMillis = getGlobalSessionTimeout();
         httpSession.setMaxInactiveInterval((int) (timeoutMillis / MILLIS_PER_SECOND));
 
-        String originatingHost = wsc.getHost();
-        if (originatingHost == null) {
-            originatingHost = request.getRemoteHost();
-        }
-        return createSession(httpSession, originatingHost);
+        String host = getHost(sessionContext);
+
+        return createSession(httpSession, host);
     }
 
     protected Session createSession(HttpSession httpSession, String host) {

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java Wed May 19 02:39:25 2010
@@ -19,6 +19,7 @@
 package org.apache.shiro.web.session;
 
 import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.web.util.RequestPairSource;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -31,7 +32,7 @@ import javax.servlet.ServletResponse;
  * @author Les Hazlewood
  * @since 1.0
  */
-public interface WebSessionContext extends SessionContext {
+public interface WebSessionContext extends SessionContext, RequestPairSource {
 
     /**
      * Returns the {@code ServletRequest} received by the servlet container triggering the creation of the

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java Wed May 19 02:39:25 2010
@@ -23,6 +23,7 @@ import org.apache.shiro.mgt.SecurityMana
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.subject.SubjectContext;
 import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
+import org.apache.shiro.web.util.RequestPairSource;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -33,7 +34,7 @@ import javax.servlet.ServletResponse;
  *
  * @since 1.0
  */
-public interface WebSubject extends Subject {
+public interface WebSubject extends Subject, RequestPairSource {
 
     /**
      * Returns the {@code ServletRequest} accessible when the Subject instance was created.

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubjectContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubjectContext.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubjectContext.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubjectContext.java Wed May 19 02:39:25 2010
@@ -19,6 +19,7 @@
 package org.apache.shiro.web.subject;
 
 import org.apache.shiro.subject.SubjectContext;
+import org.apache.shiro.web.util.RequestPairSource;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -30,7 +31,7 @@ import javax.servlet.ServletResponse;
  * @author Les Hazlewood
  * @since 1.0
  */
-public interface WebSubjectContext extends SubjectContext {
+public interface WebSubjectContext extends SubjectContext, RequestPairSource {
 
     /**
      * Returns the {@code ServletRequest} received by the servlet container triggering the creation of the

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java Wed May 19 02:39:25 2010
@@ -20,7 +20,6 @@ package org.apache.shiro.web.subject.sup
 
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.subject.support.DefaultSubjectContext;
-import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.subject.WebSubject;
 import org.apache.shiro.web.subject.WebSubjectContext;
 
@@ -81,10 +80,6 @@ public class DefaultWebSubjectContext ex
                 request = ((WebSubject) existing).getServletRequest();
             }
         }
-        //last resort - try the thread-local (TODO - remove this if possible):
-        if (request == null) {
-            request = WebUtils.getServletRequest();
-        }
 
         return request;
     }
@@ -111,11 +106,6 @@ public class DefaultWebSubjectContext ex
             }
         }
 
-        //last resort - try the thread-local (TODO - remove this if possible):
-        if (response == null) {
-            response = WebUtils.getServletResponse();
-        }
-
         return response;
     }
 }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java Wed May 19 02:39:25 2010
@@ -30,7 +30,6 @@ import org.apache.shiro.web.subject.WebS
 
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
-import java.util.concurrent.Callable;
 
 /**
  * @since 1.0
@@ -70,14 +69,4 @@ public class WebDelegatingSubject extend
         wsc.setServletResponse(this.servletResponse);
         return wsc;
     }
-
-    @Override
-    public <V> Callable<V> associateWith(Callable<V> callable) {
-        return new WebSubjectCallable<V>(this, callable);
-    }
-
-    @Override
-    public Runnable associateWith(Runnable runnable) {
-        return new WebSubjectRunnable(this, runnable);
-    }
 }

Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/AbstractWebSecurityManagerTest.java Wed May 19 02:39:25 2010
@@ -18,16 +18,9 @@
  */
 package org.apache.shiro.web;
 
-import org.apache.shiro.mgt.SecurityManager;
-import org.apache.shiro.subject.Subject;
 import org.apache.shiro.util.ThreadContext;
-import org.apache.shiro.web.subject.WebSubject;
-import org.apache.shiro.web.subject.support.WebSubjectThreadState;
 import org.junit.After;
 
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
 /**
  * @since 1.0
  */
@@ -37,13 +30,4 @@ public abstract class AbstractWebSecurit
     public void tearDown() {
         ThreadContext.remove();
     }
-
-    protected Subject newSubject(SecurityManager sm, ServletRequest request, ServletResponse response) {
-        ThreadContext.bind(sm);
-        WebSubject subject = new WebSubject.Builder(sm, request, response).buildWebSubject();
-        WebSubjectThreadState threadState = new WebSubjectThreadState(subject);
-        threadState.bind();
-        return subject;
-    }
-
 }

Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DefaultWebSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DefaultWebSecurityManagerTest.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DefaultWebSecurityManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DefaultWebSecurityManagerTest.java Wed May 19 02:39:25 2010
@@ -26,6 +26,7 @@ import org.apache.shiro.session.Session;
 import org.apache.shiro.session.mgt.AbstractSessionManager;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.web.servlet.ShiroHttpSession;
+import org.apache.shiro.web.subject.WebSubject;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -65,7 +66,7 @@ public class DefaultWebSecurityManagerTe
     }
 
     protected Subject newSubject(ServletRequest request, ServletResponse response) {
-        return newSubject(sm, request, response);
+        return new WebSubject.Builder(sm, request, response).buildSubject();
     }
 
     @Test

Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java?rev=945999&r1=945998&r2=945999&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java Wed May 19 02:39:25 2010
@@ -20,7 +20,6 @@ package org.apache.shiro.web.session;
 
 import org.apache.shiro.session.mgt.SimpleSession;
 import org.apache.shiro.util.ThreadContext;
-import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.servlet.Cookie;
 import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
 import org.apache.shiro.web.servlet.ShiroHttpSession;
@@ -57,8 +56,9 @@ public class DefaultWebSessionManagerTes
         SimpleSession session = new SimpleSession();
         session.setId("12345");
 
-        WebUtils.bind(createMock(HttpServletRequest.class));
-        WebUtils.bind(createMock(HttpServletResponse.class));
+        WebSessionContext wsc = new DefaultWebSessionContext();
+        wsc.setServletRequest(createMock(HttpServletRequest.class));
+        wsc.setServletResponse(createMock(HttpServletResponse.class));
 
         //test that the cookie template is being used:
         expect(cookie.getValue()).andReturn("blah");
@@ -73,7 +73,7 @@ public class DefaultWebSessionManagerTes
 
         replay(cookie);
 
-        mgr.onStart(session);
+        mgr.onStart(session, wsc);
 
         verify(cookie);
     }
@@ -91,12 +91,13 @@ public class DefaultWebSessionManagerTes
         SimpleSession session = new SimpleSession();
         session.setId("12345");
 
-        WebUtils.bind(createMock(HttpServletRequest.class));
-        WebUtils.bind(createMock(HttpServletResponse.class));
+        WebSessionContext wsc = new DefaultWebSessionContext();
+        wsc.setServletRequest(createMock(HttpServletRequest.class));
+        wsc.setServletResponse(createMock(HttpServletResponse.class));
 
         replay(cookie);
 
-        mgr.onStart(session);
+        mgr.onStart(session, wsc);
 
         verify(cookie);
     }