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 2013/04/17 05:20:44 UTC

svn commit: r1468734 - in /shiro/branches/1.2.x/web/src: main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java test/groovy/org/apache/shiro/web/session/mgt/DefaultWebSessionManagerTest.groovy test/java/org/apache/shiro/web/session/

Author: lhazlewood
Date: Wed Apr 17 03:20:42 2013
New Revision: 1468734

URL: http://svn.apache.org/r1468734
Log:
SHIRO-351: added URI Path Segment Parameter parsing (with tests at 100% coverage).

Added:
    shiro/branches/1.2.x/web/src/test/groovy/org/apache/shiro/web/session/mgt/DefaultWebSessionManagerTest.groovy
Removed:
    shiro/branches/1.2.x/web/src/test/java/org/apache/shiro/web/session/
Modified:
    shiro/branches/1.2.x/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java

Modified: shiro/branches/1.2.x/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java
URL: http://svn.apache.org/viewvc/shiro/branches/1.2.x/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java?rev=1468734&r1=1468733&r2=1468734&view=diff
==============================================================================
--- shiro/branches/1.2.x/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java (original)
+++ shiro/branches/1.2.x/web/src/main/java/org/apache/shiro/web/session/mgt/DefaultWebSessionManager.java Wed Apr 17 03:20:42 2013
@@ -25,7 +25,6 @@ import org.apache.shiro.session.mgt.Defa
 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.util.StringUtils;
 import org.apache.shiro.web.servlet.Cookie;
 import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
 import org.apache.shiro.web.servlet.ShiroHttpSession;
@@ -115,12 +114,19 @@ public class DefaultWebSessionManager ex
             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):
-            String name = getSessionIdName();
-            id = request.getParameter(name);
+            //not in a cookie, or cookie is disabled - try the request URI as a fallback (i.e. due to URL rewriting):
+
+            //try the URI path segment parameters first:
+            id = getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
+
             if (id == null) {
-                //try lowercase:
-                id = request.getParameter(name.toLowerCase());
+                //not a URI path segment parameter, try the query parameters:
+                String name = getSessionIdName();
+                id = request.getParameter(name);
+                if (id == null) {
+                    //try lowercase:
+                    id = request.getParameter(name.toLowerCase());
+                }
             }
             if (id != null) {
                 request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
@@ -136,6 +142,54 @@ public class DefaultWebSessionManager ex
         return id;
     }
 
