使用struts拦截器+注解实现网络安全要求中的日志审计功能

J2EE项目中出于安全的角度考虑,用户行为审计日志功能必不可少,通过本demo可以实现如下功能:
1.项目中记录审计日志的方法.
2.struts拦截器的基本配置和使用方法.
3.struts拦截器中获得用户访问的类和访问的方法.
4.注解的基本用法,以及在struts拦截器中使用注解.

5.struts拦截器中获得用户访问的IP地址,可扩展对IP进行鉴权功能(允许或限制某些IP).

 

系统运行一段时间后,通过这些审计日志还可以挖掘的内容:
1.用户行为审计,发现最异常情况及时调整和处理.
2.统计哪些模块访问的频度最高,调整界面把用户访问最高的模块放到显著位置.
3.统计各个功能模块方法的访问时长,有助于我们进行程序性能的优化.
4.用户关联行为分析,优化访问流程,提高用户体验.

项目结构:

功能代码:

AuditLogInterceptor.java(知识点见注释):

 

[java][/java] view plaincopy

  1. package com.tgb.lk.auditlog;
  2. import java.lang.reflect.Method;
  3. import java.util.Date;
  4. import org.apache.struts2.ServletActionContext;
  5. import com.opensymphony.xwork2.ActionInvocation;
  6. import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
  7. import com.tgb.lk.model.AuditLog;
  8. public class AuditLogInterceptor extends MethodFilterInterceptor {
  9.     @Override
  10.     protected String doIntercept(ActionInvocation actioninvocation)
  11.             throws Exception {
  12.         AuditLog auditLog = new AuditLog();
  13.         auditLog.setStartTime(new Date());// 设置开始时间
  14.         String result = actioninvocation.invoke();// 递归调用拦截器
  15.         auditLog.setEndTime(new Date());// 设置结束时间
  16.         String userId = (String) ServletActionContext.getRequest().getSession()
  17.                 .getAttribute(“userId”);
  18.         auditLog.setUserId(userId);// 设置登录用户的Id,在用户登录时把id保存到session中,这里可扩展判断用户是否登录的验证和权限验证
  19.         String name = actioninvocation.getInvocationContext().getName();
  20.         String methodName = “”;
  21.         // struts.xml中配置:
  22.         // <package name=”user” namespace=”/user” extends=”default”>
  23.         // <action name=”user_*” class=”com.tgb.lk.action.UserAction” method=”{1}”>
  24.         //
  25.         // 访问地址: http://127.0.0.1:8080/AuditLogDemo/user/user_add
  26.         // http://127.0.0.1:8080/AuditLogDemo/user/user_del
  27.         if (name != null && name.contains(“_”)) {
  28.             methodName = name.substring(name.indexOf(“_”) + 1, name.length());
  29.         }
  30.         if (methodName.length() > 0) {
  31.             Object action = actioninvocation.getAction();
  32.             Class clazz = action.getClass();
  33.             // 如果设置了注解则读取注解的内容,如果没有设置注解则记录登录的class名
  34.             if (clazz.isAnnotationPresent(AuditLogger.class)) {
  35.                 AuditLogger talClazz = (AuditLogger) clazz
  36.                         .getAnnotation(AuditLogger.class);
  37.                 auditLog.setClazz(talClazz.log());
  38.             } else {
  39.                 auditLog.setClazz(clazz.getSimpleName());
  40.             }
  41.             Method method = action.getClass().getMethod(methodName, null);
  42.             // 如果设置了注解则读取注解的内容,如果没有设置注解则记录登录的method名
  43.             if (method.isAnnotationPresent(AuditLogger.class)) {
  44.                 AuditLogger alm = (AuditLogger) method
  45.                         .getAnnotation(AuditLogger.class);
  46.                 auditLog.setMethod(alm.log());
  47.             } else {
  48.                 auditLog.setMethod(methodName);
  49.             }
  50.             String ip = ServletActionContext.getRequest().getRemoteAddr();
  51.             auditLog.setIp(ip);// 记录登录的IP,这里还可以对IP进行鉴权功能(允许或限制某些IP)
  52.             auditLog.setResult(result);// 记录登录时返回的结果.
  53.             System.out.println(auditLog);
  54.             // auditLogService.save(auditLog); //保存入库
  55.         }
  56.         return result; // 跳转
  57.     }
  58. }

struts.xml:

 

 

