You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vk...@apache.org on 2016/06/15 09:58:45 UTC

ignite git commit: IGNITE-2344 - WebSessionFilter doesn't support session ID renewal. Fixes #780.

Repository: ignite
Updated Branches:
  refs/heads/master db4e936b1 -> b500d3a56


IGNITE-2344 - WebSessionFilter doesn't support session ID renewal. Fixes #780.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b500d3a5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b500d3a5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b500d3a5

Branch: refs/heads/master
Commit: b500d3a56b756b92ea0b3ab55795a9022cbc7430
Parents: db4e936
Author: samaitra <sa...@gmail.com>
Authored: Wed Jun 15 12:58:33 2016 +0300
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Jun 15 12:58:33 2016 +0300

----------------------------------------------------------------------
 .../cache/websession/WebSessionFilter.java      |  39 ++-
 .../internal/websession/WebSessionSelfTest.java | 330 ++++++++++++++++++-
 2 files changed, 357 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b500d3a5/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
----------------------------------------------------------------------
diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
index 70b6349..b24bc36 100644
--- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
+++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java
@@ -31,9 +31,8 @@ import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpSession;
+import javax.servlet.http.*;
+
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteClientDisconnectedException;
@@ -963,6 +962,22 @@ public class WebSessionFilter implements Filter {
 
             return newId;
         }
