v2.9.0 & loginSession
This commit is contained in:
@@ -331,6 +331,7 @@ public abstract class AbstractAuthenticationProvider {
|
||||
_logger.debug("login user " + username + " not in this System ." + message);
|
||||
UserInfo loginUser = new UserInfo(username);
|
||||
loginUser.setId(loginUser.generateId());
|
||||
loginUser.setUsername(username);
|
||||
loginUser.setDisplayName("not exist");
|
||||
loginUser.setLoginCount(0);
|
||||
authenticationRealm.insertLoginHistory(loginUser, ConstantsLoginType.LOCAL, "",
|
||||
|
||||
@@ -94,7 +94,7 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
|
||||
|
||||
userInfo = loadUserInfo(loginCredential.getUsername(),loginCredential.getPassword());
|
||||
|
||||
userinfoValid(userInfo, loginCredential.getPassword());
|
||||
userinfoValid(userInfo, loginCredential.getUsername());
|
||||
|
||||
tftcaptchaValid(loginCredential.getOtpCaptcha(),loginCredential.getAuthType(),userInfo);
|
||||
|
||||
|
||||
@@ -139,15 +139,16 @@ public abstract class AbstractAuthenticationRealm {
|
||||
public boolean insertLoginHistory(UserInfo userInfo, String type, String provider, String code, String message) {
|
||||
String sessionId = WebContext.genId();
|
||||
OnlineTicket onlineTicket = null ;
|
||||
int sessionStatus = 7;
|
||||
Authentication authentication = WebContext.getAuthentication();
|
||||
if(authentication.getPrincipal() instanceof SigninPrincipal) {
|
||||
if(authentication !=null && authentication.getPrincipal() instanceof SigninPrincipal) {
|
||||
sessionStatus = 1;
|
||||
SigninPrincipal signinPrincipal = (SigninPrincipal)authentication.getPrincipal();
|
||||
onlineTicket = signinPrincipal.getOnlineTicket();
|
||||
sessionId = onlineTicket.getTicketId().substring(3);
|
||||
WebContext.setAttribute(WebConstants.CURRENT_USER_SESSION_ID, sessionId);
|
||||
}
|
||||
|
||||
WebContext.setAttribute(WebConstants.CURRENT_USER_SESSION_ID, sessionId);
|
||||
|
||||
_logger.debug("user session id is {} , online ticket {} ",sessionId,(onlineTicket == null ? "" : onlineTicket.getTicketId()));
|
||||
|
||||
userInfo.setLastLoginTime(DateUtils.formatDateTime(new Date()));
|
||||
@@ -189,7 +190,7 @@ public abstract class AbstractAuthenticationRealm {
|
||||
|
||||
}
|
||||
|
||||
loginHistoryService.login(userInfo,sessionId, type, message, code, provider, browser, platform);
|
||||
loginHistoryService.login(userInfo,sessionId, type, message, code, provider, browser, platform,sessionStatus);
|
||||
|
||||
loginService.setLastLoginInfo(userInfo);
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
||||
public class LoginHistoryService {
|
||||
private static Logger _logger = LoggerFactory.getLogger(LoginHistoryService.class);
|
||||
|
||||
private static final String HISTORY_LOGIN_INSERT_STATEMENT = "insert into mxk_history_login (id , sessionid , uid , username , displayname , logintype , message , code , provider , sourceip , browser , platform , application , loginurl )values( ? , ? , ? , ? , ?, ? , ? , ?, ? , ? , ?, ? , ? , ?)";
|
||||
private static final String HISTORY_LOGIN_INSERT_STATEMENT = "insert into mxk_history_login (id , sessionid , uid , username , displayname , logintype , message , code , provider , sourceip , browser , platform , application , loginurl , sessionstatus)values( ? , ? , ? , ? , ? , ?, ? , ? , ?, ? , ? , ?, ? , ? , ?)";
|
||||
|
||||
private static final String HISTORY_LOGOUT_UPDATE_STATEMENT = "update mxk_history_login set logouttime = ? where sessionid = ?";
|
||||
private static final String HISTORY_LOGOUT_UPDATE_STATEMENT = "update mxk_history_login set logouttime = ? ,sessionstatus = 7 where sessionid = ?";
|
||||
|
||||
protected JdbcTemplate jdbcTemplate;
|
||||
|
||||
@@ -39,14 +39,14 @@ public class LoginHistoryService {
|
||||
}
|
||||
|
||||
public void login(UserInfo userInfo,String sessionId,
|
||||
String type, String message, String code, String provider,String browser, String platform) {
|
||||
String type, String message, String code, String provider,String browser, String platform,int sessionStatus) {
|
||||
jdbcTemplate.update(HISTORY_LOGIN_INSERT_STATEMENT,
|
||||
new Object[] { WebContext.genId(), sessionId, userInfo.getId(), userInfo.getUsername(),
|
||||
userInfo.getDisplayName(), type, message, code, provider, userInfo.getLastLoginIp(), browser, platform,
|
||||
"Browser", WebContext.getRequest().getRequestURI() },
|
||||
"Browser", WebContext.getRequest().getRequestURI() , sessionStatus},
|
||||
new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
|
||||
Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
|
||||
Types.VARCHAR, Types.VARCHAR });
|
||||
Types.VARCHAR, Types.VARCHAR ,Types.INTEGER});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
package org.maxkey.persistence.mapper;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
|
||||
import org.maxkey.entity.HistoryLogin;
|
||||
|
||||
@@ -26,5 +28,7 @@ import org.maxkey.entity.HistoryLogin;
|
||||
*
|
||||
*/
|
||||
public interface HistoryLoginMapper extends IJpaBaseMapper<HistoryLogin> {
|
||||
|
||||
|
||||
public List<HistoryLogin> queryOnlineSession(HistoryLogin historyLogin);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.maxkey.persistence.service;
|
||||
|
||||
import org.apache.mybatis.jpa.persistence.JpaBaseService;
|
||||
import org.apache.mybatis.jpa.persistence.JpaPageResults;
|
||||
import org.maxkey.entity.HistoryLogin;
|
||||
import org.maxkey.persistence.mapper.HistoryLoginMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -37,4 +38,8 @@ public class HistoryLoginService extends JpaBaseService<HistoryLogin>{
|
||||
// TODO Auto-generated method stub
|
||||
return (HistoryLoginMapper)super.getMapper();
|
||||
}
|
||||
|
||||
public JpaPageResults<HistoryLogin> queryOnlineSession(HistoryLogin historyLogin) {
|
||||
return this.queryPageResults("queryOnlineSession",historyLogin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,33 @@
|
||||
order by logintime desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="queryOnlineSession" parameterType="HistoryLogin" resultType="HistoryLogin">
|
||||
select
|
||||
sessionid id,
|
||||
sessionid,
|
||||
uid,
|
||||
username,
|
||||
displayname,
|
||||
logintype,
|
||||
message,
|
||||
code,
|
||||
provider,
|
||||
sourceip,
|
||||
browser,
|
||||
platform,
|
||||
application,
|
||||
loginurl,
|
||||
date_format(logintime, '%Y-%m-%d %H:%i:%s') as logintime,
|
||||
date_format(logouttime, '%Y-%m-%d %H:%i:%s') as logouttime
|
||||
from mxk_history_login
|
||||
where sessionstatus = 1
|
||||
|
||||
<include refid="dao_where_statement"/>
|
||||
|
||||
order by logintime desc
|
||||
</select>
|
||||
|
||||
<update id="logout" parameterType="java.lang.String" >
|
||||
update mxk_history_login set
|
||||
logouttime = current_timestamp()
|
||||
|
||||
@@ -150,6 +150,8 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
|
||||
.addPathPatterns("/profile/**")
|
||||
.addPathPatterns("/safe/**")
|
||||
.addPathPatterns("/historys/**")
|
||||
.addPathPatterns("/loginsession/**")
|
||||
.addPathPatterns("loginsession/loginSessionList/grid")
|
||||
.addPathPatterns("/appList")
|
||||
.addPathPatterns("/appList/**")
|
||||
.addPathPatterns("/socialsignon/**")
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.SigninPrincipal;
|
||||
import org.maxkey.authn.online.OnlineTicket;
|
||||
import org.maxkey.authn.online.OnlineTicketServices;
|
||||
import org.maxkey.constants.ConstantsOperateMessage;
|
||||
import org.maxkey.entity.HistoryLogin;
|
||||
import org.maxkey.entity.HistoryLoginApps;
|
||||
import org.maxkey.entity.HistoryLogs;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.persistence.db.LoginHistoryService;
|
||||
import org.maxkey.persistence.db.LoginService;
|
||||
import org.maxkey.persistence.service.HistoryLoginAppsService;
|
||||
import org.maxkey.persistence.service.HistoryLoginService;
|
||||
import org.maxkey.persistence.service.HistorySystemLogsService;
|
||||
import org.maxkey.util.DateUtils;
|
||||
import org.maxkey.util.StringUtils;
|
||||
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.security.core.Authentication;
|
||||
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 = { "/loginsession" })
|
||||
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 = { "/loginSessionList" })
|
||||
public String authList() {
|
||||
return "historys/loginSessionList";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询登录日志.
|
||||
*
|
||||
* @param logsAuth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = { "/loginSessionList/grid" })
|
||||
@ResponseBody
|
||||
public JpaPageResults<HistoryLogin> loginSessionListGrid(@ModelAttribute("historyLogin") HistoryLogin historyLogin) {
|
||||
_logger.debug("history/loginsession/ loginSessionListGrid() " + historyLogin);
|
||||
historyLogin.setUid(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 {
|
||||
OnlineTicket onlineTicket = null;
|
||||
Authentication authentication = WebContext.getAuthentication();
|
||||
if(authentication.getPrincipal() instanceof SigninPrincipal) {
|
||||
SigninPrincipal signinPrincipal = (SigninPrincipal)authentication.getPrincipal();
|
||||
//onlineTicket
|
||||
onlineTicket = signinPrincipal.getOnlineTicket();
|
||||
|
||||
}
|
||||
for(String sessionId : StringUtils.string2List(ids, ",")) {
|
||||
_logger.trace("terminate session Id {} ",sessionId);
|
||||
if(onlineTicket.getTicketId().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));
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,7 @@ button.text.select=\u8bf7\u9009\u62e9
|
||||
button.text.search=\u67e5\u8be2
|
||||
button.text.expandsearch=\u5c55\u5f00
|
||||
button.text.collapsesearch=\u6536\u7f29
|
||||
button.text.terminate=\u7EC8\u6B62
|
||||
|
||||
forgotpassword.emailmobile=\u90ae\u7bb1\u6216\u624b\u673a
|
||||
forgotpassword.email=\u90ae\u7bb1
|
||||
@@ -284,6 +285,7 @@ navs.setting.timetoken=\u65f6\u95f4\u4ee4\u724c
|
||||
navs.myprofile=\u6211\u7684\u8d44\u6599
|
||||
|
||||
navs.audit=\u5ba1\u8ba1
|
||||
navs.audit.loginsession=\u4F1A\u8BDD
|
||||
navs.audit.login=\u767b\u5f55\u65e5\u5fd7
|
||||
navs.audit.signon=\u8bbf\u95ee\u65e5\u5fd7
|
||||
navs.audit.operation=\u7BA1\u7406\u65e5\u5fd7
|
||||
|
||||
@@ -216,6 +216,7 @@ button.text.select=Select
|
||||
button.text.search=Search
|
||||
button.text.expandsearch=Expand
|
||||
button.text.collapsesearch=Collapse
|
||||
button.text.terminate=Terminate
|
||||
|
||||
forgotpassword.emailmobile=Email OR Mobile
|
||||
forgotpassword.email=Email
|
||||
@@ -285,6 +286,7 @@ navs.setting.timetoken=Timetoken
|
||||
navs.myprofile=My Profile
|
||||
|
||||
navs.audit=Audit
|
||||
navs.audit.loginsession=Session
|
||||
navs.audit.login=Login
|
||||
navs.audit.signon=Sign-on
|
||||
navs.audit.operation=Management
|
||||
|
||||
@@ -217,6 +217,7 @@ button.text.select=\u8bf7\u9009\u62e9
|
||||
button.text.search=\u67e5\u8be2
|
||||
button.text.expandsearch=\u5c55\u5f00
|
||||
button.text.collapsesearch=\u6536\u7f29
|
||||
button.text.terminate=\u7EC8\u6B62
|
||||
|
||||
forgotpassword.emailmobile=\u90ae\u7bb1\u6216\u624b\u673a
|
||||
forgotpassword.email=\u90ae\u7bb1
|
||||
@@ -284,6 +285,7 @@ navs.setting.timetoken=\u65f6\u95f4\u4ee4\u724c
|
||||
navs.myprofile=\u6211\u7684\u8d44\u6599
|
||||
|
||||
navs.audit=\u5ba1\u8ba1
|
||||
navs.audit.loginsession=\u4F1A\u8BDD
|
||||
navs.audit.login=\u767b\u5f55\u65e5\u5fd7
|
||||
navs.audit.signon=\u8bbf\u95ee\u65e5\u5fd7
|
||||
navs.audit.operation=\u7BA1\u7406\u65e5\u5fd7
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE HTML >
|
||||
<html>
|
||||
<head>
|
||||
<#include "../layout/header.ftl"/>
|
||||
<#include "../layout/common.cssjs.ftl"/>
|
||||
</head>
|
||||
<body>
|
||||
<#include "../layout/top.ftl"/>
|
||||
<#include "../layout/nav_primary.ftl"/>
|
||||
<div class="container">
|
||||
<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/>/loginsession/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="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>
|
||||
|
||||
<div class="mainwrap" id="main">
|
||||
|
||||
<table data-url="<@base />/loginsession/loginSessionList/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 id="footer">
|
||||
<#include "../layout/footer.ftl"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -52,6 +52,12 @@
|
||||
<li id="nav_primay_15" class="nav_primay_level primaryleft" xpath="">
|
||||
<a href="<@base/>/historys/loginList"><@locale code="navs.audit"/></a>
|
||||
<div id="nav_child_1501" class="nav_second_child">
|
||||
<ul>
|
||||
<!--登录日志-->
|
||||
<li id="nav_second_1501" class="nav_second_level">
|
||||
<a href="<@base/>/loginsession/loginSessionList"><@locale code="navs.audit.loginsession"/></a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<!--登录日志-->
|
||||
<li id="nav_second_1501" class="nav_second_level">
|
||||
|
||||
Reference in New Issue
Block a user