[html][/html] view plaincopy

  1. <?xml version=”1.0″ encoding=”UTF-8″ ?>
  2. <!DOCTYPE struts PUBLIC
  3.     “-//Apache Software Foundation//DTD Struts Configuration 2.3//EN”
  4.     “http://struts.apache.org/dtds/struts-2.3.dtd”>
  5. <struts>
  6.     <constant name=”struts.devMode” value=”true” />
  7.     <package name=”default” namespace=”/” extends=”struts-default”>
  8.         <interceptors>
  9.             <!– 日志审计拦截器 –>
  10.             <interceptor name=”auditlog”
  11.                 class=”com.tgb.lk.auditlog.AuditLogInterceptor” />
  12.             <interceptor-stack name=”myStack”>
  13.                 <interceptor-ref name=”auditlog”>
  14.                     <!–
  15.                         配置到excludeMethods中的方法将不记录日志
  16.                     –>
  17.                     <param name=”excludeMethods”>testExclude</param>
  18.                 </interceptor-ref>
  19.                 <!–
  20.                     struts默认的拦截器
  21.                 –>
  22.                 <interceptor-ref name=”defaultStack” />
  23.             </interceptor-stack>
  24.         </interceptors>
  25.         <default-interceptor-ref name=”myStack” />
  26.     </package>
  27.     <!– 注意extends=”default” –>
  28.     <package name=”user” namespace=”/user” extends=”default”>
  29.         <action name=”user_*” class=”com.tgb.lk.action.UserAction” method=”{1}”>
  30.             <result name=”add”>/index.jsp</result>
  31.             <result name=”del”>/index.jsp</result>
  32.             <result name=”modify”>/index.jsp</result>
  33.             <result name=”view”>/index.jsp</result>
  34.         </action>
  35.     </package>
  36. </struts>

注解类AuditLogger.java:

 

 

[java][/java] view plaincopy

  1. package com.tgb.lk.auditlog;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. @Retention(RetentionPolicy.RUNTIME)
  6. @Target( { java.lang.annotation.ElementType.METHOD,
  7.         java.lang.annotation.ElementType.TYPE })
  8. public @interface AuditLogger {
  9.     public abstract String log();
  10. }

Struts的Action中使用配置:

 

 

[java][/java] view plaincopy

  1. package com.tgb.lk.action;
  2. import com.tgb.lk.auditlog.AuditLogger;
  3. @AuditLogger(log = “用户管理”)
  4. public class UserAction {
  5.     @AuditLogger(log = “添加用户”)
  6.     public String add() {
  7.         return “add”;
  8.     }
  9.     @AuditLogger(log = “删除用户”)
  10.     public String del() {
  11.         return “del”;
  12.     }
  13.     @AuditLogger(log = “修改用户”)
  14.     public String modify() {
  15.         return “modify”;
  16.     }
  17.     @AuditLogger(log = “浏览用户信息”)
  18.     public String view() {
  19.         return “view”;
  20.     }
  21. }

实体类AuditLog.java

 

 

[java][/java] view plaincopy

  1. package com.tgb.lk.model;
  2. import java.util.Date;
  3. public class AuditLog {
  4.     private int id;
  5.     private String userId;
  6.     private Date startTime;
  7.     private Date endTime;
  8.     private String ip;
  9.     private String clazz;
  10.     private String method;
  11.     private String result;
  12.     public int getId() {
  13.         return id;
  14.     }
  15.     public void setId(int id) {
  16.         this.id = id;
  17.     }
  18.     public String getUserId() {
  19.         return userId;
  20.     }
  21.     public void setUserId(String userId) {
  22.         this.userId = userId;
  23.     }
  24.     public Date getStartTime() {
  25.         return startTime;
  26.     }
  27.     public void setStartTime(Date startTime) {
  28.         this.startTime = startTime;
  29.     }
  30.     public Date getEndTime() {
  31.         return endTime;
  32.     }
  33.     public void setEndTime(Date endTime) {
  34.         this.endTime = endTime;
  35.     }
  36.     public String getIp() {
  37.         return ip;
  38.     }
  39.     public void setIp(String ip) {
  40.         this.ip = ip;
  41.     }
  42.     public String getClazz() {
  43.         return clazz;
  44.     }
  45.     public void setClazz(String clazz) {
  46.         this.clazz = clazz;
  47.     }
  48.     public String getMethod() {
  49.         return method;
  50.     }
  51.     public void setMethod(String method) {
  52.         this.method = method;
  53.     }
  54.     public String getResult() {
  55.         return result;
  56.     }
  57.     public void setResult(String result) {
  58.         this.result = result;
  59.     }
  60.     @Override
  61.     public String toString() {
  62.         return “AuditLog [id=” + id + “, userId=” + userId + “, ip=” + ip
  63.                 + “, startTime=” + startTime + “, endTime=” + endTime
  64.                 + “, clazz=” + clazz + “, method=” + method + “, result=”
  65.                 + result + “]”;
  66.     }
  67. }

代码下载地址: http://download.csdn.net/detail/lk_blog/6002371

 

限于本人水平有限,很多地方写的并不完美,望大家不吝赐教,希望在和大家的交流中得到提高.

标签