HandlerInterceptorAdapter实现简单拦截

以下是本人开发中使用的简单实现,望各位大神提出见解及改进方法,也写此博客记录

一、继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter类


package com.rzxt.test.common.auth;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rzxt.test.common.ResultCode;
import com.rzxt.test.common.constants.Constants;
import com.rzxt.test.common.utils.MD5Util;
import com.rzxt.test.common.utils.RedisUtil;
import com.rzxt.test.web.entity.AccessToken;
import com.rzxt.test.web.entity.BaseUser;
import com.rzxt.test.web.service.AccessService;
import com.rzxt.test.web.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;


/**
 * Created by lei.w on 2016/10/11 0020.
 */
public class AccessAuthInterceptor extends HandlerInterceptorAdapter {


    private static Logger logger = Logger.getLogger(LogHandler.LOG_SCHEMA_AUTH);


    @Autowired
    AccessService accessService;
    @Autowired
    UserService userService;




    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.debug("Access Auth Interceptor - 进入拦截器");
        //记录访问开始时间
        request.setAttribute("access_begin_time", System.currentTimeMillis());
        if (handler instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod) handler;
            AccessAuth accessAuth = method.getMethodAnnotation(AccessAuth.class);
            if (!ObjectUtils.isEmpty(accessAuth) && accessAuth.auth()) {
            } else {
                logger.debug("Access Auth Interceptor - 拦截器跳出");
                return true;
            }
        }
        logger.debug("Authorized Access - 拦截器开始");
        //return true;
        //request basic paramter
        String req_uid = request.getParameter(Constants.MOBILE_UID);
        String req_access_token = request.getParameter(Constants.MOBILE_ACCESS_TOKEN);
        logger.info("req uid  " + req_uid);
        logger.info("req access_token  " + req_access_token);
        //0.参数解析
        if (!StringUtils.isEmpty(req_access_token) && !StringUtils.isEmpty(req_uid) && req_access_token.length() == 87) {
            //fx+f+ts+token+v   2314d7e2ea7b4fe99b28042739f1af26 1 1477292375598 91a5e51dcc1028398394ee7889d20b46 000001000
            String req_token = req_access_token.substring(46, 78);
            String req_timestamp = req_access_token.substring(33, 46);
            String req_fx = req_access_token.substring(0, 32);
            String req_from = req_access_token.substring(32, 33);
            String req_version = req_access_token.substring(78, 87);
            logger.info("req token  " + req_token);
            logger.info("req timestamp  " + req_timestamp);
            logger.info("req fx  " + req_fx);
            logger.info("req from  " + req_from);
            logger.info("req version  " + req_version);
            //1.check 非空验证
            if (this.checkMobileEmpty(req_uid, req_token, req_timestamp, req_fx, req_from, req_version)) {
                //2.check ts时间戳
                if (this.checkTs(req_timestamp)) {
                    //3.check 用户权限
                    if (this.checkUserAuth(req_uid, req_token, req_from)) {
                        //4.check
                        if (this.check(req_uid, req_token, req_timestamp, req_fx, req_from, req_version)) {
                            //为aspect构造属性值
                            request.setAttribute(Constants.MOBILE_UID, req_uid);
                            request.setAttribute(Constants.MOBILE_TOKEN, req_token);
                            request.setAttribute(Constants.MOBILE_TIMESTAMP, req_timestamp);
                            request.setAttribute(Constants.MOBILE_FX, req_fx);
                            request.setAttribute(Constants.MOBILE_FROM, req_from);
                            request.setAttribute(Constants.MOBILE_VERSION, req_version);
                            request.setAttribute(Constants.MOBILE_URI, request.getRequestURI());
                            request.setAttribute(Constants.MOBILE_IP, this.getIPAddr(request));
                            return true;
                        } else {
                            out(response, ResultCode.AUTH_FAIL);
                            return false;
                        }
                    } else {
                        out(response, ResultCode.AUTH_RELOGIN);
                        return false;
                    }
                } else {
                    out(response, ResultCode.AUTH_FAIL);
                    return false;
                }
            } else {
                out(response, ResultCode.AUTH_FAIL);
                return false;
            }
        } else {
            logger.error("Access Auth Interceptor - 请求参数不完整");
            out(response, ResultCode.AUTH_FAIL);
            return false;
        }
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.debug("Access Auth Interceptor - interceptor auth execution time 拦截器验证执行时间:" + (System.currentTimeMillis() - Long.valueOf(request.getAttribute("access_begin_time").toString())) + "ms");
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.debug("Access Auth Interceptor - controller execution time 控制器方法执行时间:" + (System.currentTimeMillis() - Long.valueOf(request.getAttribute("access_begin_time").toString())) + "ms");
    }




    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }


    /**
     * 验证移动端参数非空
     *
     * @param req_uid
     * @param req_token
     * @param req_timestamp
     * @param req_fx
     * @param req_from
     * @param req_version
     * @return
     */
    private static final boolean checkMobileEmpty(String req_uid, String req_token, String req_timestamp, String req_fx, String req_from, String req_version) {
        if (!StringUtils.isEmpty(req_uid) && !StringUtils.isEmpty(req_token) && !StringUtils.isEmpty(req_timestamp) && !StringUtils.isEmpty(req_fx) && !StringUtils.isEmpty(req_from) && !StringUtils.isEmpty(req_version)) {
            return true;
        } else {
            logger.error("Access Auth Interceptor - 解析参数不完整");
            return false;
        }
    }


    /**
     * 验证时间戳ts
     *
     * @param req_timestamp
     * @return
     */
    private static final boolean checkTs(String req_timestamp) {
        if (Long.valueOf(req_timestamp) < System.currentTimeMillis() - 10 * 60 * 1000) {
            logger.error("Authorized Access - 超时访问");
            return false;
        } else {
            return true;
        }
    }


    /**
     * 验证token信息
     *
     * @param req_uid
     * @param req_token
     * @return
     */
    private final boolean checkUserAuth(String req_uid, String req_token, String req_side) {
        try {
            //1.验证uid是否存在
            logger.info("Access Auth Interceptor - UserAuth  [uid] = "+req_uid+" [token] = "+req_token+" [side] = "+req_side);
            BaseUser baseUser = userService.getUserById(Long.valueOf(req_uid));
            if (!ObjectUtils.isEmpty(baseUser)) {
                //2.验证token及side
                AccessToken accessToken = accessService.getAccessToken(Long.valueOf(req_uid));
                if (!ObjectUtils.isEmpty(accessToken) && !StringUtils.isEmpty(accessToken.getToken()) && req_token.equalsIgnoreCase(accessToken.getToken()) && !StringUtils.isEmpty(accessToken.getSide()) && req_side.equals(accessToken.getSide() + "")) {
                    return true;
                } else {
                    logger.error("Access Auth Interceptor - UserAuth token is null 权限验证失败 [uid] = "+req_uid+" [token] = "+req_token+" [side] = "+req_side);
                    return false;
                }
            } else {
                logger.error("Access Auth Interceptor - UserAuth User is null 权限验证失败 [uid] = "+req_uid+" [token] = "+req_token+" [side] = "+req_side);
                return false;
            }
            /*RedisUtil redisUtil = RedisUtil.getRu();
            String cache_token = redisUtil.get(Constants.CACHE_MOBILE_AUTH_TOKEN_PREFIX + req_uid);
            String cache_side = redisUtil.get(Constants.CACHE_MOBILE_AUTH_SIDE_PREFIX + req_uid);
            //data token
            String com_token = "";
            String com_side = "";
            if (!StringUtils.isEmpty(cache_token) && !StringUtils.isEmpty(cache_side)) {
                com_token = cache_token;
                com_side = cache_side;
                logger.debug("token and side cache");
            } else {
                logger.debug("token and side no cache");
                AccessToken accessToken = accessService.getAccessToken(Integer.valueOf(req_uid));
                if (!ObjectUtils.isEmpty(accessToken) && !StringUtils.isEmpty(accessToken.getToken()) && !StringUtils.isEmpty(accessToken.getSide())) {
                    com_token = accessToken.getToken();
                    com_side = accessToken.getSide()+"";
                    redisUtil.set(Constants.CACHE_MOBILE_AUTH_TOKEN_PREFIX + req_uid, com_token);
                    redisUtil.set(Constants.CACHE_MOBILE_AUTH_SIDE_PREFIX + req_uid, com_side);
                    logger.debug("token and side set cache from database");
                }
            }*/
        } catch (Exception e) {
            logger.error("Access Auth Interceptor - UserAuth权限验证失败,程序异常");
            return false;
        }
    }


    /**
     * 验证
     *
     * @param req_uid
     * @param req_token
     * @param req_timestamp
     * @param req_fx
     * @return
     */
    private static final boolean check(String req_uid, String req_token, String req_timestamp, String req_fx, String req_from, String req_version) {
        logger.info("MD5加密 :" + MD5Util.MD5(req_uid + "_" + req_timestamp + "_" + req_from + "_" + req_version + "_" + req_token).toLowerCase());
        if (req_fx.equalsIgnoreCase(MD5Util.MD5(req_uid + "_" + req_timestamp + "_" + req_from + "_" + req_version + "_" + req_token))) {
            return true;
        } else {
            logger.error("Access Auth Interceptor - 签名验证失败");
            return false;
        }
    }


    /**
     * 错误信息
     *
     * @param resultCode
     * @return
     */
    private static final Map<String, Object> resultFail(ResultCode resultCode) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", resultCode.getCode());
        map.put("msg", resultCode.getMessage());
        return map;
    }


    /**
     * 返回输出json
     *
     * @param response
     * @param resultCode
     */
    private static final void out(HttpServletResponse response, ResultCode resultCode) {
        ObjectMapper objectMapper = new ObjectMapper();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(objectMapper.writeValueAsString(resultFail(resultCode)));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }


    /**
     * 获取http请求的真实IP地址
     *
     * @param request
     * @return
     */
    private static String getIPAddr(HttpServletRequest request) {
        if (request == null)
            return null;
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = request.getHeader("Proxy-Client-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = request.getHeader("WL-Proxy-Client-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = request.getHeader("HTTP_CLIENT_IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = request.getRemoteAddr();
        if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip))
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException unknownhostexception) {
            }
        return ip;
    }


    public static void main(String[] args) {
    }


}

二、配置xml加载文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd"
>


    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
            <!-- 用户相关 -->
            <mvc:mapping path="/test/**"/>
            <bean class="com.rzxt.test.common.auth.AccessAuthInterceptor"></bean>
        </mvc:interceptor>
        <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
    </mvc:interceptors>


</beans>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值