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/10 02:25:34 UTC

svn commit: r942634 - in /incubator/shiro/trunk: core/src/test/java/org/apache/shiro/authc/support/ web/src/main/java/org/apache/shiro/web/session/ web/src/test/java/org/apache/shiro/web/session/

Author: lhazlewood
Date: Mon May 10 00:25:33 2010
New Revision: 942634

URL: http://svn.apache.org/viewvc?rev=942634&view=rev
Log:
SHIRO-83 - Made sessionId cookie optional for native session mode.  Added DefaultWebSessionManagerTest class for test case verification.  Also removed an empty package.

Added:
    incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/
    incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java
Removed:
    incubator/shiro/trunk/core/src/test/java/org/apache/shiro/authc/support/
Modified:
    incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java

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=942634&r1=942633&r2=942634&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 Mon May 10 00:25:33 2010
@@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
 import java.io.Serializable;
 
 
@@ -46,32 +47,50 @@ public class DefaultWebSessionManager ex
     private static final Logger log = LoggerFactory.getLogger(DefaultWebSessionManager.class);
 
     private Cookie sessionIdCookie;
+    private boolean sessionIdCookieEnabled;
 
     public DefaultWebSessionManager() {
         this.sessionIdCookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
         this.sessionIdCookie.setPath(Cookie.ROOT_PATH);
+        this.sessionIdCookieEnabled = true;
     }
 
     public Cookie getSessionIdCookie() {
         return sessionIdCookie;
     }
 
+    @SuppressWarnings({"UnusedDeclaration"})
     public void setSessionIdCookie(Cookie sessionIdCookie) {
         this.sessionIdCookie = sessionIdCookie;
     }
 
-    protected void storeSessionId(Serializable currentId, ServletRequest request, ServletResponse response) {
+    public boolean isSessionIdCookieEnabled() {
+        return sessionIdCookieEnabled;
+    }
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public void setSessionIdCookieEnabled(boolean sessionIdCookieEnabled) {
+        this.sessionIdCookieEnabled = sessionIdCookieEnabled;
+    }
+
+    private void storeSessionId(Serializable currentId, ServletRequest request, ServletResponse 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);
-        cookie.setValue(currentId.toString());
+        String idString = currentId.toString();
+        cookie.setValue(idString);
         cookie.saveTo(WebUtils.toHttp(request), WebUtils.toHttp(response));
+        log.trace("Set session ID cookie for session with id {}", idString);
     }
 
-    private void markSessionIdValid(Serializable sessionId, ServletRequest request) {
+    private void markSessionIdValid(ServletRequest request) {
         request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
     }
 
@@ -83,13 +102,32 @@ public class DefaultWebSessionManager ex
         getSessionIdCookie().removeFrom(WebUtils.toHttp(request), WebUtils.toHttp(response));
     }
 
-    protected Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) {
-        String id = getSessionIdCookie().readValue(WebUtils.toHttp(request), WebUtils.toHttp(response));
+    private String getSessionIdCookieValue(ServletRequest request, ServletResponse response) {
+        if (!isSessionIdCookieEnabled()) {
+            log.debug("Session ID cookie is disabled - session id will not be acquired from a request cookie.");
+            return null;
+        }
+        if (!(request instanceof HttpServletRequest)) {
+            log.debug("Current request is not an HttpServletRequest - cannot get session ID cookie.  Returning null.");
+            return null;
+        }
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+        return getSessionIdCookie().readValue(httpRequest, WebUtils.toHttp(response));
+    }
+
+    private Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) {
+
+        String id = getSessionIdCookieValue(request, response);
         if (id != null) {
             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
                     ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
         } else {
+            //not in a cookie, or cookie is disabled - try the request params as a fallback (i.e. URL rewriting):
             id = request.getParameter(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
+            if (id == null) {
+                //try lowercase:
+                id = request.getParameter(ShiroHttpSession.DEFAULT_SESSION_ID_NAME.toLowerCase());
+            }
             if (id != null) {
                 request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
                         ShiroHttpServletRequest.URL_SESSION_ID_SOURCE);
@@ -99,7 +137,7 @@ 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(id, request);
+            markSessionIdValid(request);
         }
         return id;
     }
@@ -111,10 +149,22 @@ public class DefaultWebSessionManager ex
      */
     @Override
     protected void onStart(Session session) {
-        ServletRequest request = WebUtils.getRequiredServletRequest();
-        ServletResponse response = WebUtils.getRequiredServletResponse();
-        Serializable sessionId = session.getId();
-        storeSessionId(sessionId, request, response);
+        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.");
+            return;
+        }
+        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());
+        }
+
         request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
         request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
     }
@@ -125,7 +175,10 @@ public class DefaultWebSessionManager ex
 
     @Override
     public void onUnknownSession(Serializable sessionId) {
-        markSessionIdInvalid(WebUtils.getRequiredServletRequest());
+        ServletRequest request = WebUtils.getServletRequest();
+        if (request != null) {
+            markSessionIdInvalid(request);
+        }
         removeSessionIdCookie();
     }
 
@@ -139,9 +192,14 @@ public class DefaultWebSessionManager ex
         removeSessionIdCookie();
     }
 
