From 4f0d6c3422011370cfcab6b31847342949f5dc85 Mon Sep 17 00:00:00 2001 From: Heiky Date: Thu, 17 Dec 2020 17:27:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9SysUser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listenerr/SecuritySessionListener.java | 29 ++++++++++ .../web/session/HttpSessionContext.java | 53 +++++++++++++++++++ .../web/session/HttpSessionContextHolder.java | 14 +++++ .../com/pearadmin/system/domain/SysUser.java | 2 + 4 files changed, 98 insertions(+) create mode 100644 pear-common/src/main/java/com/pearadmin/common/web/listenerr/SecuritySessionListener.java create mode 100644 pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContext.java create mode 100644 pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContextHolder.java diff --git a/pear-common/src/main/java/com/pearadmin/common/web/listenerr/SecuritySessionListener.java b/pear-common/src/main/java/com/pearadmin/common/web/listenerr/SecuritySessionListener.java new file mode 100644 index 00000000..508caf49 --- /dev/null +++ b/pear-common/src/main/java/com/pearadmin/common/web/listenerr/SecuritySessionListener.java @@ -0,0 +1,29 @@ +package com.pearadmin.common.web.listenerr; + +import com.pearadmin.common.web.session.HttpSessionContext; + +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +/** + * @Author: Heiky + * @Date: 2020/12/17 17:42 + * @Description: + */ + +@WebListener("自定义HttpSession监听器") +public class SecuritySessionListener implements HttpSessionListener { + + private HttpSessionContext sessionContext = HttpSessionContext.getInstance(); + + @Override + public void sessionCreated(HttpSessionEvent se) { + sessionContext.addSession(se.getSession()); + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + sessionContext.removeSession(se.getSession()); + } +} diff --git a/pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContext.java b/pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContext.java new file mode 100644 index 00000000..ca936c18 --- /dev/null +++ b/pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContext.java @@ -0,0 +1,53 @@ +package com.pearadmin.common.web.session; + +import javax.servlet.http.HttpSession; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @Author: Heiky + * @Date: 2020/12/17 17:14 + * @Description: 单例模式 HttpSessionContext + */ +public class HttpSessionContext { + + private static volatile HttpSessionContext sessionContext; + + private Map map; + + private HttpSessionContext() { + this.map = new ConcurrentHashMap<>(); + } + + public static HttpSessionContext getInstance() { + if (sessionContext == null) { + synchronized (HttpSessionContext.class) { + if (sessionContext == null) { + sessionContext = new HttpSessionContext(); + } + } + } + return sessionContext; + } + + public void addSession(HttpSession session) { + if (session != null) { + map.put(session.getId(), session); + } + } + + public void removeSession(HttpSession session) { + if (session != null) { + map.remove(session.getId()); + } + } + + public HttpSession getSession(String sessionId) { + if (sessionId != null && sessionId.length() == 0) { + return null; + } else { + return map.get(sessionId); + } + } + +} diff --git a/pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContextHolder.java b/pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContextHolder.java new file mode 100644 index 00000000..1a964e66 --- /dev/null +++ b/pear-common/src/main/java/com/pearadmin/common/web/session/HttpSessionContextHolder.java @@ -0,0 +1,14 @@ +package com.pearadmin.common.web.session; + +/** + * @Author: Heiky + * @Date: 2020/12/17 17:47 + * @Description: HttpSessionContext对象持有者 + */ +public class HttpSessionContextHolder { + + public static HttpSessionContext currentSessionContext() { + return HttpSessionContext.getInstance(); + } + +} diff --git a/pear-modules/pear-system/src/main/java/com/pearadmin/system/domain/SysUser.java b/pear-modules/pear-system/src/main/java/com/pearadmin/system/domain/SysUser.java index 2f0ce5ba..3d82b70f 100644 --- a/pear-modules/pear-system/src/main/java/com/pearadmin/system/domain/SysUser.java +++ b/pear-modules/pear-system/src/main/java/com/pearadmin/system/domain/SysUser.java @@ -22,6 +22,8 @@ import java.util.List; @Alias("SysUser") public class SysUser extends BaseDomain implements UserDetails { + private static final long serialVersionUID = 1L; + /** * 编号 */ -- Gitee From c5cf079fc75c7b75e6dda2568186c844fc4b39c3 Mon Sep 17 00:00:00 2001 From: Heiky Date: Thu, 17 Dec 2020 17:27:56 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=B8=A2=E5=87=BA?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pearadmin/PearEntranceApplication.java | 9 ++-- .../templates/system/user/online.html | 2 +- .../controller/SysOnlineUserController.java | 44 +++++++++++++++---- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/pear-entrance/src/main/java/com/pearadmin/PearEntranceApplication.java b/pear-entrance/src/main/java/com/pearadmin/PearEntranceApplication.java index e5106355..f24c7a51 100644 --- a/pear-entrance/src/main/java/com/pearadmin/PearEntranceApplication.java +++ b/pear-entrance/src/main/java/com/pearadmin/PearEntranceApplication.java @@ -4,18 +4,19 @@ import org.springframework.boot.SpringApplication; import org.activiti.spring.boot.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.web.servlet.ServletComponentScan; /** * Describe: 入 口 启 动 类 * Author: 就 眠 仪 式 * CreateTime: 2019/10/23 - * */ + */ + +@ServletComponentScan @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, org.activiti.spring.boot.SecurityAutoConfiguration.class, SecurityAutoConfiguration.class}) public class PearEntranceApplication { - public static void main(String[] args) - - { + public static void main(String[] args) { SpringApplication.run(PearEntranceApplication.class, args); } diff --git a/pear-entrance/src/main/resources/templates/system/user/online.html b/pear-entrance/src/main/resources/templates/system/user/online.html index 921cb496..d07b32dc 100644 --- a/pear-entrance/src/main/resources/templates/system/user/online.html +++ b/pear-entrance/src/main/resources/templates/system/user/online.html @@ -81,7 +81,7 @@ layer.close(index); let loading = layer.load(); $.ajax({ - url: MODULE_PATH + "remove/" + obj.data['onlineId'], + url: MODULE_PATH + "remove/" + obj.data['userId'], dataType: 'json', type: 'delete', success: function (result) { diff --git a/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysOnlineUserController.java b/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysOnlineUserController.java index d6292cb8..694992c6 100644 --- a/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysOnlineUserController.java +++ b/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysOnlineUserController.java @@ -3,14 +3,15 @@ package com.pearadmin.system.controller; import com.pearadmin.common.web.base.BaseController; import com.pearadmin.common.web.domain.response.Result; import com.pearadmin.common.web.domain.response.ResultTable; +import com.pearadmin.common.web.session.HttpSessionContext; +import com.pearadmin.common.web.session.HttpSessionContextHolder; import com.pearadmin.system.domain.SysOnlineUser; import com.pearadmin.system.domain.SysUser; import io.swagger.annotations.ApiOperation; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.session.SessionInformation; import org.springframework.security.core.session.SessionRegistry; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; @@ -23,7 +24,7 @@ import java.util.List; * Describe: 在线用户控制器 * Author: 就 眠 仪 式 * CreateTime: 2019/10/23 - * */ + */ @RestController @RequestMapping("system/online") @@ -36,13 +37,13 @@ public class SysOnlineUserController extends BaseController { * Describe: 在线用户列表 * Param: username * Return: ModelAndView - * */ + */ @GetMapping("data") @PreAuthorize("hasPermission('/system/online/data','sys:online:data')") - public ResultTable data(String username){ + public ResultTable data(String username) { List allPrincipalsUser = sessionRegistry.getAllPrincipals(); - List onlineUser= new ArrayList<>(); - for (Object obj : allPrincipalsUser ){ + List onlineUser = new ArrayList<>(); + for (Object obj : allPrincipalsUser) { SysOnlineUser sysOnlineUser = new SysOnlineUser(); SysUser objs = (SysUser) obj; sysOnlineUser.setUserId(objs.getUserId()); @@ -59,7 +60,32 @@ public class SysOnlineUserController extends BaseController { @GetMapping("main") @PreAuthorize("hasPermission('/system/online/main','sys:online:main')") - public ModelAndView main(){ + public ModelAndView main() { return JumpPage("system/user/online"); } + + + @DeleteMapping("/remove/{onlineId}") + @ResponseBody + public Result remove(@PathVariable String onlineId) { + List principals = sessionRegistry.getAllPrincipals(); + for (Object principal : principals) { + SysUser userDetails = (SysUser) principal; + String userId = userDetails.getUserId(); + if (onlineId.equals(userId)) { + if ("admin".equals(userDetails.getUsername())) { + return failure("不允许操作超级管理员[admin]下线"); + } + for (SessionInformation sessionInformation : sessionRegistry.getAllSessions(userDetails, false)) { + sessionInformation.expireNow(); + sessionRegistry.removeSessionInformation(sessionInformation.getSessionId()); + HttpSessionContext sessionContext = HttpSessionContextHolder.currentSessionContext(); + // 销毁session + sessionContext.getSession(sessionInformation.getSessionId()).invalidate(); + } + return success(String.format("用户[%s]已下线", userDetails.getRealName())); + } + } + return failure(); + } } -- Gitee