From f80582fbb3a72af0795fc8a5309a815bb06bbd40 Mon Sep 17 00:00:00 2001 From: MaxKey Date: Thu, 19 Aug 2021 11:33:33 +0800 Subject: [PATCH] v2.9.0 & loginSession --- .../authn/AbstractAuthenticationProvider.java | 1 + .../authn/RealmAuthenticationProvider.java | 2 +- .../realm/AbstractAuthenticationRealm.java | 9 +- .../persistence/db/LoginHistoryService.java | 10 +- .../mapper/HistoryLoginMapper.java | 6 +- .../service/HistoryLoginService.java | 5 + .../mapper/xml/mysql/HistoryLoginMapper.xml | 27 ++++ .../main/java/org/maxkey/MaxKeyMvcConfig.java | 2 + .../contorller/LoginSessionController.java | 141 ++++++++++++++++++ .../resources/messages/message.properties | 2 + .../resources/messages/message_en.properties | 2 + .../messages/message_zh_CN.properties | 2 + .../views/historys/loginSessionList.ftl | 98 ++++++++++++ .../templates/views/layout/nav_primary.ftl | 6 + 14 files changed, 302 insertions(+), 11 deletions(-) create mode 100644 maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/historys/contorller/LoginSessionController.java create mode 100644 maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/historys/loginSessionList.ftl diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java index 10d56ab6..7c3a905e 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java @@ -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, "", diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java index 5016361b..6d08bd62 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java @@ -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); diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/AbstractAuthenticationRealm.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/AbstractAuthenticationRealm.java index e29ff7ee..6910b2cb 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/AbstractAuthenticationRealm.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/AbstractAuthenticationRealm.java @@ -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); diff --git a/maxkey-core/src/main/java/org/maxkey/persistence/db/LoginHistoryService.java b/maxkey-core/src/main/java/org/maxkey/persistence/db/LoginHistoryService.java index d917e14b..7e8bd84b 100644 --- a/maxkey-core/src/main/java/org/maxkey/persistence/db/LoginHistoryService.java +++ b/maxkey-core/src/main/java/org/maxkey/persistence/db/LoginHistoryService.java @@ -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}); } diff --git a/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/HistoryLoginMapper.java b/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/HistoryLoginMapper.java index 5ccafe33..13f386a9 100644 --- a/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/HistoryLoginMapper.java +++ b/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/HistoryLoginMapper.java @@ -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 { - + + public List queryOnlineSession(HistoryLogin historyLogin); + } diff --git a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/HistoryLoginService.java b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/HistoryLoginService.java index c633cca7..9dd5aa77 100644 --- a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/HistoryLoginService.java +++ b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/HistoryLoginService.java @@ -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{ // TODO Auto-generated method stub return (HistoryLoginMapper)super.getMapper(); } + + public JpaPageResults queryOnlineSession(HistoryLogin historyLogin) { + return this.queryPageResults("queryOnlineSession",historyLogin); + } } diff --git a/maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/HistoryLoginMapper.xml b/maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/HistoryLoginMapper.xml index 95847cdd..dfdc1a14 100644 --- a/maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/HistoryLoginMapper.xml +++ b/maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/HistoryLoginMapper.xml @@ -63,6 +63,33 @@ order by logintime desc + + + update mxk_history_login set logouttime = current_timestamp() diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java b/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java index 0f073774..359de79d 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java +++ b/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyMvcConfig.java @@ -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/**") diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/historys/contorller/LoginSessionController.java b/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/historys/contorller/LoginSessionController.java new file mode 100644 index 00000000..eeb80097 --- /dev/null +++ b/maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/historys/contorller/LoginSessionController.java @@ -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 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)); + } +} diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message.properties b/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message.properties index 3881aa99..67309d69 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message.properties +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message.properties @@ -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 diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_en.properties b/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_en.properties index 36f4b712..888cebff 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_en.properties +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_en.properties @@ -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 diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_zh_CN.properties b/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_zh_CN.properties index 3881aa99..67309d69 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_zh_CN.properties +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/messages/message_zh_CN.properties @@ -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 diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/historys/loginSessionList.ftl b/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/historys/loginSessionList.ftl new file mode 100644 index 00000000..6c0e50b6 --- /dev/null +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/historys/loginSessionList.ftl @@ -0,0 +1,98 @@ + + + + <#include "../layout/header.ftl"/> + <#include "../layout/common.cssjs.ftl"/> + + +<#include "../layout/top.ftl"/> +<#include "../layout/nav_primary.ftl"/> +
+
+ + + + + + +
+ <@locale code="log.loginhistory.sourceIp"/> + +
+ + "> + " expandValue="<@locale code="button.text.expandsearch"/>" collapseValue="<@locale code="button.text.collapsesearch"/>"> +
+
+
+ " + wurl="<@base/>/loginsession/terminate" /> +
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
<@locale code="log.loginhistory.id"/><@locale code="log.loginhistory.sessionId"/><@locale code="log.loginhistory.username"/><@locale code="log.loginhistory.displayName"/><@locale code="log.loginhistory.provider"/><@locale code="log.loginhistory.message"/><@locale code="log.loginhistory.loginType"/><@locale code="log.loginhistory.sourceIp"/><@locale code="log.loginhistory.browser"/><@locale code="log.loginhistory.loginTime"/><@locale code="log.loginhistory.logoutTime"/><@locale code="log.loginhistory.platform"/><@locale code="log.loginhistory.application"/><@locale code="log.loginhistory.loginUrl"/><@locale code="log.loginhistory.code"/><@locale code="log.loginhistory.rpUserInfo"/>
+
+
+ + + \ No newline at end of file diff --git a/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/nav_primary.ftl b/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/nav_primary.ftl index 7b8f54ba..ba2a4c60 100644 --- a/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/nav_primary.ftl +++ b/maxkey-webs/maxkey-web-maxkey/src/main/resources/templates/views/layout/nav_primary.ftl @@ -52,6 +52,12 @@