Browse Source

session manage

会话管理
Crystal.Sea 3 years ago
parent
commit
c55d58ef8e

+ 4 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java

@@ -124,6 +124,10 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
                 .addPathPatterns("/permissions/**")
                 .addPathPatterns("/config/**")
                 .addPathPatterns("/logs/**")
+                .addPathPatterns("/historys/**")
+                .addPathPatterns("/historys/**/**")
+                .addPathPatterns("/session/**")
+                
                 ;
         
         _logger.debug("add PermissionAdapter");

+ 131 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/historys/contorller/LoginSessionController.java

@@ -0,0 +1,131 @@
+/*
+ * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.maxkey.web.historys.contorller;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.apache.mybatis.jpa.persistence.JpaPageResults;
+import org.maxkey.authn.online.OnlineTicketServices;
+import org.maxkey.constants.ConstantsOperateMessage;
+import org.maxkey.entity.HistoryLogin;
+import org.maxkey.entity.UserInfo;
+import org.maxkey.persistence.db.LoginHistoryService;
+import org.maxkey.persistence.db.LoginService;
+import org.maxkey.persistence.service.HistoryLoginService;
+import org.maxkey.util.DateUtils;
+import org.maxkey.util.StringUtils;
+import org.maxkey.web.WebConstants;
+import org.maxkey.web.WebContext;
+import org.maxkey.web.message.Message;
+import org.maxkey.web.message.MessageType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.propertyeditors.CustomDateEditor;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * 登录日志查询.
+ * 
+ * @author Crystal.sea
+ *
+ */
+
+@Controller
+@RequestMapping(value = { "/session" })
+public class LoginSessionController {
+    static final Logger _logger = LoggerFactory.getLogger(LoginSessionController.class);
+
+    @Autowired
+    HistoryLoginService historyLoginService;
+    @Autowired
+    LoginService loginService;
+    
+    @Autowired
+    LoginHistoryService loginHistoryService;
+    
+    @Autowired
+    OnlineTicketServices onlineTicketServices;
+    
+    @RequestMapping(value = { "/sessionList" })
+    public String authList() {
+        return "historys/sessionList";
+    }
+
+    /**
+     * 查询登录日志.
+     * 
+     * @param logsAuth
+     * @return
+     */
+    @RequestMapping(value = { "/sessionList/grid" })
+    @ResponseBody
+    public JpaPageResults<HistoryLogin> loginSessionListGrid(@ModelAttribute("historyLogin") HistoryLogin historyLogin) {
+        _logger.debug("history/session/ sessionListGrid() " + historyLogin);
+        //historyLogin.setUserId(WebContext.getUserInfo().getId());
+        return historyLoginService.queryOnlineSession(historyLogin);
+    }
+
+
+    
+    @ResponseBody
+    @RequestMapping(value="/terminate")  
+    public Message deleteUsersById(@RequestParam("id") String ids) {
+        _logger.debug(ids);
+        boolean isTerminated = false;
+        try {
+            String currentUserSessionId = "";
+            if(WebContext.getAttribute(WebConstants.CURRENT_USER_SESSION_ID) != null) {
+                currentUserSessionId = WebContext.getAttribute(WebConstants.CURRENT_USER_SESSION_ID).toString();
+            }
+            for(String sessionId : StringUtils.string2List(ids, ",")) {
+                _logger.trace("terminate session Id {} ",sessionId);
+                if(currentUserSessionId.contains(sessionId)) {
+                    //skip current session
+                    continue;
+                }
+                UserInfo userInfo = WebContext.getUserInfo();
+                String lastLogoffTime = DateUtils.formatDateTime(new Date());
+                loginService.setLastLogoffInfo(userInfo);
+                loginHistoryService.logoff(lastLogoffTime, sessionId);
+                onlineTicketServices.remove("OT-" + sessionId);
+            }
+            isTerminated = true;
+        }catch(Exception e) {
+            _logger.debug("terminate Exception .",e);
+        }
+        
+        if(isTerminated) {
+            return  new Message(WebContext.getI18nValue(ConstantsOperateMessage.DELETE_SUCCESS),MessageType.success);
+        } else {
+            return  new Message(WebContext.getI18nValue(ConstantsOperateMessage.DELETE_ERROR),MessageType.error);
+        }
+    }
+    @InitBinder
+    public void initBinder(WebDataBinder binder) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.FORMAT_DATE_HH_MM_SS);
+        dateFormat.setLenient(false);
+        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
+    }
+}

