From 8b792575a66b16f55cf3e9c4eb2d24e735d97877 Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Tue, 9 Nov 2021 18:43:48 +0300 Subject: [PATCH] CB-1345 SAML session management fix --- .../src/io/cloudbeaver/WebServiceUtils.java | 21 +++++++++++++++++++ .../cloudbeaver/model/session/WebSession.java | 17 ++++++--------- .../model/session/WebSessionManager.java | 12 +++++++++++ .../server/jetty/CBJettyServer.java | 13 +++++++++++- .../server/jetty/CBServerContextListener.java | 8 ++++--- 5 files changed, 56 insertions(+), 15 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java index e01c549634..fdfe3fa9ce 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -52,6 +52,9 @@ import org.jkiss.dbeaver.runtime.properties.ObjectPropertyDescriptor; import org.jkiss.dbeaver.runtime.properties.PropertyCollector; import org.jkiss.utils.CommonUtils; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.util.Arrays; import java.util.LinkedHashMap; @@ -344,4 +347,22 @@ public class WebServiceUtils { }); } } + + public static void addResponseCookie(HttpServletResponse response, String cookieName, String cookieValue, long maxSessionIdleTime) { + Cookie sessionCookie = new Cookie(cookieName, cookieValue); + if (maxSessionIdleTime > 0) { + sessionCookie.setMaxAge((int) (maxSessionIdleTime / 1000)); + } + sessionCookie.setPath(CBApplication.getInstance().getRootURI()); + response.addCookie(sessionCookie); + } + + public static String getRequestCookie(HttpServletRequest request, String cookieName) { + for (Cookie cookie : request.getCookies()) { + if (cookie.getName().equals(cookieName)) { + return cookie.getValue(); + } + } + return null; + } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSession.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSession.java index 16db1c03b9..cfc3fa35e3 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSession.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSession.java @@ -58,7 +58,6 @@ import org.jkiss.dbeaver.registry.ProjectMetadata; import org.jkiss.dbeaver.runtime.jobs.DisconnectJob; import org.jkiss.utils.CommonUtils; -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -447,17 +446,13 @@ public class WebSession implements DBASession, DBAAuthCredentialsProvider, IAdap log.error("Error persisting web session", e); } } - { - long maxSessionIdleTime = CBApplication.getInstance().getMaxSessionIdleTime(); - SimpleDateFormat sdf = new SimpleDateFormat(DBConstants.DEFAULT_ISO_TIMESTAMP_FORMAT); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - Cookie sessionCookie = new Cookie(SESSION_TEMP_COOKIE, sdf.format(new Date(System.currentTimeMillis() + maxSessionIdleTime))); - sessionCookie.setMaxAge((int) (maxSessionIdleTime / 1000)); - sessionCookie.setPath(CBApplication.getInstance().getRootURI()); - //sessionCookie.setComment("CB session cookie"); - response.addCookie(sessionCookie); - } + long maxSessionIdleTime = CBApplication.getInstance().getMaxSessionIdleTime(); + SimpleDateFormat sdf = new SimpleDateFormat(DBConstants.DEFAULT_ISO_TIMESTAMP_FORMAT); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + String cookieValue = sdf.format(new Date(System.currentTimeMillis() + maxSessionIdleTime)); + WebServiceUtils.addResponseCookie( + response, SESSION_TEMP_COOKIE, cookieValue, maxSessionIdleTime); } @Association diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSessionManager.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSessionManager.java index 2e9ffcd01f..ebf5cb0c38 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSessionManager.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/session/WebSessionManager.java @@ -20,6 +20,7 @@ import io.cloudbeaver.DBWebException; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.utils.CommonUtils; @@ -72,14 +73,17 @@ public class WebSessionManager { return true; } + @NotNull public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException { return getWebSession(request, response, true); } + @NotNull public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, boolean errorOnNoFound) throws DBWebException { return getWebSession(request, response, true, errorOnNoFound); } + @NotNull public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, boolean updateInfo, boolean errorOnNoFound) throws DBWebException { HttpSession httpSession = request.getSession(true); String sessionId = httpSession.getId(); @@ -113,6 +117,14 @@ public class WebSessionManager { return webSession; } + @Nullable + public WebSession getWebSession(@NotNull String sessionId) { + synchronized (sessionMap) { + return sessionMap.get(sessionId); + } + } + + @Nullable public WebSession findWebSession(HttpServletRequest request) { String sessionId = request.getSession().getId(); synchronized (sessionMap) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java index 9d8b539b07..20d578202a 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBJettyServer.java @@ -101,7 +101,18 @@ public class CBJettyServer { } } - SessionHandler sessionHandler = new SessionHandler(); + SessionHandler sessionHandler = new SessionHandler()/* { + public HttpCookie access(HttpSession session, boolean secure) { + HttpCookie cookie = getSessionCookie(session, _context == null ? "/" : (_context.getContextPath()), secure); + return cookie; + } + + @Override + public int getRefreshCookieAge() { + // Refresh cookie always (we need it for FA requests) + return 1; + } + }*/; DefaultSessionCache sessionCache = new DefaultSessionCache(sessionHandler); FileSessionDataStore sessionStore = new FileSessionDataStore(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBServerContextListener.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBServerContextListener.java index 51f1154a70..41c5695a68 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBServerContextListener.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBServerContextListener.java @@ -24,7 +24,9 @@ import javax.servlet.SessionCookieConfig; public class CBServerContextListener implements ServletContextListener { - public static final String DBEAVER_SESSION_COOKIE_NAME = "DBEAVER_SESSION_ID"; + public static final String CB_SESSION_COOKIE_NAME = "cb-session-id"; + // One week + //private static final int CB_SESSION_LIFE_TIME = 60 * 60 * 24 * 7; public void contextInitialized(ServletContextEvent sce) { SessionCookieConfig scf = sce.getServletContext().getSessionCookieConfig(); @@ -32,10 +34,10 @@ public class CBServerContextListener implements ServletContextListener { scf.setComment("Cloudbeaver Session ID"); //scf.setDomain(domain); //scf.setHttpOnly(httpOnly); - //scf.setMaxAge(maxAge); + //scf.setMaxAge(CB_SESSION_LIFE_TIME); scf.setPath(CBApplication.getInstance().getRootURI()); //scf.setSecure(isSecure); - scf.setName(DBEAVER_SESSION_COOKIE_NAME); + scf.setName(CB_SESSION_COOKIE_NAME); } public void contextDestroyed(ServletContextEvent sce) {