Spring boot之拦截器的实现

  • 场景:由于用Spring boot编写了关于Ranger策略以及Hive脱敏相关的接口,并以http方式向外部提供。为了防止请求被非法模仿,因而编写了一个访问Ip 鉴权类,也就是设置了访问ip白名单,只有在白名单上的ip才可以访问接口。
  • Spring boot自带HandlerInterceptor,可通过继承它来实现拦截功能,其的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。我们不能通过拦截器修改request内容,但是可以通过抛出异常(或者返回false)来暂停request的执行。

代码如下所示:

1、创建拦截器,并实现业务逻辑

package com.bms.utils;

import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.logging.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author YeChunBo
 * @time 2017年9月8日
 *
 *       类说明: ip 拦截器,只有在配置文件中定义了的ip 才可以访问接口
 */

public class URLInterceptor implements HandlerInterceptor {

    private static final Logger logger = Logger.getLogger(URLInterceptor.class);

    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub

    }

    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        // TODO Auto-generated method stub

    }

    /**
     * 在请求处理之前进行调用(Controller方法调用之前)调用,
     *  返回true 则放行, false 则将直接跳出方法
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        String ip = getIpAddr(request);
        String ipStr = PropertyUtil.getProperty("ipWhiteList"); // 获取可以访问系统的白名单
        String[] ipArr = ipStr.split("\\|");
        List<String> ipList = java.util.Arrays.asList(ipArr);

        if (ipList.contains(ip)) {
            logger.info("the request ip is : " + ip);
            return true;
        } else {
            logger.error(ip + " is not contains ipWhiteList .......");
            response.setHeader("Content-type","text/html;charset=UTF-8");//向浏览器发送一个响应头,设置浏览器的解码方式为UTF-8
            String data = "您好,ip为" + ip + ",暂时没有访问权限,请联系管理员开通访问权限。";
            OutputStream stream = response.getOutputStream();
            stream.write(data.getBytes("UTF-8"));
            return false;
        }
    }

    /**
     * 获取访问的ip地址
     * 
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        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();
        }
        return ip;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

2、注册拦截器

package com.bms.utils;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
* @author YeChunBo
* @time 2017年9月8日 
*
* 类说明: ip 鉴权类,只有在配置文件中定义了的ip 才可以访问接口
*/

@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {

    @Bean   //把我们的拦截器注入为bean
    public HandlerInterceptor getMyInterceptor(){
        return new URLInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 用于添加拦截规则, 这里假设拦截 /url 后面的全部链接
        // excludePathPatterns 用户排除拦截
        registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

访问结果如下所示: 
这里写图片描述 

猜你喜欢

转载自blog.csdn.net/xinzi11243094/article/details/80838847