一种基于struts2 拦截器 和 log4j的轻量级crm权限及行为跟踪方式

拦截器


public class CrmTokenInterceptor extends AbstractInterceptor
{
    private static final long serialVersionUID = -6027604464670201140L;
    private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(CrmTokenInterceptor.class);

    @Autowired
    private AuthAccessor authAccessor;

    private String userId = null;

    @Autowired
    private TokenService ts;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception{

        ActionContext actionContext = invocation.getInvocationContext();
        HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);

        HttpServletResponse response = ServletActionContext.getResponse();
        response.setHeader("Access-Control-Allow-Origin", "*");

        String token = request.getParameter("token");
        String termType = request.getParameter("termType");
        System.out.println("========="+request.getRequestURI());
        String sPath = request.getServletPath();
        //System.out.println(sPath);
        SpResult spResult = new SpResult();
        String res = null;

        if (token == null || token.equals("")) {

            spResult.setHeaderCode("400");
            spResult.setHeaderMessage(MesResult.messageInfo(MesResult.LOGIN, termType));
            spResult.setBody(null);

            actionContext.put("spResult", spResult);
            res = "tokenError";
        }else {
            token = token.replaceAll(" ", "+");

            //userId = ts.getUserId(token);
            User u = ts.getUserId(token);
            if(u == null) {
                spResult.setHeaderCode("400");
                spResult.setHeaderMessage(MesResult.messageInfo(MesResult.LOGIN, termType));
                spResult.setBody(null);

                actionContext.put("spResult", spResult);
                res = "tokenError";
            } else {
                userId=String.valueOf(u.getUserId());
                String methodName=invocation.getProxy().getMethod();
                Method currentMethod=invocation.getAction().getClass().getMethod(methodName, null);
                if(currentMethod.isAnnotationPresent(Authority.class)){
                    //获取权限校验的注解
                    Authority authority=currentMethod.getAnnotation(Authority.class);
                    //获取当前请求的注解的actionName
                    String actionName=authority.actionName();
                    //获取当前请求需要的权限
                    String privilege=authority.privilege();

                    //可以在此判断当前客户是否拥有对应的权限,如果没有可以跳到指定的无权限提示页面,如果拥有则可以继续往下执行。
                    Map<String,String> map = new HashMap<String,String>();
                    map.put("userInfoId", userId);
                    map.put("actionName", actionName);
                    map.put("actionAuth", privilege);
                    map.put("isDeleted", "0");
                    List<Map<String,String>> re = authAccessor.adminAuth(map);
                    if(re == null || (re != null && re.size() == 0)) {
                        spResult = new SpResult();
                        spResult.setHeaderCode("400");
                        spResult.setHeaderMessage(String.format("无此权限。%s-%s", actionName, privilege));
                        spResult.setBody(null);
                        actionContext = invocation.getInvocationContext();
                        actionContext.put("spResult", spResult);
                        res = "authError";
                    } else {

                        // 终于使其正常执行
                        invocation.getStack().setValue("userId",userId);
                        res =  invocation.invoke();

                        // 记录执行,不考虑执行过程的异常
                        String namespace = invocation.getProxy().getNamespace();
                        String actionNameEx = invocation.getProxy().getActionName();
                        Map paramMap = request.getParameterMap();
                        String paras = JsonUtils.convert(paramMap);
                        map.clear();
                        map.put("userInfoId", userId);
                        map.put("namespace", namespace);
                        map.put("actionName", actionNameEx);
                        map.put("paras", paras);
                        LOGGER.info(userId);
                        LOGGER.info(namespace);
                        LOGGER.info(actionNameEx);
                        LOGGER.info(paras);
                        LOGGER.info("\n");
                    }
                }
            }
        }
        return res;
    }
}



log4j:

	<logger name="com.xxx.xxx.impl.interceptor.CrmTokenInterceptor"
			additivity="false">
		<level value="INFO" /><!--子类warn级别覆盖info-->
		<appender-ref ref="crmAccessAppender" />
	</logger>

	<appender name="crmAccessAppender" class="org.apache.log4j.DailyRollingFileAppender">
		<param name="File" value="/data/applogs/urgoo-service/logs/crmAccess.log" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %m%n" />
		</layout>
	</appender>


                if(currentMethod.isAnnotationPresent(Authority.class)){
                    //获取权限校验的注解
                    Authority authority=currentMethod.getAnnotation(Authority.class);
                    //获取当前请求的注解的actionName
                    String actionName=authority.actionName();
                    //获取当前请求需要的权限
                    String privilege=authority.privilege();

                    //可以在此判断当前客户是否拥有对应的权限,如果没有可以跳到指定的无权限提示页面,如果拥有则可以继续往下执行。
                    Map<String,String> map = new HashMap<String,String>();
                    map.put("userInfoId", userId);
                    map.put("actionName", actionName);
                    map.put("actionAuth", privilege);
                    map.put("isDeleted", "0");
                    List<Map<String,String>> re = authAccessor.adminAuth(map);
                    if(re == null || (re != null && re.size() == 0)) {
                        spResult = new SpResult();
                        spResult.setHeaderCode("400");
                        spResult.setHeaderMessage(String.format("无此权限。%s-%s", actionName, privilege));
                        spResult.setBody(null);
                        actionContext = invocation.getInvocationContext();
                        actionContext.put("spResult", spResult);
                        res = "authError";



这一段是获得action的权限注解值,见http://blog.csdn.net/silyvin/article/details/54425212,没有添加注解的无此宫内,然后到数据库中查询某人是否由权限进行该操作


如果无权限:

则返回警告消息


如果有权限,记录相应的namespace   actionname  参数   userId(操作人)


                        // 终于使其正常执行
                        invocation.getStack().setValue("userId",userId);
                        res =  invocation.invoke();

                        // 记录执行,不考虑执行过程的异常
                        String namespace = invocation.getProxy().getNamespace();
                        String actionNameEx = invocation.getProxy().getActionName();
                        Map paramMap = request.getParameterMap();
                        String paras = JsonUtils.convert(paramMap);
                        map.clear();
                        map.put("userInfoId", userId);
                        map.put("namespace", namespace);
                        map.put("actionName", actionNameEx);
                        map.put("paras", paras);
                        LOGGER.info(userId);
                        LOGGER.info(namespace);
                        LOGGER.info(actionNameEx);
                        LOGGER.info(paras);
                        LOGGER.info("\n");


效果:

2017-01-21 17:22:17,480 -1
2017-01-21 17:22:17,480 /adminToken
2017-01-21 17:22:17,480 selectBaseServiceLongByServiceTypeSingle
2017-01-21 17:22:17,481 {"xxx_CALLBACK":["JSON_CALLBACK"],"serviceType":["1"],"token":["ss"]}
2017-01-21 17:22:17,481

2017-01-21 17:27:22,466 -1
2017-01-21 17:27:22,466 /adminToken
2017-01-21 17:27:22,466 selectBaseService
2017-01-21 17:27:22,466 {"ccc_CALLBACK":["JSON_CALLBACK"],"token":["ss"]}
2017-01-21 17:27:22,466 



有两个缺点:

1. 记录的东西不太好再进行自动化分析,必须有人的介入

2. 暂无法分布式部署

posted on 2017-01-21 17:23  silyvin  阅读(134)  评论(0编辑  收藏  举报