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
+}