-    protected void removeSessionIdCookie() {
-        ServletRequest request = WebUtils.getRequiredServletRequest();
-        ServletResponse response = WebUtils.getRequiredServletResponse();
+    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;
+        }
         removeSessionIdCookie(request, response);
     }
 }

Added: 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=942634&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java (added)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/session/DefaultWebSessionManagerTest.java Mon May 10 00:25:33 2010
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.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;
+import org.apache.shiro.web.servlet.SimpleCookie;
+import org.junit.After;
+import org.junit.Test;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Serializable;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test cases for the {@link DefaultWebSessionManager} implementation.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public class DefaultWebSessionManagerTest {
+
+    @After
+    public void clearThread() {
+        ThreadContext.clear();
+    }
+
+    @Test
+    public void testOnStart() {
+        DefaultWebSessionManager mgr = new DefaultWebSessionManager();
+        Cookie cookie = createMock(Cookie.class);
+        mgr.setSessionIdCookie(cookie);
+
+        SimpleSession session = new SimpleSession();
+        session.setId("12345");
+
+        WebUtils.bind(createMock(HttpServletRequest.class));
+        WebUtils.bind(createMock(HttpServletResponse.class));
+
+        //test that the cookie template is being used:
+        expect(cookie.getValue()).andReturn("blah");
+        expect(cookie.getComment()).andReturn("comment");
+        expect(cookie.getDomain()).andReturn("domain");
+        expect(cookie.getMaxAge()).andReturn(SimpleCookie.DEFAULT_MAX_AGE);
+        expect(cookie.getName()).andReturn(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
+        expect(cookie.getPath()).andReturn("/");
+        expect(cookie.getVersion()).andReturn(SimpleCookie.DEFAULT_VERSION);
+        expect(cookie.isSecure()).andReturn(true);
+
+        replay(cookie);
+
+        mgr.onStart(session);
+
+        verify(cookie);
+    }
+
+    @Test
+    public void testOnStartWithSessionIdCookieDisabled() {
+
+        DefaultWebSessionManager mgr = new DefaultWebSessionManager();
+        Cookie cookie = createMock(Cookie.class);
+        mgr.setSessionIdCookie(cookie);
+        mgr.setSessionIdCookieEnabled(false);
+
+        //we should not have any reads from the cookie fields - if we do, this test case will fail.
+
+        SimpleSession session = new SimpleSession();
+        session.setId("12345");
+
+        WebUtils.bind(createMock(HttpServletRequest.class));
+        WebUtils.bind(createMock(HttpServletResponse.class));
+
+        replay(cookie);
+
+        mgr.onStart(session);
+
+        verify(cookie);
+    }
+
+    @Test
+    public void testGetSessionIdWithSessionIdCookieEnabled() {
+        DefaultWebSessionManager mgr = new DefaultWebSessionManager();
+        Cookie cookie = createMock(Cookie.class);
+        mgr.setSessionIdCookie(cookie);
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+
+        String id = "12345";
+
+        expect(cookie.readValue(request, response)).andReturn(id);
+
+        //expect that state attributes are set correctly
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
+                ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
+
+        replay(cookie);
+        replay(request);
+        replay(response);
+
+        Serializable sessionId = mgr.getSessionId(request, response);
+        assertEquals(sessionId, id);
+
+        verify(cookie);
+        verify(request);
+        verify(response);
+    }
+
+    @Test
+    public void testGetSessionIdWithSessionIdCookieDisabled() {
+
+        DefaultWebSessionManager mgr = new DefaultWebSessionManager();
+        Cookie cookie = createMock(Cookie.class);
+        mgr.setSessionIdCookie(cookie);
+        mgr.setSessionIdCookieEnabled(false);
+
+        //we should not have any reads from the cookie fields - if we do, this test case will fail.
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+
+        String id = "12345";
+
+        expect(request.getParameter(ShiroHttpSession.DEFAULT_SESSION_ID_NAME)).andReturn(id);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
+                ShiroHttpServletRequest.URL_SESSION_ID_SOURCE);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
+
+        replay(cookie);
+        replay(request);
+        replay(response);
+
+        Serializable sessionId = mgr.getSessionId(request, response);
+        assertEquals(sessionId, id);
+
+        verify(cookie);
+        verify(request);
+        verify(response);
+    }
+
+    @Test
+    public void testGetSessionIdWithSessionIdCookieDisabledAndLowercaseRequestParam() {
+
+        DefaultWebSessionManager mgr = new DefaultWebSessionManager();
+        Cookie cookie = createMock(Cookie.class);
+        mgr.setSessionIdCookie(cookie);
+        mgr.setSessionIdCookieEnabled(false);
+
+        //we should not have any reads from the cookie fields - if we do, this test case will fail.
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+
+        String id = "12345";
+
+        expect(request.getParameter(ShiroHttpSession.DEFAULT_SESSION_ID_NAME)).andReturn(null);
+        expect(request.getParameter(ShiroHttpSession.DEFAULT_SESSION_ID_NAME.toLowerCase())).andReturn(id);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
+                ShiroHttpServletRequest.URL_SESSION_ID_SOURCE);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
+        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
+
+        replay(cookie);
+        replay(request);
+        replay(response);
+
+        Serializable sessionId = mgr.getSessionId(request, response);
+        assertEquals(sessionId, id);
+
+        verify(cookie);
+        verify(request);
+        verify(response);
+    }
+}