+    //SHIRO-351
+    //also see http://cdivilly.wordpress.com/2011/04/22/java-servlets-uri-parameters/
+    //since 1.2.2
+    private String getUriPathSegmentParamValue(ServletRequest servletRequest, String paramName) {
+
+        if (!(servletRequest instanceof HttpServletRequest)) {
+            return null;
+        }
+        HttpServletRequest request = (HttpServletRequest)servletRequest;
+        String uri = request.getRequestURI();
+        if (uri == null) {
+            return null;
+        }
+
+        int queryStartIndex = uri.indexOf('?');
+        if (queryStartIndex >= 0) { //get rid of the query string
+            uri = uri.substring(0, queryStartIndex);
+        }
+
+        int index = uri.indexOf(';'); //now check for path segment parameters:
+        if (index < 0) {
+            //no path segment params - return:
+            return null;
+        }
+
+        //there are path segment params, let's get the last one that may exist:
+
+        final String TOKEN = paramName + "=";
+
+        uri = uri.substring(index+1); //uri now contains only the path segment params
+
+        //we only care about the last JSESSIONID param:
+        index = uri.lastIndexOf(TOKEN);
+        if (index < 0) {
+            //no segment param:
+            return null;
+        }
+
+        uri = uri.substring(index + TOKEN.length());
+
+        index = uri.indexOf(';'); //strip off any remaining segment params:
+        if(index >= 0) {
+            uri = uri.substring(0, index);
+        }
+
+        return uri; //what remains is the value
+    }
+
     //since 1.2.1
     private String getSessionIdName() {
         String name = this.sessionIdCookie != null ? this.sessionIdCookie.getName() : null;

Added: shiro/branches/1.2.x/web/src/test/groovy/org/apache/shiro/web/session/mgt/DefaultWebSessionManagerTest.groovy
URL: http://svn.apache.org/viewvc/shiro/branches/1.2.x/web/src/test/groovy/org/apache/shiro/web/session/mgt/DefaultWebSessionManagerTest.groovy?rev=1468734&view=auto
==============================================================================
--- shiro/branches/1.2.x/web/src/test/groovy/org/apache/shiro/web/session/mgt/DefaultWebSessionManagerTest.groovy (added)
+++ shiro/branches/1.2.x/web/src/test/groovy/org/apache/shiro/web/session/mgt/DefaultWebSessionManagerTest.groovy Wed Apr 17 03:20:42 2013
@@ -0,0 +1,316 @@
+/*
+ * 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.mgt
+
+import org.apache.shiro.session.mgt.SimpleSession
+import org.apache.shiro.util.ThreadContext
+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.Before
+import org.junit.Test
+
+import javax.servlet.ServletRequest
+import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpServletResponse
+
+import static org.easymock.EasyMock.*
+import static org.junit.Assert.*
+
+/**
+ * Test cases for the {@link DefaultWebSessionManager} implementation.
+ *
+ * @since 1.0
+ */
+public class DefaultWebSessionManagerTest {
+
+
+    DefaultWebSessionManager mgr;
+
+    @Before
+    void setUp() {
+        this.mgr = new DefaultWebSessionManager()
+    }
+
+    @After
+    public void clearThread() {
+        ThreadContext.remove();
+    }
+
+    @Test
+    public void testOnStart() {
+        Cookie cookie = createMock(Cookie.class);
+        mgr.setSessionIdCookie(cookie);
+
+        SimpleSession session = new SimpleSession();
+        session.setId("12345");
+
+        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");
+        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);
+        expect(cookie.isHttpOnly()).andReturn(true);
+
+        replay(cookie);
+
+        mgr.onStart(session, wsc);
+
+        verify(cookie);
+    }
+
+    @Test
+    public void testOnStartWithSessionIdCookieDisabled() {
+
+        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");
+
+        WebSessionContext wsc = new DefaultWebSessionContext();
+        wsc.setServletRequest(createMock(HttpServletRequest.class));
+        wsc.setServletResponse(createMock(HttpServletResponse.class));
+
+        replay(cookie);
+
+        mgr.onStart(session, wsc);
+
+        verify(cookie);
+    }
+
+    @Test
+    public void testGetSessionIdWithSessionIdCookieEnabled() {
+        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() {
+
+        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(cookie.getName()).andReturn(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
+        expect(request.getRequestURI()).andReturn("/foo/bar?JSESSIONID=$id" as String)
+        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() {
+
+        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(cookie.getName()).andReturn(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
+        expect(request.getRequestURI()).andReturn("/foo/bar?JSESSIONID=$id" as String)
+        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);
+    }
+
+    //SHIRO-351:
+    //since 1.2.2
+    @Test
+    public void testGetSessionIdFromRequestUriPathSegmentParam() {
+
+        mgr.setSessionIdCookieEnabled(false);
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+
+        String id = "12345";
+
+        expect(request.getRequestURI()).andReturn("/foo/bar.html;JSESSIONID=$id;key2=value2?key3=value3" as String)
+
+        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(request);
+        replay(response);
+
+        Serializable sessionId = mgr.getSessionId(request, response);
+        assertEquals(sessionId, id);
+
+        verify(request);
+        verify(response);
+    }
+
+    //SHIRO-351:
+    //since 1.2.2
+    @Test
+    void testSessionIDRequestPathParameterWithNonHttpRequest() {
+
+        def request = createMock(ServletRequest)
+
+        replay request
+
+        assertNull mgr.getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
+
+        verify request
+    }
+
+    //SHIRO-351:
+    //since 1.2.2
+    @Test
+    void testSessionIDRequestPathParameterWithoutARequestURI() {
+
+        def request = createMock(HttpServletRequest)
+
+        expect(request.getRequestURI()).andReturn null
+        replay request
+
+        assertNull mgr.getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
+
+        verify request
+    }
+
+    //SHIRO-351:
+    //since 1.2.2
+    @Test
+    void testSessionIDRequestPathParameterWithoutPathParameters() {
+
+        def request = createMock(HttpServletRequest)
+
+        expect(request.getRequestURI()).andReturn '/foo/bar/baz.html'
+        replay request
+
+        assertNull mgr.getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
+
+        verify request
+    }
+
+    //SHIRO-351:
+    //since 1.2.2
+    @Test
+    void testSessionIDRequestPathParameterWithoutJSESSIONID() {
+
+        def request = createMock(HttpServletRequest)
+
+        expect(request.getRequestURI()).andReturn '/foo/bar;key1=key2;a/b/c;blah'
+        replay request
+
+        assertNull mgr.getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
+
+        verify request
+    }
+
+    //SHIRO-351:
+    //since 1.2.2
+    @Test
+    void testSessionIDRequestPathParameter() {
+
+        def request = createMock(HttpServletRequest)
+
+        def id = 'baz'
+        def path = "/foo/bar;key1=value1;key3,key4,key5;JSESSIONID=$id;key6=value6?key7=value7&key8=value8"
+
+        expect(request.getRequestURI()).andReturn(path.toString())
+        replay request
+
+        String found = mgr.getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME)
+
+        assertEquals id, found
+
+        verify request
+    }
+}