From b06c4a87b00d202448ceac256b168ce6a5885749 Mon Sep 17 00:00:00 2001 From: Kamil Date: Tue, 20 Aug 2024 23:19:16 +0200 Subject: [PATCH 1/2] #2988 Fixed active sessions load in loggedUsers bean when tomcat starts: - added methods: MangoContextListener.sessionsInitialize, LoggedUsers.loadSessions; - added Logger org.scada_lts.login in log4j2.xml; --- .../serotonin/mango/MangoContextListener.java | 37 +++++++++++++++++++ src/org/scada_lts/login/ILoggedUsers.java | 2 + src/org/scada_lts/login/LoggedUsers.java | 34 +++++++++++++++-- webapp-resources/log4j2.xml | 2 + 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/com/serotonin/mango/MangoContextListener.java b/src/com/serotonin/mango/MangoContextListener.java index fd44341f76..2cc950e038 100644 --- a/src/com/serotonin/mango/MangoContextListener.java +++ b/src/com/serotonin/mango/MangoContextListener.java @@ -55,6 +55,11 @@ import freemarker.cache.TemplateLoader; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; +import org.apache.catalina.Manager; +import org.apache.catalina.Session; +import org.apache.catalina.core.ApplicationContext; +import org.apache.catalina.core.ApplicationContextFacade; +import org.apache.catalina.core.StandardContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.mozilla.javascript.ContextFactory; @@ -76,6 +81,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -192,6 +198,8 @@ private void initialized(ServletContextEvent evt) { initSchedule(); + sessionsInitialize(evt); + log.info("Scada-LTS context started"); } @@ -682,4 +690,33 @@ private void initSchedule() { log.error(e.getMessage(), e); } } + + private void sessionsInitialize(ServletContextEvent evt) { + try { + Session[] sessions = getSessions(evt); + ApplicationBeans.getLoggedUsersBean().loadSessions(sessions); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + } + } + + private static Session[] getSessions(ServletContextEvent evt) throws NoSuchFieldException, IllegalAccessException { + Manager manager = getManager(evt); + return manager.findSessions(); + } + + private static Manager getManager(ServletContextEvent evt) throws NoSuchFieldException, IllegalAccessException { + ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade) evt.getServletContext(); + + Field applicationContextField = applicationContextFacade.getClass().getDeclaredField("context"); + applicationContextField.setAccessible(true); + ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(applicationContextFacade); + applicationContextField.setAccessible(false); + + Field standardContextField = applicationContext.getClass().getDeclaredField("context"); + standardContextField.setAccessible(true); + StandardContext standardContext = (StandardContext) standardContextField.get(applicationContext); + standardContextField.setAccessible(false); + return standardContext.getManager(); + } } diff --git a/src/org/scada_lts/login/ILoggedUsers.java b/src/org/scada_lts/login/ILoggedUsers.java index 1c548e63f3..07cdc391e9 100644 --- a/src/org/scada_lts/login/ILoggedUsers.java +++ b/src/org/scada_lts/login/ILoggedUsers.java @@ -2,6 +2,7 @@ import br.org.scadabr.vo.usersProfiles.UsersProfileVO; import com.serotonin.mango.vo.User; +import org.apache.catalina.Session; import javax.servlet.http.HttpSession; import java.util.Collection; @@ -15,4 +16,5 @@ public interface ILoggedUsers { Set getUserIds(); Collection getUsers(); User getUser(int id); + void loadSessions(Session[] sessions); } diff --git a/src/org/scada_lts/login/LoggedUsers.java b/src/org/scada_lts/login/LoggedUsers.java index 71b8913652..7d5f6f2a3e 100644 --- a/src/org/scada_lts/login/LoggedUsers.java +++ b/src/org/scada_lts/login/LoggedUsers.java @@ -3,9 +3,14 @@ import br.org.scadabr.vo.usersProfiles.UsersProfileVO; import com.serotonin.mango.util.LoggingUtils; import com.serotonin.mango.vo.User; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.apache.catalina.Session; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.scada_lts.mango.service.UserService; +import org.scada_lts.web.beans.ApplicationBeans; +import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContext; import javax.servlet.http.HttpSession; import java.util.*; @@ -17,7 +22,7 @@ public class LoggedUsers implements ILoggedUsers { - private static final Log LOG = LogFactory.getLog(LoggedUsers.class); + private static final Logger LOG = LogManager.getLogger(LoggedUsers.class); private final Map loggedUsers = new ConcurrentHashMap<>(); private final Map> loggedSessions = new ConcurrentHashMap<>(); @@ -111,6 +116,29 @@ public User getUser(int id) { } } + @Override + public void loadSessions(Session[] sessions) { + for(Session session: sessions) { + HttpSession httpSession = session.getSession(); + UserService userService = ApplicationBeans.getBean("userService", UserService.class); + SecurityContext securityContext = (SecurityContext)httpSession.getAttribute("SPRING_SECURITY_CONTEXT"); + if(securityContext != null) { + Authentication authentication = securityContext.getAuthentication(); + if(authentication != null) { + String username = authentication.getName(); + User sessionUser = userService.getUser(username); + if (sessionUser != null) { + int userId = sessionUser.getId(); + loggedSessions.putIfAbsent(userId, new ArrayList<>()); + loggedSessions.get(userId).add(httpSession); + loggedUsers.put(userId, sessionUser); + LOG.info("Loaded session for user: {}", username); + } + } + } + } + } + private static void update(User user, Map loggedUsers, Map> loggedSessions) { User loggedUser = loggedUsers.get(user.getId()); diff --git a/webapp-resources/log4j2.xml b/webapp-resources/log4j2.xml index 3def578e1d..1f094a18bf 100644 --- a/webapp-resources/log4j2.xml +++ b/webapp-resources/log4j2.xml @@ -155,6 +155,8 @@ + + From a0e635a1e6269888fe08882e0b39290d1a9ccfd5 Mon Sep 17 00:00:00 2001 From: Kamil Date: Wed, 21 Aug 2024 12:52:42 +0200 Subject: [PATCH 2/2] #2988 Fixed active sessions load in loggedUsers bean when tomcat starts: - user sessions initialize first; - check admin; --- src/com/serotonin/mango/MangoContextListener.java | 4 ++-- src/org/scada_lts/login/LoggedUsers.java | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/com/serotonin/mango/MangoContextListener.java b/src/com/serotonin/mango/MangoContextListener.java index 2cc950e038..48d8627c57 100644 --- a/src/com/serotonin/mango/MangoContextListener.java +++ b/src/com/serotonin/mango/MangoContextListener.java @@ -111,6 +111,8 @@ public void contextInitialized(ServletContextEvent evt) { private void initialized(ServletContextEvent evt) { log.info("Scada-LTS context starting at: " + Common.getStartupTime()); + sessionsInitialize(evt); + scriptContextInitialize(); // Get a handle on the context. @@ -198,8 +200,6 @@ private void initialized(ServletContextEvent evt) { initSchedule(); - sessionsInitialize(evt); - log.info("Scada-LTS context started"); } diff --git a/src/org/scada_lts/login/LoggedUsers.java b/src/org/scada_lts/login/LoggedUsers.java index 7d5f6f2a3e..c4dccddb07 100644 --- a/src/org/scada_lts/login/LoggedUsers.java +++ b/src/org/scada_lts/login/LoggedUsers.java @@ -127,7 +127,7 @@ public void loadSessions(Session[] sessions) { if(authentication != null) { String username = authentication.getName(); User sessionUser = userService.getUser(username); - if (sessionUser != null) { + if (sessionUser != null && (!sessionUser.isAdmin() || isAdmin(authentication))) { int userId = sessionUser.getId(); loggedSessions.putIfAbsent(userId, new ArrayList<>()); loggedSessions.get(userId).add(httpSession); @@ -155,4 +155,13 @@ private static void update(User user, Map loggedUsers, } loggedUsers.put(user.getId(), user); } + + private static boolean isAdmin(Authentication authentication) { + for(GrantedAuthority authority: authentication.getAuthorities()) { + if("ROLE_ADMIN".equals(authority.getAuthority())) { + return true; + } + } + return false; + } }