+
+        /** {@inheritDoc} */
+        @Override public void login(String username, String password) throws ServletException{
+            HttpServletRequest req = (HttpServletRequest)getRequest();
+
+            req.login(username, password);
+
+            String newId = req.getSession(false).getId();
+
+            this.ses.setId(newId);
+
+            this.ses = createSession(ses, newId);
+            this.ses.servletContext(ctx);
+            this.ses.filter(WebSessionFilter.this);
+            this.ses.resetUpdates();
+        }
     }
 
     /**
@@ -1026,5 +1041,23 @@ public class WebSessionFilter implements Filter {
 
             return newId;
         }
+
+        /** {@inheritDoc} */
+        @Override public void login(String username, String password) throws ServletException{
+            final HttpServletRequest req = (HttpServletRequest)getRequest();
+
+            req.login(username, password);
+
+            final String newId = req.getSession(false).getId();
+
+            if (!F.eq(newId, ses.getId())) {
+                try {
+                    ses = createSessionV2(ses, newId);
+                }
+                catch (IOException e) {
+                    throw new IgniteException(e);
+                }
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b500d3a5/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
index 1e01d3c..0ab1130 100644
--- a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
+++ b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java
@@ -17,16 +17,11 @@
 
 package org.apache.ignite.internal.websession;
 
-import java.io.BufferedReader;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Serializable;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
+import java.io.*;
+import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.Random;
+import java.util.*;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -51,6 +46,7 @@ import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.eclipse.jetty.security.HashLoginService;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
@@ -92,6 +88,13 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
+    public void testSessionRenewalDuringLogin() throws Exception {
+        testSessionRenewalDuringLogin("/modules/core/src/test/config/websession/example-cache.xml");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testSingleRequestMetaInf() throws Exception {
         testSingleRequest("ignite-webapp-config.xml");
     }
@@ -293,6 +296,171 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Tests session renewal during login. Checks modification attribute in cache.
+     *
+     * @param cfg Configuration.
+     * @throws Exception If failed.
+     */
+    private void testSessionRenewalDuringLogin(String cfg) throws Exception {
+        Server srv = null;
+        String sesId = null;
+        try {
+            srv = startServerWithLoginService(TEST_JETTY_PORT, cfg, null, new SessionLoginServlet());
+
+            URLConnection conn = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/test").openConnection();
+
+            conn.connect();
+
+            String sesIdCookie1 = getSessionIdFromCookie(conn);
+
+            X.println(">>>", "Initial session Cookie: " + sesIdCookie1, ">>>");
+
+            try (BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
+                sesId = rdr.readLine();
+
+                if (!keepBinary()) {
+                    IgniteCache<String, HttpSession> cache = G.ignite().cache(getCacheName());
+
+                    assertNotNull(cache);
+
+                    HttpSession ses = cache.get(sesId);
+
+                    assertNotNull(ses);
+
+                    assertEquals("val1", ses.getAttribute("key1"));
+                }
+                else {
+                    final IgniteCache<String, WebSessionEntity> cache = G.ignite().cache(getCacheName());
+
+                    assertNotNull(cache);
+
+                    final WebSessionEntity entity = cache.get(sesId);
+
+                    assertNotNull(entity);
+
+                    final byte[] data = entity.attributes().get("key1");
+
+                    assertNotNull(data);
+
+                    final Marshaller marshaller = G.ignite().configuration().getMarshaller();
+
+                    final String val = marshaller.unmarshal(data, getClass().getClassLoader());
+
+                    assertEquals("val1", val);
+                }
+            }
+
+            URLConnection conn2 = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/login").openConnection();
+
+            HttpURLConnection con = (HttpURLConnection) conn2;
+
+            con.addRequestProperty("Cookie", "JSESSIONID=" + sesIdCookie1);
+
+            con.setRequestMethod("POST");
+
+            con.setDoOutput(true);
+
+            String sesIdCookie2 = getSessionIdFromCookie(con);
+
+            X.println(">>>", "Logged In session Cookie: " + sesIdCookie2, ">>>");
+
+            try (BufferedReader rdr = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
+                String sesId2 = rdr.readLine();
+
+                if (!keepBinary()) {
+                    IgniteCache<String, HttpSession> cache = G.ignite().cache(getCacheName());
+
+                    assertNotNull(cache);
+
+                    HttpSession ses = cache.get(sesId2);
+
+                    assertNotNull(ses);
+
+                    assertEquals("val1", ses.getAttribute("key1"));
+
+                }
+                else {
+                    final IgniteCache<String, WebSessionEntity> cache = G.ignite().cache(getCacheName());
+
+                    assertNotNull(cache);
+
+                    final WebSessionEntity entity = cache.get(sesId2);
+
+                    assertNotNull(entity);
+
+                    final byte[] data = entity.attributes().get("key1");
+
+                    assertNotNull(data);
+
+                    final Marshaller marshaller = G.ignite().configuration().getMarshaller();
+
+                    final String val = marshaller.unmarshal(data, getClass().getClassLoader());
+
+                    assertEquals("val1", val);
+
+                }
+
+            }
+
+            URLConnection conn3 = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/simple").openConnection();
+
+            conn3.addRequestProperty("Cookie", "JSESSIONID=" + sesIdCookie2);
+
+            conn3.connect();
+
+            String sesIdCookie3 = getSessionIdFromCookie(conn3);
+
+            X.println(">>>", "Post Logged In session Cookie: " + sesIdCookie3, ">>>");
+
+            assertEquals(sesIdCookie2, sesIdCookie3);
+
+            try (BufferedReader rdr = new BufferedReader(new InputStreamReader(conn3.getInputStream()))) {
+                String sesId3 = rdr.readLine();
+
+                if (!keepBinary()) {
+                    IgniteCache<String, HttpSession> cache = G.ignite().cache(getCacheName());
+
+                    HttpSession session = cache.get(sesId3);
+
+                    assertNotNull(session);
+
+                    assertNotNull(cache);
+
+                    HttpSession ses = cache.get(sesId3);
+
+                    assertNotNull(ses);
+
+                    assertEquals("val1", ses.getAttribute("key1"));
+                }
+                else {
+                    final IgniteCache<String, WebSessionEntity> cache = G.ignite().cache(getCacheName());
+
+                    assertNotNull(cache);
+
+                    final WebSessionEntity entity = cache.get(sesId3);
+
+                    assertNotNull(entity);
+
+                    assertNotNull(cache.get(sesId3));
+
+                    final byte[] data = entity.attributes().get("key1");
+
+                    assertNotNull(data);
+
+                    final Marshaller marshaller = G.ignite().configuration().getMarshaller();
+
+                    final String val = marshaller.unmarshal(data, getClass().getClassLoader());
+
+                    assertEquals("val1", val);
+                }
+            }
+        }
+        finally {
+            stopServerWithLoginService(srv);
+        }
+    }
+
+    /**
      * Tests invalidated sessions.
      *
      * @throws Exception Exception If failed.
@@ -668,6 +836,35 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Starts server with Login Service and create a realm file.
+     *
+     * @param port Port number.
+     * @param cfg Configuration.
+     * @param gridName Grid name.
+     * @param servlet Servlet.
+     * @return Server.
+     * @throws Exception In case of error.
+     */
+    private Server startServerWithLoginService(int port, @Nullable String cfg, @Nullable String gridName, HttpServlet servlet)
+            throws Exception {
+        Server srv = new Server(port);
+
+        WebAppContext ctx = getWebContext(cfg, gridName, keepBinary(), servlet);
+
+        HashLoginService hashLoginService = new HashLoginService();
+        hashLoginService.setName("Test Realm");
+        createRealm();
+        hashLoginService.setConfig("realm.properties");
+        ctx.getSecurityHandler().setLoginService(hashLoginService);
+
+        srv.setHandler(ctx);
+
+        srv.start();
+
+        return srv;
+    }
+
+    /**
      * Stops server.
      *
      * @param srv Server.
@@ -679,6 +876,60 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Stops server and delete realm file.
+     *
+     * @param srv Server.
+     * @throws Exception In case of error.
+     */
+    private void stopServerWithLoginService(@Nullable Server srv) throws Exception{
+        if (srv != null){
+            srv.stop();
+            File realmFile = new File("realm.properties");
+            realmFile.delete();
+        }
+    }
+
+    /** Creates a realm file to store test user credentials */
+    private void createRealm() throws Exception{
+        File realmFile = new File("realm.properties");
+        FileWriter fileWriter = new FileWriter(realmFile);
+        fileWriter.append("admin:admin");
+        fileWriter.flush();
+        fileWriter.close();
+    }
+
+    /**
+     * Retrieves HttpSession sessionId from Cookie
+     *
+     * @param conn URLConnection
+     * @return sesId
+     */
+    private String getSessionIdFromCookie(URLConnection conn) {
+        String sessionCookieValue = null;
+        String sesId = null;
+        Map<String, List<String>> headerFields = conn.getHeaderFields();
+        Set<String> headerFieldsSet = headerFields.keySet();
+        Iterator<String> hearerFieldsIter = headerFieldsSet.iterator();
+
+        while (hearerFieldsIter.hasNext()) {
+            String headerFieldKey = hearerFieldsIter.next();
+
+            if ("Set-Cookie".equalsIgnoreCase(headerFieldKey)) {
+                List<String> headerFieldValue = headerFields.get(headerFieldKey);
+
+                for (String headerValue : headerFieldValue) {
+                    String[] fields = headerValue.split(";");
+                    sessionCookieValue = fields[0];
+                    sesId = sessionCookieValue.substring(sessionCookieValue.indexOf("=")+1,
+                            sessionCookieValue.length());
+                }
+            }
+        }
+
+        return sesId;
+    }
+
+    /**
      * Test servlet.
      */
     private static class SessionCreateServlet extends HttpServlet {
@@ -831,6 +1082,67 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test session behavior on id change.
+     */
+    private static class SessionLoginServlet extends HttpServlet {
+        /** {@inheritDoc} */
+        @Override protected void doGet(HttpServletRequest req, HttpServletResponse res)
+                throws ServletException, IOException {
+
+            if (req.getPathInfo().equals("/test")) {
+                HttpSession ses = req.getSession(true);
+                assertNotNull(ses);
+                ses.setAttribute("checkCnt", 0);
+                ses.setAttribute("key1", "val1");
+                ses.setAttribute("key2", "val2");
+                ses.setAttribute("mkey", new TestObj());
+
+                Profile p = (Profile) ses.getAttribute("profile");
+
+                if (p == null) {
+                    p = new Profile();
+                    ses.setAttribute("profile", p);
+                }
+
+                p.setMarker(req.getParameter("marker"));
+
+                X.println(">>>", "Request session test: " + ses.getId(), ">>>");
+
+                res.getWriter().write(ses.getId());
+
+                res.getWriter().flush();
+
+            } else if (req.getPathInfo().equals("/simple")) {
+                HttpSession session = req.getSession();
+                X.println(">>>", "Request session simple: " + session.getId(), ">>>");
+
+                res.getWriter().write(session.getId());
+
+                res.getWriter().flush();
+            }
+        }
+        /** {@inheritDoc} */
+        @Override protected void doPost(HttpServletRequest req, HttpServletResponse res)
+                throws ServletException, IOException {
+            if (req.getPathInfo().equals("/login")) {
+                try {
+                    req.login("admin", "admin");
+                } catch (Exception e) {
+                    X.printerrln("Login failed.");
+                }
+
+                HttpSession session = req.getSession();
+
+                X.println(">>>", "Logged In session: " + session.getId(), ">>>");
+
+                res.getWriter().write(session.getId());
+
+                res.getWriter().flush();
+            }
+        }
+    }
+
+    /**
      * Servlet for restarts test.
      */
     private static class RestartsTestServlet extends HttpServlet {
@@ -932,4 +1244,4 @@ public class WebSessionSelfTest extends GridCommonAbstractTest {
             return result;
         }
     }
-}
\ No newline at end of file
+}