新增退出日志记录
This commit is contained in:
parent
720e079d20
commit
10761200dd
|
|
@ -23,6 +23,11 @@ public class CommonConstant
|
||||||
*/
|
*/
|
||||||
public static final String LOGIN_SUCCESS = "Success";
|
public static final String LOGIN_SUCCESS = "Success";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销
|
||||||
|
*/
|
||||||
|
public static final String Logout = "Logout";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录失败
|
* 登录失败
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package com.ruoyi.common.utils;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端工具类
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
public class HttpContextUtils
|
|
||||||
{
|
|
||||||
public static HttpServletRequest getHttpServletRequest()
|
|
||||||
{
|
|
||||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class ServletUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取request对象
|
||||||
|
*/
|
||||||
|
public static HttpServletRequest getHttpServletRequest()
|
||||||
|
{
|
||||||
|
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是Ajax异步请求
|
||||||
|
*/
|
||||||
|
public static boolean isAjaxRequest(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
|
||||||
|
String accept = request.getHeader("accept");
|
||||||
|
if (accept != null && accept.indexOf("application/json") != -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||||
|
if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = request.getRequestURI();
|
||||||
|
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ajax = request.getParameter("__ajax");
|
||||||
|
if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -153,4 +153,25 @@ public class StringUtils
|
||||||
return (str == null ? "" : str.trim());
|
return (str == null ? "" : str.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否包含字符串
|
||||||
|
*
|
||||||
|
* @param str 验证字符串
|
||||||
|
* @param strs 字符串组
|
||||||
|
* @return 包含返回true
|
||||||
|
*/
|
||||||
|
public static boolean inStringIgnoreCase(String str, String... strs)
|
||||||
|
{
|
||||||
|
if (str != null && strs != null)
|
||||||
|
{
|
||||||
|
for (String s : strs)
|
||||||
|
{
|
||||||
|
if (str.equalsIgnoreCase(trim(s)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ public class SystemLogUtils
|
||||||
|
|
||||||
sys_user_logger.info(s.toString(), args);
|
sys_user_logger.info(s.toString(), args);
|
||||||
|
|
||||||
if (CommonConstant.LOGIN_SUCCESS.equals(status))
|
if (CommonConstant.LOGIN_SUCCESS.equals(status) || CommonConstant.Logout.equals(status))
|
||||||
{
|
{
|
||||||
saveOpLog(username, msg, CommonConstant.SUCCESS);
|
saveOpLog(username, msg, CommonConstant.SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ public class SystemLogUtils
|
||||||
|
|
||||||
public static void saveOpLog(String username, String message, String status)
|
public static void saveOpLog(String username, String message, String status)
|
||||||
{
|
{
|
||||||
UserAgent userAgent = UserAgent.parseUserAgentString(HttpContextUtils.getHttpServletRequest().getHeader("User-Agent"));
|
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getHttpServletRequest().getHeader("User-Agent"));
|
||||||
// 获取客户端操作系统
|
// 获取客户端操作系统
|
||||||
String os = userAgent.getOperatingSystem().getName();
|
String os = userAgent.getOperatingSystem().getName();
|
||||||
// 获取客户端浏览器
|
// 获取客户端浏览器
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ public class ShiroUtils
|
||||||
return getUser().getUserId().longValue();
|
return getUser().getUserId().longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getLoginName()
|
||||||
|
{
|
||||||
|
return getUser().getLoginName();
|
||||||
|
}
|
||||||
|
|
||||||
public static String getIp()
|
public static String getIp()
|
||||||
{
|
{
|
||||||
return getSubjct().getSession().getHost();
|
return getSubjct().getSession().getHost();
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.utils.HttpContextUtils;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.security.ShiroUtils;
|
import com.ruoyi.common.utils.security.ShiroUtils;
|
||||||
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
||||||
import com.ruoyi.project.monitor.operlog.domain.OperLog;
|
import com.ruoyi.project.monitor.operlog.domain.OperLog;
|
||||||
|
|
@ -85,7 +85,7 @@ public class LogAspect
|
||||||
// 请求的地址
|
// 请求的地址
|
||||||
String ip = ShiroUtils.getIp();
|
String ip = ShiroUtils.getIp();
|
||||||
operLog.setOperIp(ip);
|
operLog.setOperIp(ip);
|
||||||
operLog.setOperUrl(HttpContextUtils.getHttpServletRequest().getRequestURI());
|
operLog.setOperUrl(ServletUtils.getHttpServletRequest().getRequestURI());
|
||||||
if (currentUser != null)
|
if (currentUser != null)
|
||||||
{
|
{
|
||||||
operLog.setLoginName(currentUser.getLoginName());
|
operLog.setLoginName(currentUser.getLoginName());
|
||||||
|
|
@ -146,7 +146,7 @@ public class LogAspect
|
||||||
*/
|
*/
|
||||||
private static void setRequestValue(OperLog operLog)
|
private static void setRequestValue(OperLog operLog)
|
||||||
{
|
{
|
||||||
Map<String, String[]> map = HttpContextUtils.getHttpServletRequest().getParameterMap();
|
Map<String, String[]> map = ServletUtils.getHttpServletRequest().getParameterMap();
|
||||||
String params = JSONObject.toJSONString(map);
|
String params = JSONObject.toJSONString(map);
|
||||||
operLog.setOperParam(params);
|
operLog.setOperParam(params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||||
import org.apache.shiro.web.filter.authc.LogoutFilter;
|
|
||||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -15,10 +14,10 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import com.ruoyi.framework.shiro.realm.UserRealm;
|
import com.ruoyi.framework.shiro.realm.UserRealm;
|
||||||
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
||||||
import com.ruoyi.framework.shiro.session.OnlineSessionFactory;
|
import com.ruoyi.framework.shiro.session.OnlineSessionFactory;
|
||||||
|
import com.ruoyi.framework.shiro.web.filter.LogoutFilter;
|
||||||
import com.ruoyi.framework.shiro.web.filter.online.OnlineSessionFilter;
|
import com.ruoyi.framework.shiro.web.filter.online.OnlineSessionFilter;
|
||||||
import com.ruoyi.framework.shiro.web.filter.sync.SyncOnlineSessionFilter;
|
import com.ruoyi.framework.shiro.web.filter.sync.SyncOnlineSessionFilter;
|
||||||
import com.ruoyi.framework.shiro.web.session.OnlineWebSessionManager;
|
import com.ruoyi.framework.shiro.web.session.OnlineWebSessionManager;
|
||||||
|
|
@ -173,6 +172,16 @@ public class ShiroConfig
|
||||||
return securityManager;
|
return securityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出过滤器
|
||||||
|
*/
|
||||||
|
public LogoutFilter logoutFilter()
|
||||||
|
{
|
||||||
|
LogoutFilter logoutFilter = new LogoutFilter();
|
||||||
|
logoutFilter.setLoginUrl(loginUrl);
|
||||||
|
return logoutFilter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shiro过滤器配置
|
* Shiro过滤器配置
|
||||||
*/
|
*/
|
||||||
|
|
@ -186,9 +195,6 @@ public class ShiroConfig
|
||||||
shiroFilterFactoryBean.setLoginUrl(loginUrl);
|
shiroFilterFactoryBean.setLoginUrl(loginUrl);
|
||||||
// 权限认证失败,则跳转到指定页面
|
// 权限认证失败,则跳转到指定页面
|
||||||
shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
|
shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
|
||||||
// 注销成功,则跳转到指定页面
|
|
||||||
LogoutFilter logoutFilter = new LogoutFilter();
|
|
||||||
logoutFilter.setRedirectUrl(loginUrl);
|
|
||||||
// Shiro连接约束配置,即过滤链的定义
|
// Shiro连接约束配置,即过滤链的定义
|
||||||
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
||||||
// 对静态资源设置匿名访问
|
// 对静态资源设置匿名访问
|
||||||
|
|
@ -212,6 +218,8 @@ public class ShiroConfig
|
||||||
Map<String, Filter> filters = new LinkedHashMap<>();
|
Map<String, Filter> filters = new LinkedHashMap<>();
|
||||||
filters.put("onlineSession", onlineSessionFilter());
|
filters.put("onlineSession", onlineSessionFilter());
|
||||||
filters.put("syncOnlineSession", syncOnlineSessionFilter());
|
filters.put("syncOnlineSession", syncOnlineSessionFilter());
|
||||||
|
// 注销成功,则跳转到指定页面
|
||||||
|
filters.put("logout", logoutFilter());
|
||||||
shiroFilterFactoryBean.setFilters(filters);
|
shiroFilterFactoryBean.setFilters(filters);
|
||||||
|
|
||||||
// 所有请求需要认证
|
// 所有请求需要认证
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import org.apache.shiro.session.mgt.SessionContext;
|
||||||
import org.apache.shiro.session.mgt.SessionFactory;
|
import org.apache.shiro.session.mgt.SessionFactory;
|
||||||
import org.apache.shiro.web.session.mgt.WebSessionContext;
|
import org.apache.shiro.web.session.mgt.WebSessionContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import com.ruoyi.common.utils.HttpContextUtils;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.IpUtils;
|
import com.ruoyi.common.utils.IpUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.project.monitor.online.domain.OnlineSession;
|
import com.ruoyi.project.monitor.online.domain.OnlineSession;
|
||||||
|
|
@ -43,7 +43,7 @@ public class OnlineSessionFactory implements SessionFactory
|
||||||
if (request != null)
|
if (request != null)
|
||||||
{
|
{
|
||||||
UserAgent userAgent = UserAgent
|
UserAgent userAgent = UserAgent
|
||||||
.parseUserAgentString(HttpContextUtils.getHttpServletRequest().getHeader("User-Agent"));
|
.parseUserAgentString(ServletUtils.getHttpServletRequest().getHeader("User-Agent"));
|
||||||
// 获取客户端操作系统
|
// 获取客户端操作系统
|
||||||
String os = userAgent.getOperatingSystem().getName();
|
String os = userAgent.getOperatingSystem().getName();
|
||||||
// 获取客户端浏览器
|
// 获取客户端浏览器
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.ruoyi.framework.shiro.web.filter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.shiro.session.SessionException;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import com.ruoyi.common.constant.CommonConstant;
|
||||||
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
|
import com.ruoyi.common.utils.SystemLogUtils;
|
||||||
|
import com.ruoyi.common.utils.security.ShiroUtils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出过滤器
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出后重定向的地址
|
||||||
|
*/
|
||||||
|
private String loginUrl;
|
||||||
|
|
||||||
|
public String getLoginUrl()
|
||||||
|
{
|
||||||
|
return loginUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoginUrl(String loginUrl)
|
||||||
|
{
|
||||||
|
this.loginUrl = loginUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Subject subject = getSubject(request, response);
|
||||||
|
String redirectUrl = getRedirectUrl(request, response, subject);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String loginName = ShiroUtils.getLoginName();
|
||||||
|
// 记录用户退出日志
|
||||||
|
SystemLogUtils.log(loginName, CommonConstant.Logout, MessageUtils.message("user.logout.success"));
|
||||||
|
// 退出登录
|
||||||
|
subject.logout();
|
||||||
|
}
|
||||||
|
catch (SessionException ise)
|
||||||
|
{
|
||||||
|
log.error("logout fail.", ise);
|
||||||
|
}
|
||||||
|
issueRedirect(request, response, redirectUrl);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.debug("Encountered session exception during logout. This can generally safely be ignored.", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出跳转URL
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject)
|
||||||
|
{
|
||||||
|
String url = getLoginUrl();
|
||||||
|
if (StringUtils.isNoneBlank(url))
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
return super.getRedirectUrl(request, response, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ package com.ruoyi.framework.web.support;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.HttpContextUtils;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.MapDataUtil;
|
import com.ruoyi.common.utils.MapDataUtil;
|
||||||
import com.ruoyi.framework.web.page.PageUtilEntity;
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ public class TableSupport
|
||||||
*/
|
*/
|
||||||
public static PageUtilEntity getPageUtilEntity()
|
public static PageUtilEntity getPageUtilEntity()
|
||||||
{
|
{
|
||||||
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
HttpServletRequest request = ServletUtils.getHttpServletRequest();
|
||||||
PageUtilEntity pageUtilEntity = new PageUtilEntity();
|
PageUtilEntity pageUtilEntity = new PageUtilEntity();
|
||||||
pageUtilEntity.setPage(Integer.valueOf(request.getParameter("offset")));
|
pageUtilEntity.setPage(Integer.valueOf(request.getParameter("offset")));
|
||||||
pageUtilEntity.setSize(Integer.valueOf(request.getParameter("limit")));
|
pageUtilEntity.setSize(Integer.valueOf(request.getParameter("limit")));
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ user.password.retry.limit.count=密码输入错误{0}次,{1}
|
||||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
|
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
|
||||||
user.blocked=用户已封禁,原因:{0}
|
user.blocked=用户已封禁,原因:{0}
|
||||||
role.blocked=角色已封禁,原因:{0}
|
role.blocked=角色已封禁,原因:{0}
|
||||||
|
user.logout.success=退出成功
|
||||||
|
|
||||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||||
|
|
||||||
|
|
@ -16,7 +17,6 @@ user.jcaptcha.error=验证码错误
|
||||||
|
|
||||||
user.email.not.valid=邮箱格式错误
|
user.email.not.valid=邮箱格式错误
|
||||||
user.mobile.phone.number.not.valid=手机号格式错误
|
user.mobile.phone.number.not.valid=手机号格式错误
|
||||||
user.logout.success=退出成功
|
|
||||||
user.login.success=登录成功
|
user.login.success=登录成功
|
||||||
user.notfound=请重新登录
|
user.notfound=请重新登录
|
||||||
user.forcelogout=管理员强制退出,请重新登录
|
user.forcelogout=管理员强制退出,请重新登录
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ $(function() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'status',
|
field: 'status',
|
||||||
title: '登录状态',
|
title: '状态',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
formatter: function(value, row, index) {
|
formatter: function(value, row, index) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
|
|
@ -36,6 +36,10 @@ $(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'msg',
|
||||||
|
title: '操作信息'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'loginTime',
|
field: 'loginTime',
|
||||||
title: '登录时间'
|
title: '登录时间'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue