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

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

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


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

项目结构:

功能代码:

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

package com.tgb.lk.auditlog;

import java.lang.reflect.Method;
import java.util.Date;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
import com.tgb.lk.model.AuditLog;

public class AuditLogInterceptor extends MethodFilterInterceptor {

	@Override
	protected String doIntercept(ActionInvocation actioninvocation)
			throws Exception {
		AuditLog auditLog = new AuditLog();

		auditLog.setStartTime(new Date());// 设置开始时间
		String result = actioninvocation.invoke();// 递归调用拦截器
		auditLog.setEndTime(new Date());// 设置结束时间

		String userId = (String) ServletActionContext.getRequest().getSession()
				.getAttribute("userId");
		auditLog.setUserId(userId);// 设置登录用户的Id,在用户登录时把id保存到session中,这里可扩展判断用户是否登录的验证和权限验证
		/*String name = actioninvocation.getInvocationContext().getName();
		String methodName = "";

		// struts.xml中配置:
		// <package name="user" namespace="/user" extends="default">
		// <action name="user_*" class="com.tgb.lk.action.UserAction" method="{1}">
		//
		// 访问地址: http://127.0.0.1:8080/AuditLogDemo/user/user_add
		// http://127.0.0.1:8080/AuditLogDemo/user/user_del
		if (name != null && name.contains("_")) {
			methodName = name.substring(name.indexOf("_") + 1, name.length());
		}*/
		String methodName = actioninvocation.getProxy().getMethod();
		if (methodName.length() > 0) {
			Object action = actioninvocation.getAction();
			Class clazz = action.getClass();
			// 如果设置了注解则读取注解的内容,如果没有设置注解则记录登录的class名
			if (clazz.isAnnotationPresent(AuditLogger.class)) {
				AuditLogger talClazz = (AuditLogger) clazz
						.getAnnotation(AuditLogger.class);
				auditLog.setClazz(talClazz.log());
			} else {
				auditLog.setClazz(clazz.getSimpleName());
			}

			Method method = action.getClass().getMethod(methodName, null);
			// 如果设置了注解则读取注解的内容,如果没有设置注解则记录登录的method名
			if (method.isAnnotationPresent(AuditLogger.class)) {
				AuditLogger alm = (AuditLogger) method
						.getAnnotation(AuditLogger.class);
				auditLog.setMethod(alm.log());
			} else {
				auditLog.setMethod(methodName);
			}
			String ip = ServletActionContext.getRequest().getRemoteAddr();
			auditLog.setIp(ip);// 记录登录的IP,这里还可以对IP进行鉴权功能(允许或限制某些IP)
			auditLog.setResult(result);// 记录登录时返回的结果.

			System.out.println(auditLog);
			// auditLogService.save(auditLog); //保存入库
		}
		return result; // 跳转
	}

}


struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

	<constant name="struts.devMode" value="true" />
	<package name="default" namespace="/" extends="struts-default">
		<interceptors>
			<!-- 日志审计拦截器 -->
			<interceptor name="auditlog"
				class="com.tgb.lk.auditlog.AuditLogInterceptor" />
			<interceptor-stack name="myStack">
				<interceptor-ref name="auditlog">
					<!--
						配置到excludeMethods中的方法将不记录日志
					-->
					<param name="excludeMethods">testExclude</param>
				</interceptor-ref>
				<!--
					struts默认的拦截器
				-->
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="myStack" />
	</package>
	
	<!-- 注意extends="default" -->
	<package name="user" namespace="/user" extends="default">
		<action name="user_*" class="com.tgb.lk.action.UserAction" method="{1}">
			<result name="add">/index.jsp</result>
			<result name="del">/index.jsp</result>
			<result name="modify">/index.jsp</result>
			<result name="view">/index.jsp</result>
		</action>
	</package>

</struts>

注解类AuditLogger.java:

package com.tgb.lk.auditlog;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target( { java.lang.annotation.ElementType.METHOD,
		java.lang.annotation.ElementType.TYPE })
public @interface AuditLogger {

	public abstract String log();

}
Struts的Action中使用配置:

package com.tgb.lk.action;

import com.tgb.lk.auditlog.AuditLogger;

@AuditLogger(log = "用户管理")
public class UserAction {

	@AuditLogger(log = "添加用户")
	public String add() {
		return "add";
	}

	@AuditLogger(log = "删除用户")
	public String del() {
		return "del";
	}

	@AuditLogger(log = "修改用户")
	public String modify() {
		return "modify";
	}

	@AuditLogger(log = "浏览用户信息")
	public String view() {
		return "view";
	}

}
实体类AuditLog.java

package com.tgb.lk.model;

import java.util.Date;

public class AuditLog {
	private int id;
	private String userId;
	private Date startTime;
	private Date endTime;
	private String ip;
	private String clazz;
	private String method;
	private String result;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public Date getStartTime() {
		return startTime;
	}

	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

	public Date getEndTime() {
		return endTime;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getClazz() {
		return clazz;
	}

	public void setClazz(String clazz) {
		this.clazz = clazz;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	@Override
	public String toString() {
		return "AuditLog [id=" + id + ", userId=" + userId + ", ip=" + ip
				+ ", startTime=" + startTime + ", endTime=" + endTime
				+ ", clazz=" + clazz + ", method=" + method + ", result="
				+ result + "]";
	}

}

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值