+ 3 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties

@@ -486,6 +486,7 @@ button.text.hidden=\u9690\u85cf
 button.text.import=\u5bfc\u5165
 button.text.adjunct=\u517c\u4efb\u673a\u6784
 button.text.sync=\u540C\u6B65
+button.text.terminate=\u7EC8\u6B62
 #loginhistory
 log.loginhistory.id=\u7f16\u53f7
 log.loginhistory.sessionId=\u4f1a\u8bdd
@@ -572,6 +573,7 @@ navs.groups.privileges=\u8bbf\u95ee\u6743\u9650\u7ba1\u7406
 navs.conf=\u914d\u7f6e\u7ba1\u7406
 navs.conf.passwordpolicy=\u5bc6\u7801\u7b56\u7565
 navs.audit=\u65e5\u5fd7\u5ba1\u8ba1
+navs.audit.loginsession=\u4F1A\u8BDD\u7BA1\u7406
 navs.audit.login=\u767b\u5f55\u65e5\u5fd7
 navs.audit.loginapps=\u8bbf\u95ee\u65e5\u5fd7
 navs.audit.operate=\u7BA1\u7406\u65e5\u5fd7
@@ -583,4 +585,4 @@ navs.role.permissions=\u89d2\u8272\u6743\u9650\u7ba1\u7406
 navs.resources=\u8d44\u6e90\u7ba1\u7406
 navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
 navs.notices=\u901A\u77E5\u516C\u544A
-navs.synchronizers=\u540C\u6B65\u5668
+navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406

+ 2 - 0
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties

@@ -497,6 +497,7 @@ button.text.hidden=Hidden
 button.text.import=Import
 button.text.adjunct=Adjoint Depts
 button.text.sync=Sync
+button.text.terminate=Terminate
 
 log.loginhistory.id=id
 log.loginhistory.sessionId=sessionId
@@ -583,6 +584,7 @@ navs.groups.privileges=Access Privileges
 navs.conf=Conf
 navs.conf.passwordpolicy=PasswordPolicy
 navs.audit=Audit
+navs.audit.loginsession=Session
 navs.audit.login=Login
 navs.audit.loginapps=LoginApps
 navs.audit.operate=Management

+ 3 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties

@@ -492,6 +492,7 @@ button.text.hidden=\u9690\u85cf
 button.text.import=\u5bfc\u5165
 button.text.adjunct=\u517c\u4efb\u673a\u6784
 button.text.sync=\u540C\u6B65
+button.text.terminate=\u7EC8\u6B62
 #loginhistory
 log.loginhistory.id=\u7f16\u53f7
 log.loginhistory.sessionId=\u4f1a\u8bdd
@@ -577,6 +578,7 @@ navs.groups.privileges=\u8bbf\u95ee\u6743\u9650\u7ba1\u7406
 navs.conf=\u914d\u7f6e\u7ba1\u7406
 navs.conf.passwordpolicy=\u5bc6\u7801\u7b56\u7565
 navs.audit=\u65e5\u5fd7\u5ba1\u8ba1
+navs.audit.loginsession=\u4F1A\u8BDD\u7BA1\u7406
 navs.audit.login=\u767b\u5f55\u65e5\u5fd7
 navs.audit.loginapps=\u8bbf\u95ee\u65e5\u5fd7
 navs.audit.operate=\u7BA1\u7406\u65e5\u5fd7
