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 03:47:44 UTC

svn commit: r945994 [2/2] - in /incubator/shiro/branches/session_manager_API_change: 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/test/java/org/apache/sh...

Modified: incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/WebUtils.java
URL: http://svn.apache.org/viewvc/incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/WebUtils.java?rev=945994&r1=945993&r2=945994&view=diff
==============================================================================
--- incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/WebUtils.java (original)
+++ incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/WebUtils.java Wed May 19 01:47:43 2010
@@ -20,14 +20,9 @@ package org.apache.shiro.web;
 
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.session.Session;
-import org.apache.shiro.session.mgt.SessionContext;
 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;
@@ -227,7 +222,7 @@ public class WebUtils {
         return enc;
     }
 
-    /**
+    /*
      * Returns {@code true} IFF the specified {@code SubjectContext}:
      * <ol>
      * <li>A {@link WebSubjectContext} instance</li>
@@ -240,298 +235,57 @@ 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) {
-        return context instanceof RequestPairSource && isHttp((RequestPairSource) context);
-    }
-
-    public static boolean isHttp(Subject subject) {
-        return subject instanceof RequestPairSource && isHttp((RequestPairSource) subject);
-    }
-
-    public static boolean isHttp(SessionContext context) {
-        return context instanceof RequestPairSource && isHttp((RequestPairSource) context);
-    }
-
-    public static boolean isWeb(Subject subject) {
-        return subject instanceof RequestPairSource && isWeb((RequestPairSource) subject);
-    }
-
-    public static boolean isWeb(SubjectContext context) {
-        return context instanceof RequestPairSource && isWeb((RequestPairSource) context);
-    }
-
-    public static boolean isWeb(SessionContext context) {
-        return context instanceof RequestPairSource && isWeb((RequestPairSource) context);
-    }
-
-    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;
-    }
-
-    public static ServletRequest getRequest(Subject subject) {
-        if (subject instanceof RequestPairSource) {
-            return ((RequestPairSource) subject).getServletRequest();
-        }
-        return null;
-    }
-
-    public static ServletResponse getResponse(Subject subject) {
-        if (subject instanceof RequestPairSource) {
-            return ((RequestPairSource) subject).getServletResponse();
-        }
-        return null;
-    }
 
-    public static HttpServletRequest getHttpRequest(Subject subject) {
-        ServletRequest request = getRequest(subject);
-        if (request instanceof HttpServletRequest) {
-            return toHttp(request);
-        }
-        return null;
+    public static boolean isWeb(Object requestPairSource) {
+        return requestPairSource instanceof RequestPairSource && isWeb((RequestPairSource) requestPairSource);
     }
 
-    public static HttpServletResponse getHttpResponse(Subject subject) {
-        ServletResponse response = getResponse(subject);
-        if (response instanceof HttpServletResponse) {
-            return toHttp(response);
-        }
-        return null;
+    public static boolean isHttp(Object requestPairSource) {
+        return requestPairSource instanceof RequestPairSource && isHttp((RequestPairSource) requestPairSource);
     }
 
-    public static ServletRequest getRequest(SubjectContext context) {
-        if (context instanceof RequestPairSource) {
-            return ((RequestPairSource) context).getServletRequest();
+    public static ServletRequest getRequest(Object requestPairSource) {
+        if (requestPairSource instanceof RequestPairSource) {
+            return ((RequestPairSource) requestPairSource).getServletRequest();
         }
         return null;
     }
 
-    public static ServletResponse getResponse(SubjectContext context) {
-        if (context instanceof RequestPairSource) {
-            return ((RequestPairSource) context).getServletResponse();
+    public static ServletResponse getResponse(Object requestPairSource) {
+        if (requestPairSource instanceof RequestPairSource) {
+            return ((RequestPairSource) requestPairSource).getServletResponse();
         }
         return null;
     }
 
-    public static HttpServletRequest getHttpRequest(SubjectContext context) {
-        ServletRequest request = getRequest(context);
+    public static HttpServletRequest getHttpRequest(Object requestPairSource) {
+        ServletRequest request = getRequest(requestPairSource);
         if (request instanceof HttpServletRequest) {
-            return toHttp(request);
+            return (HttpServletRequest) request;
         }
         return null;
     }
 
-    public static HttpServletResponse getHttpResponse(SubjectContext context) {
-        ServletResponse response = getResponse(context);
+    public static HttpServletResponse getHttpResponse(Object requestPairSource) {
+        ServletResponse response = getResponse(requestPairSource);
         if (response instanceof HttpServletResponse) {
-            return toHttp(response);
-        }
-        return null;
-    }
-
-    public static ServletRequest getRequest(SessionContext context) {
-        if (context instanceof RequestPairSource) {
-            return ((RequestPairSource) context).getServletRequest();
-        }
-        return null;
-    }
-
-    public static ServletResponse getResponse(SessionContext context) {
-        if (context instanceof RequestPairSource) {
-            return ((RequestPairSource) context).getServletResponse();
+            return (HttpServletResponse) response;
         }
         return null;
     }
 
-    public static HttpServletRequest getHttpRequest(SessionContext context) {
-        ServletRequest request = getRequest(context);
-        if (request instanceof HttpServletRequest) {
-            return toHttp(request);
-        }
-        return null;
+    private static boolean isWeb(RequestPairSource source) {
+        ServletRequest request = source.getServletRequest();
+        ServletResponse response = source.getServletResponse();
+        return request != null && response != null;
     }
 
-    public static HttpServletResponse getHttpResponse(SessionContext context) {
-        ServletResponse response = getResponse(context);
-        if (response instanceof HttpServletResponse) {
-            return toHttp(response);
-        }
-        return null;
+    private static boolean isHttp(RequestPairSource source) {
+        ServletRequest request = source.getServletRequest();
+        ServletResponse response = source.getServletResponse();
+        return request instanceof HttpServletRequest && response instanceof HttpServletResponse;
     }
 
-    /*public static ServletRequest getRequest(SubjectContext context) {
-        if (!(context instanceof RequestPairSource)) {
-            String msg = "Subject instance is not web-based instance.  " +
-                    "This is required to obtain a ServletRequest and ServletResponse";
-            throw new IllegalArgumentException(msg);
-        }
-        WebSubjectContext wsc = (WebSubjectContext) context;
-        ServletRequest request = wsc.getServletRequest();
-        if (request == null) {
-            String msg = "WebSubjectContext's ServletRequest is null.";
-            throw new IllegalArgumentException(msg);
-        }
-        return request;
-    }
-
-    public static ServletResponse getResponse(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.getServletResponse();
-        if (response == null) {
-            String msg = "WebSubjectContext's ServletResponse is null.";
-            throw new IllegalArgumentException(msg);
-        }
-        return response;
-    }*/
-
-    /**
-     * 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;
-    }*/
-
-    /**
-     * 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);
-        }
-        return (HttpServletRequest) request;
-    }*/
-
-    /**
-     * 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);
-        }
-        return (HttpServletResponse) response;
-    }*/
-
-    /**
-     * 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);
-        }
-        return (HttpServletRequest) request;
-    }*/
-
-    /**
-     * 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);
-        }
-        return (HttpServletResponse) response;
-    }*/
-
     /**
      * A convenience method that merely casts the incoming <code>ServletRequest</code> to an
      * <code>HttpServletRequest</code>:
@@ -565,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/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java?rev=945994&r1=945993&r2=945994&view=diff
==============================================================================
--- incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java (original)
+++ incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java Wed May 19 01:47:43 2010
@@ -18,10 +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.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;
@@ -45,8 +48,6 @@ import java.io.Serializable;
  */
 public class DefaultWebSessionManager extends DefaultSessionManager {
 
-    //TODO - complete JavaDoc
-
     private static final Logger log = LoggerFactory.getLogger(DefaultWebSessionManager.class);
 
     private Cookie sessionIdCookie;
@@ -90,14 +91,6 @@ public class DefaultWebSessionManager ex
         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(HttpServletRequest request, HttpServletResponse response) {
         getSessionIdCookie().removeFrom(request, response);
     }
@@ -137,11 +130,32 @@ 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.
      *
@@ -149,10 +163,11 @@ public class DefaultWebSessionManager ex
      */
     @Override
     protected void onStart(Session session, SessionContext context) {
+        super.onStart(session, context);
+
         if (!WebUtils.isHttp(context)) {
-            log.debug("SubjectContext argument is not HTTP compatible or does not have a request/response " +
-                    "pair. Assuming this session start activity is due to a non web request (possible in a web " +
-                    "application that also services non web clients.");
+            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;
 
         }
@@ -171,11 +186,11 @@ public class DefaultWebSessionManager ex
     }
 
     @Override
-    public Serializable getSessionId(SessionContext context) {
-        Serializable id = super.getSessionId(context);
-        if (id == null && WebUtils.isWeb(context)) {
-            ServletRequest request = WebUtils.getRequest(context);
-            ServletResponse response = WebUtils.getResponse(context);
+    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 id;
@@ -185,22 +200,43 @@ public class DefaultWebSessionManager ex
         return getReferencedSessionId(request, response);
     }
 
-    protected void onInvalidSession(SessionContext context, Serializable sessionId, InvalidSessionException ise) {
-        ServletRequest request = WebUtils.getRequest(context);
+    @Override
+    protected void onExpiration(Session s, ExpiredSessionException ese, SessionKey key) {
+        super.onExpiration(s, ese, key);
+        onInvalidation(key);
+    }
+
+    @Override
+    protected void onInvalidation(Session session, InvalidSessionException ise, SessionKey key) {
+        super.onInvalidation(session, ise, key);
+        onInvalidation(key);
+    }
+
+    private void onInvalidation(SessionKey key) {
+        ServletRequest request = WebUtils.getRequest(key);
         if (request != null) {
-            markSessionIdInvalid(request);
+            request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID);
         }
-        if (WebUtils.isHttp(context)) {
-            removeSessionIdCookie(WebUtils.getHttpRequest(context), WebUtils.getHttpResponse(context));
+        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.");
         }
     }
 
-    protected void onStop(Session session) {
-        super.onStop(session);
-        ServletRequest request = WebUtils.getServletRequest();
-        ServletResponse response = WebUtils.getServletResponse();
-        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
-            removeSessionIdCookie(WebUtils.toHttp(request), WebUtils.toHttp(response));
+    @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.");
         }
     }
 }

