内网IP拦截器

该博客介绍了如何在Spring MVC配置中设置过滤器和拦截器。通过`WebMvcConfigurer`接口实现拦截器注册,用于企业备案信息接口的权限验证。拦截器检查请求的IP地址,如果属于内网则允许访问,否则返回错误信息。同时展示了如何使用`XssFilter`过滤XSS攻击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import com.xmeport.framework.filter.XssFilter;
import com.xmeport.project.interceptor.GetEntApiInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * ClassName: WebMvcAutoConfiguration
 * Function:  Spring MVC配置
 *
 */
@Configuration
public class WebMvcAutoConfiguration implements WebMvcConfigurer {

    @Autowired
    private GetEntApiInterceptor getEntApiInterceptor;

    /**
     * 过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new XssFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getEntApiInterceptor).addPathPatterns("/local/**");
    }
}
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import sun.net.util.IPAddressUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * Description: 企业备案信息接口拦截器
 *
 * @date: 2021/5/31 10:13
 */
@Component
public class GetEntApiInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI().substring(request.getContextPath().length());
        if (uri.endsWith("/")) {
            uri = uri.substring(0, uri.length() - 1);
        }
        if (uri.startsWith("/local")){
            String ip = getRemoteHost(request);
            byte[] addr = IPAddressUtil.textToNumericFormatV4(ip);
            if (internalIp(addr)){
                return super.preHandle(request, response, handler);
            }else {
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = response.getWriter();
                String info = "{\"status\":400,\"msg\":\"客户端的IP不属于内网IP,无法调用接口\",\"result\":[]}";
                out.print(info);
                out.close();
                out.flush();
                return false;
            }
        }
        return super.preHandle(request, response, handler);
    }

    /**
     * 获取IP地址
     */
    private String getRemoteHost(javax.servlet.http.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.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
    }

    /**
     * 判断是否内网IP地址
     */
    private boolean internalIp(byte[] addr) {
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        //10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        //172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        //192.168.x.x/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        //192.101.x.x
        final byte SECTION_7 = (byte) 0x65;
        switch (b0) {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4) {
                    return true;
                }
            case SECTION_5:
                switch (b1) {
                    case SECTION_6:
                    case SECTION_7:
                        return true;
                }
            default:
                return false;
        }
    }

}
import com.xmeport.framework.web.controller.SuperController;
import com.xmeport.framework.web.responses.ApiResponses;
import com.xmeport.project.model.entity.GEnt;
import com.xmeport.project.model.vo.ApiResult;
import com.xmeport.project.model.vo.GEntApiVO;
import com.xmeport.project.model.vo.GetEntRequestParamVO;
import com.xmeport.project.service.IGEntService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

/**
 * Description:企业备案信息接口
 *
 * @date: 2021/5/28 16:30
 */
@Slf4j
@RequestMapping("/local/api")
@AllArgsConstructor
@Controller
public class GetEntApiController extends SuperController {

    private IGEntService igEntService;

    /**
     * 获取用户信息
     */
    @PostMapping("/get-ent")
    @ResponseBody
    public ApiResult<List<GEntApiVO>> getEntApi(@RequestBody GetEntRequestParamVO paramVO){
        try{
            List<GEnt> list =  igEntService.query().eq(GEnt::getEntCodeCus,paramVO.getCusCode()).list();
            List<GEntApiVO> result = new ArrayList<>();
            for (GEnt gEnt : list) {
                GEntApiVO convert = gEnt.convert(GEntApiVO.class);
                result.add(convert);
            }
            return new ApiResult(HttpStatus.SC_OK,"操作成功",result);
        }catch( Exception e){
            e.printStackTrace();
            return new ApiResult(HttpStatus.SC_BAD_REQUEST,"操作失败",e.getMessage());
        }
    }
}
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 功能描述: 结果封装类
 *
 */
@Data
@AllArgsConstructor
public class ApiResult<T> {

    private Integer status;
    private String msg;
    private T result;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值