Authored by qinchao

用户操作记录拦截

package com.ui.User;
import com.ui.contants.HttpUriContants;
import org.apache.commons.lang.StringUtils;
/**
* Created by craig.qin
* 用户操作uri
*/
public enum UserOperateEnum {
//user服务相关
manage_toUser("/manage/toUser","用户管理页面",false),
manage_saveUser("/manage/saveUser","用户新增/更新",true),
manage_deleteUser("/manage/deleteUser","用户删除",true),
//java服务相关
JAVA_STOP_RESTART(HttpUriContants.JAVA_STOP_RESTART,"java重启/停止",true);
private String uri;
private String desc;
private boolean aspectFlag;
UserOperateEnum(String uri, String desc,boolean aspectFlag){
this.uri = uri;
this.desc = desc;
this.aspectFlag=aspectFlag;
}
/**
* 根据uri获取具有拦截标识的操作对象
* @param uri
* @return
*/
public static UserOperateEnum getAspectByUri(String uri){
if(StringUtils.isBlank(uri)){
return null;
}
UserOperateEnum[] allOperate = UserOperateEnum.values();
for(UserOperateEnum oper:allOperate){
if(oper.aspectFlag&&oper.uri.equals(uri)){
return oper;
}
}
return null;
}
/**
* 获取操作的描述信息
* @param operate
* @return
*/
public String getDesc(UserOperateEnum operate){
if(operate==null){
return "";
}
return operate.desc;
}
}
... ...
... ... @@ -55,8 +55,31 @@ public class UserOperateListener {
this.httpRestClient.defaultPost(HttpUriContants.USER_OPERATE,userOperateReq,String.class);
}
public void add(String user,String operate){
UserOperate userOperate = new UserOperate(user,operate,simpleDateFormat.format(new Date()));
/**
* 新增一条记录
* @param user 操作用户
* @param operate 操作uri
* @param params 操作参数
*/
public void add(String user,String operate,String params){
java.util.Date ts=new Date();
UserOperate userOperate = new UserOperate(user,operate,params,simpleDateFormat.format(ts),ts);
this.pending.offer(userOperate);
if(this.pending.size() > 800){
this.flush();
}
}
/**
* 新增一条记录
* @param user 操作用户
* @param operate 操作uri
* @param operateDesc 操作uri描述
* @param params 操作参数
*/
public void add(String user,String operate,String operateDesc,String params){
java.util.Date ts=new Date();
UserOperate userOperate = new UserOperate(user,operate,operateDesc,params,simpleDateFormat.format(ts),ts);
this.pending.offer(userOperate);
if(this.pending.size() > 800){
this.flush();
... ...
... ... @@ -7,22 +7,39 @@ import lombok.Data;
*/
@Data
public class UserOperate {
//用户名
private String user;
//操作uri
private String operate;
//操作uri名称
private String operateDesc;
//操作参数
private String params;
//操作时间
private String time;
private java.util.Date ts;
private UserOperate(){
}
public UserOperate(String user,String operate, String time){
public UserOperate(String user,String operate, String params ,String time,java.util.Date ts){
this.user = user;
this.operate = operate;
this.params=params;
this.time = time;
this.ts=ts;
}
public UserOperate(String user,String operate,String operateDesc, String params ,String time,java.util.Date ts){
this.user = user;
this.operate = operate;
this.operateDesc=operateDesc;
this.params=params;
this.time = time;
this.ts=ts;
}
}
... ...
package com.ui.ctrl;
import com.ui.User.MD5Util;
import com.ui.User.UserAuthLocal;
import com.ui.contants.HttpUriContants;
import com.ui.http.HttpRestClient;
... ...
package com.ui.ctrl;
import com.ui.User.UserOperateListener;
import com.ui.contants.HttpUriContants;
import com.ui.http.HttpRestClient;
import com.ui.model.BaseResponse;
import com.ui.model.req.SqlOpLogsReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/userOperateLog")
public class UserOperateLogCtrl {
Logger log = LoggerFactory.getLogger(UserOperateLogCtrl.class);
@Autowired
UserOperateListener userOperateListener;
@Autowired
private HttpRestClient httpClient;
@RequestMapping("/toUserOperateLog")
public ModelAndView toLogin(String loginTargetUrl, Model model) {
return new ModelAndView("userOperate/userOperateLog");
}
//查询
@RequestMapping("/queryUserOperateLogList")
@ResponseBody
public BaseResponse queryUserOperateLogList(SqlOpLogsReq req) {
BaseResponse response = httpClient.defaultPost(HttpUriContants.GET_MIPS_RECORD_FROM_OPS_DB_FORBID, req,
BaseResponse.class);
return response;
}
//刷新
@RequestMapping("/flusher")
@ResponseBody
public String flusher() {
userOperateListener.flusher();
return "success";
}
}
... ...
package com.ui.interceptor;
import com.ui.User.UserAuthLocal;
import com.ui.User.UserOperateListener;
import com.ui.model.Directional;
import com.ui.model.req.User;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
... ... @@ -14,7 +12,6 @@ import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
public class AuthInterceptor implements HandlerInterceptor {
... ... @@ -23,8 +20,8 @@ public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private UserAuthLocal userAuthLocal;
@Autowired
UserOperateListener userOperateListener;
/*@Autowired
UserOperateListener userOperateListener;*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
... ... @@ -33,7 +30,7 @@ public class AuthInterceptor implements HandlerInterceptor {
if(null!=u){
String name = u.getName();
String path = getPath(request);
userOperateListener.add(name,request.getRequestURI());//记录用户操作
//userOperateListener.add(name,request.getRequestURI());//记录用户操作
if(!userAuthLocal.auth(name,path)){
response.sendRedirect("/dashboard/toDashboard");
return false;
... ...
package com.ui.interceptor;
import com.ui.User.UserOperateEnum;
import com.ui.User.UserOperateListener;
import com.ui.model.req.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Objects;
import static com.ui.User.UserOperateEnum.getAspectByUri;
/**
* Created by craig.qin on 2018/1/29.
* 操作记录
*/
@Aspect
@Component
public class UserOperateLog {
@Autowired
UserOperateListener userOperateListener;
@Pointcut("execution(* com.ui.ctrl..*(..))")
public void controller() { }
@Before("controller()")
public void controller(JoinPoint point) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
User u = (User) session.getAttribute("user");
if(null!=u){
String name=u.getName();
String uri=request.getRequestURI();
if(uri==null){
uri="";
}
uri = uri.trim();
while(uri.indexOf("//")==0){
uri = uri.substring(1);
}
UserOperateEnum userOperateEnum=UserOperateEnum.getAspectByUri(uri);
if(userOperateEnum!=null){
String operateDesc=userOperateEnum.getDesc(userOperateEnum);
String param=getMethodInfo(point);
userOperateListener.add(name,uri,operateDesc,param);//记录用户操作
}
/*MethodSignature signature = (MethodSignature) point.getSignature();
Long count = Stream.of(signature.getMethod().getDeclaredAnnotations())
.filter(annotation -> annotation.annotationType() == RequestMapping.class)
.count();
String requestPath = count >= 1 ? signature.getMethod().getAnnotation(RequestMapping.class).value()[0] : "";
String info = String.format("path:%s | %s", requestPath, getMethodInfo(point));
*/
}
}
private String getMethodInfo(JoinPoint point) {
// String className = point.getSignature().getDeclaringType().getSimpleName();
// String methodName = point.getSignature().getName();
String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
StringBuilder sb = null;
if (Objects.nonNull(parameterNames)) {
sb = new StringBuilder();
for (int i = 0; i < parameterNames.length; i++) {
String value = point.getArgs()[i] != null ? point.getArgs()[i].toString() : "";
sb.append(parameterNames[i] + ":" + value + "; ");
}
}
sb = sb == null ? new StringBuilder() : sb;
//String info = String.format("class:%s | method:%s | args:%s", className, methodName, sb.toString());
return sb.toString();
}
}
\ No newline at end of file
... ...
<%--
Created by IntelliJ IDEA.
User: meiling.ge
Date: 2017/9/21
Time: 16:25
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<%=basePath %>css/bootstrap.min.css"/>
<link rel="stylesheet" href="<%=basePath %>css/unicorn.main.css"/>
<link rel="stylesheet" href="<%=basePath %>css/unicorn.grey.css"/>
<link rel="stylesheet" href="<%=basePath %>css/jquery-ui.css"/>
<link rel="stylesheet" href="<%=basePath %>css/bootstrap-responsive.min.css"/>
<link rel="stylesheet" href="<%=basePath %>css/uniform.css"/>
<link rel="stylesheet" href="<%=basePath %>css/select2.css"/>
<script src="<%=basePath %>js/excanvas.min.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/jquery-1.12.0.min.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/jquery-ui.custom.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>/js/bootstrap.min.js"></script>
<script src="<%=basePath %>/js/unicorn.js"></script>
<script src="<%=basePath %>js/bootstrap-plugin/datetimepicker/moment-with-locales.js" charset="UTF-8"
type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/datetimepicker/bootstrap-datetimepicker.js" charset="UTF-8"
type="text/javascript"></script>
<script src="<%=basePath %>js/global.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.pagination.js" charset="UTF-8"
type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.table.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.dialog.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.form.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.panel.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.alerts.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.accordion.js" charset="UTF-8"
type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.breadcrumb.js" charset="UTF-8"
type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.validate.js" charset="UTF-8"
type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.form.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/layer/layer.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/bootstrap.select.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/jstree/jstree.min.js"></script>
<script src="<%=basePath %>js/jquery.toaster.js"></script>
<script src="<%=basePath %>js/laydate/laydate.js" charset="UTF-8" type="text/javascript"></script>
<script src="<%=basePath %>js/bootstrap-plugin/tableExport.min.js" charset="UTF-8" type="text/javascript"></script>
<script>
var contextPath = '<%=basePath %>';
</script>
<title>YOHO!运维</title>
</head>
<body>
<!-- 头部 -->
<div id="head">
</div>
<!-- 右侧具体内容 -->
<div id="content">
<div id="breadcrumb">
<a href="#" title="Go to Home" class="tip-bottom"><i
class="icon-home"></i> Home</a> <a href="#" class="current">用户重要操作记录</a>
</div>
<div class="container-fluid">
<div class="widget-box">
<div class="widget-title">
<h5>重要操作记录</h5>
</div>
<div class="widget-title" style="height: 56px;">
<div>
<div class="form-inline" role="form" id="inBoxQueryDiv" style=" margin-top: 12px;margin-left: 25px;float: left;">
<div class="input-group" style="float: left;margin-left: 20px">
<span class="input-group-addon">开始日期:</span>
<input id="beginTime"type="text" class="form-control dateTimeInput" style="width:150px;" />
</div>
<div class="input-group" style="float: left;margin-left: 20px">
<span class="input-group-addon">结束日期:</span>
<input id="endTime"type="text" class="form-control dateTimeInput" style="width:150px;" />
</div>
<button id="searchSqlLogsBtn" class="btn btn-primary" style="margin-left: 18px;" >搜索</button>
</div>
</div>
</div>
<div id="ipTable" style="overflow-y: auto; overflow-x:hidden;max-height: 700px" />
</div>
</div>
</div>
</body>
<script src="<%=basePath %>script/common/genarate_left_panel.js"></script>
<script>
$("#li_mip").addClass("active open");
$("#li_malicious_record").addClass("active");
</script>
<script type="text/javascript">
$(function () {
lay('.dateTimeInput').each(function(){
laydate.render({
elem: this ,type: 'datetime'
,trigger: 'click'
});
});
refreshTable();
});
//点击搜索按钮
$("#searchSqlLogsBtn").click(function () {
var beginTime = $.trim($("#beginTime").val());
var endTime = $.trim($("#endTime").val());
$("#ipTable").table("load", {
'beginTime':beginTime,
'endTime':endTime
});
});
function refreshTable(){
$("#ipTable").table({
url: contextPath + "userOperateLog/queryUserOperateLogList",
dataType: 'json',
striped: true,
pagination: true,
pageSize: 10,
//sortName: 'count', // 设置默认排序为 name
//sortOrder: 'desc', // 设置排序为反序 desc
panelClass: "panel-success",
loadFilter: function (data) {
return defaultLoadFilter(data);
},
columns: [
{
title: "用户名",
width: "15%",
field: "userName"
}, {
title: "操作",
width: "15%",
field: "operateDesc"
},{
title: "uri",
width: "10%",
field: "operate"
},
{
title: "参数",
width: "50%",
field: "params",
align: "left",
styler : function(value, rowData, rowIndex){
return {
"vertical-align" : "middle"
};
}
},
{
title: "时间",
field: "createTime",
width: "10%",
formatter:function (value,rowData,rowIndex) {
if(value !=null && value!=""){
return format(value);
}
return value;
}
}]
});
}
//timeValue---时间戳
function format(timeValue){
var time = new Date(timeValue);
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
var h = time.getHours();
var mm = time.getMinutes();
var s = time.getSeconds();
return y+'-'+add0(m)+'-'+add0(d)+' '+add0(h)+':'+add0(mm)+':'+add0(s);
}
function add0(m){
return m<10 ? '0'+m : m;
}
</script>
</html>
... ...