Modified: incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java?rev=945994&r1=945993&r2=945994&view=diff
==============================================================================
--- incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java (original)
+++ incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java Wed May 19 01:47:43 2010
@@ -23,6 +23,7 @@ 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;
@@ -63,20 +64,19 @@ public class ServletContainerSessionMana
         return createSession(context);
     }
 
-    public Session getSession(SessionContext sessionContext) throws SessionException {
-        if (!WebUtils.isHttp(sessionContext)) {
-            String msg = "SessionContext must be an HTTP compatible implementation.";
+    public Session getSession(SessionKey key) throws SessionException {
+        if (!WebUtils.isHttp(key)) {
+            String msg = "SessionKey must be an HTTP compatible implementation.";
             throw new IllegalArgumentException(msg);
         }
 
-        HttpServletRequest request = WebUtils.getHttpRequest(sessionContext);
+        HttpServletRequest request = WebUtils.getHttpRequest(key);
 
         Session session = null;
 
         HttpSession httpSession = request.getSession(false);
         if (httpSession != null) {
-            String host = getHost(sessionContext);
-            session = createSession(httpSession, host);
+            session = createSession(httpSession, request.getRemoteHost());
         }
 
         return session;

Added: incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/WebSessionKey.java
URL: http://svn.apache.org/viewvc/incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/WebSessionKey.java?rev=945994&view=auto
==============================================================================
--- incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/WebSessionKey.java (added)
+++ incubator/shiro/branches/session_manager_API_change/web/src/main/java/org/apache/shiro/web/session/WebSessionKey.java Wed May 19 01:47:43 2010
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Les Hazlewood
+ *
+ * Licensed 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.shiro.web.session;
+
+import org.apache.shiro.session.mgt.DefaultSessionKey;
+import org.apache.shiro.web.util.RequestPairSource;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.Serializable;
+
+/**
+ * A {@link org.apache.shiro.session.mgt.SessionKey SessionKey} implementation that also retains the
+ * {@code ServletRequest} and {@code ServletResponse} associated with the web request that is performing the
+ * session lookup.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public class WebSessionKey extends DefaultSessionKey implements RequestPairSource {
+
+    private final ServletRequest servletRequest;
+    private final ServletResponse servletResponse;
+
+    public WebSessionKey(ServletRequest request, ServletResponse response) {
+        if (request == null) {
+            throw new NullPointerException("request argument cannot be null.");
+        }
+        if (response == null) {
+            throw new NullPointerException("response argument cannot be null.");
+        }
+        this.servletRequest = request;
+        this.servletResponse = response;
+    }
+
+    public WebSessionKey(Serializable sessionId, ServletRequest request, ServletResponse response) {
+        this(request, response);
+        setSessionId(sessionId);
+    }
+
+    public ServletRequest getServletRequest() {
+        return servletRequest;
+    }
+
+    public ServletResponse getServletResponse() {
+        return servletResponse;
+    }
+}