@@ -588,4 +590,4 @@ navs.role.permissions=\u89d2\u8272\u6743\u9650\u7ba1\u7406
 navs.resources=\u8d44\u6e90\u7ba1\u7406
 navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
 navs.notices=\u901A\u77E5\u516C\u544A
-navs.synchronizers=\u540C\u6B65\u5668
+navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406

+ 152 - 0
maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/historys/sessionList.ftl

@@ -0,0 +1,152 @@
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<#include  "../layout/header.ftl"/>
+	<#include  "../layout/common.cssjs.ftl"/>
+	<script type="text/javascript">	
+
+	</script>
+</head>
+<body> 
+<div class="app header-default side-nav-dark">
+<div class="layout">
+	<div class="header navbar">
+		<#include  "../layout/top.ftl"/>
+	</div>
+	
+	<div class="col-md-3 sidebar-nav side-nav" >
+		<#include  "../layout/sidenav.ftl"/>
+	</div>
+	<div class="page-container">
+	
+	<div class="main-content">
+					<div class="container-fluid">
+
+						<div class="breadcrumb-wrapper row">
+							<div class="col-12 col-lg-3 col-md-6">
+								<h4 class="page-title"><@locale code="navs.audit.loginsession"/></h4>
+							</div>
+							<div class="col-12 col-lg-9 col-md-6">
+								<ol class="breadcrumb float-right">
+									<li><a href="<@base/>/main"><@locale code="navs.home"/></a></li>
+									<li class="inactive" >/ <@locale code="navs.audit"/></li>
+									<li class="active">/ <@locale code="navs.audit.loginsession"/></li>
+								</ol>
+							</div>
+						</div>
+
+					</div>
+					<div class="container-fluid">
+					<div class="content-wrapper row">
+					<div class="col-12 grid-margin">
+						<div class="card">
+							<div class="card-body">
+	<div id="tool_box">
+		<table  class="table table-bordered">
+			<tr>
+				<td  width="120px">
+				<@locale code="log.loginhistory.sourceIp"/>
+				</td>
+				<td  width="375px">
+					<form id="basic_search_form">
+				 			<input class="form-control" name="sourceIp" type="text" style ="width:150px;float:left;">
+				 			<input class="button btn btn-primary mr-3"  id="searchBtn" type="button" size="50" value="<@locale code="button.text.search"/>">
+				 			<input class="button btn btn-secondary"  id="advancedSearchExpandBtn" type="button" size="50"  value="<@locale code="button.text.expandsearch"/>" expandValue="<@locale code="button.text.expandsearch"/>"  collapseValue="<@locale code="button.text.collapsesearch"/>">
+					 	</form>
+				</td>
+				<td colspan="2"> 
+				    <div id="tool_box_right">
+					   <input id="deleteBtn" type="button" class="button btn btn-danger mr-3 "   
+					       value="<@locale code="button.text.terminate"/>" 
+					       wurl="<@base/>/session/terminate" />
+				    </div>
+				</td>
+			</tr>
+		</table>
+ 		
+		
+ 	</div>
+ 	
+ 	<div id="advanced_search">
+ 		<form id="advanced_search_form">
+ 			<table   class="table table-bordered">
+ 			<tr>
+	 				<td width="120px"><@locale code="log.loginhistory.username"/></td>
+		 			<td width="360px">
+		 				<input class="form-control" name="username" type="text" >
+		 			</td>
+		 			<td width="120px"><@locale code="log.loginhistory.displayName"/></td>
+		 			<td width="360px">
+						<input style="width:70%"  class="form-control"  type="text" name="displayName"  title="" value=""/>
+			 		</td>
+			 </tr>
+			 <tr>
+	 				<td width="120px"><@locale code="common.text.startdate"/></td>
+		 			<td width="360px">
+		 				<input class="datetimepicker form-control" name="startDate" type="text" >
+		 			</td>
+		 			<td width="120px"><@locale code="common.text.enddate"/></td>
+		 			<td width="360px">
+						<input style="width:70%"  class="datetimepicker form-control"  type="text" id="endDate" name="endDate"  title="" value=""/>
+			 		</td>
+			 </tr>
+			</table>
+ 		</form>
+ 	</div>
+ 	
+	<table  data-url="<@base />/session/sessionList/grid"
+			id="datagrid"
+			data-toggle="table"
+			data-classes="table table-bordered table-hover table-striped"
+			data-pagination="true"
+			data-click-to-select="true"
+			data-total-field="records"
+			data-page-list="[10, 25, 50, 100]"
+			data-search="false"
+			data-locale="zh-CN"
+			data-query-params="dataGridQueryParams"
+			data-query-params-type="pageSize"
+			data-side-pagination="server">
+		<thead>
+			<tr>
+			    <th data-checkbox="true"></th>
+				<th data-sortable="true" data-field="id"   data-visible="false"><@locale code="log.loginhistory.id"/></th>
+				<th data-field="sessionId"><@locale code="log.loginhistory.sessionId"/></th>
+				<th data-field="username"><@locale code="log.loginhistory.username"/></th>
+				<th data-field="displayName"><@locale code="log.loginhistory.displayName"/></th>
+				<th data-field="provider"><@locale code="log.loginhistory.provider"/></th>
+				<th data-field="message"><@locale code="log.loginhistory.message"/></th>
+				<th data-field="loginType"><@locale code="log.loginhistory.loginType"/></th>
+				<th data-field="sourceIp"><@locale code="log.loginhistory.sourceIp"/></th>
+				<th data-field="browser"><@locale code="log.loginhistory.browser"/></th>
+				<th data-field="loginTime"><@locale code="log.loginhistory.loginTime"/></th>
+				<th data-field="logoutTime"><@locale code="log.loginhistory.logoutTime"/></th>
+				<th data-field="platform"><@locale code="log.loginhistory.platform"/></th>
+				<th data-field="application" data-visible="false"><@locale code="log.loginhistory.application"/></th>
+				<th data-field="loginUrl" data-visible="false"><@locale code="log.loginhistory.loginUrl"/></th>
+				<th data-field="code" data-visible="false"><@locale code="log.loginhistory.code"/></th>
+				<th data-field="rpUserInfo" data-visible="false"><@locale code="log.loginhistory.rpUserInfo"/></th>
+	
+			</tr>
+		</thead>
+	</table>
+</div>
+	
+</div>
+</div>
+					</div>
+<footer class="content-footer">
+					<#include  "../layout/footer.ftl"/>
+</footer>
+
+	</div>
+	
+	</div>
+</div>
+
+<div id="preloader">
+<div class="loader" id="loader-1"></div>
+</div>
+
+</body>
+</html>

+ 8 - 2
maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/layout/sidenav.ftl

@@ -107,7 +107,7 @@
            <li>
              <a class="side-nav-menu" href="<@base />/synchronizers/list/">
                 <@locale code="navs.synchronizers"/>  
-                <span class="fa fa-fw fa-chain"></span>
+                <span class="fa fa-fw fa-share-alt-square"></span>
              </a>
            </li>
            <li>
@@ -128,8 +128,14 @@
      	<a class="side-nav-menu has-arrow" href="#">
        		<@locale code="navs.audit"/>
        		<span class="fa fa-fw fa-eye fa-lg"></span>
-     	</a>
+     	</a> 
      	<ul>
+     		<li>
+	         <a class="side-nav-menu" href="<@base/>/session/sessionList/">
+	         	<@locale code="navs.audit.loginsession"/>
+	         	<span class="fa fa-fw fa-eye"></span>
+	         </a>
+	       </li>
 	       <li>
 	         <a class="side-nav-menu" href="<@base />/historys/loginHistoryList/">
 	         	<@locale code="navs.audit.login"/>