springboot中对接口请求进行ip白名单过滤

本文介绍了一个Spring MVC应用程序中实现请求拦截的方法,并详细展示了如何通过自定义拦截器来验证客户端IP是否在白名单中。同时提供了获取真实IP地址的实用工具类。
1. 请求拦截器代码
/**
 * @author: 
 * @date: 2021-10-19 16:44
 * @description: 拦截http请求并加载请求url信息
 */
@Component
public class RequestUrlInterceptor implements HandlerInterceptor {

    @Value("${ipList}")
    private String ipList;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        String url = request.getRequestURL().toString();
        if (StrUtil.isNotEmpty(ipList)){
            String[] ipArr = ipList.split(",");
            List<String> ipLists = CollUtil.newArrayList(ipArr);
            String nowIp = IpUtils.getRealIP(request);
            if (StrUtil.isNotEmpty(nowIp)){
                if (!ipLists.contains(nowIp)){
                    response.getWriter().append("<h1 style=\"text-align:center;\">IP is not in the whitelist, please contact the administrator!</h1>");
                    return false;
                }
            }
        }
        return true;
    }
}
2.WebMvcConfigurer代码

这里配置需要拦截的url地址

/**
 * @author: 
 * @date: 2021-10-19 16:46
 * @description: 配置拦截的请求url
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private RequestUrlInterceptor requestUrlInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(requestUrlInterceptor).addPathPatterns("/api/open/**");
    }

}
3.获取请求ip地址
/**
 * @author: 
 * @date: 2021-11-02 9:50
 * @description: 获取ip地址的工具类
 */
public class IpUtils {

    /**
     * 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值
     * @return ip
     */
    public static String getRealIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip != null && ip.length() != 0 && ! "unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值,第一个ip才是真实ip
            if( ip.indexOf(",") != -1 ){
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
            System.out.println("Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
            System.out.println("WL-Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
            System.out.println("HTTP_CLIENT_IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
            System.out.println("X-Real-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            System.out.println("getRemoteAddr ip: " + ip);
        }
        return ip;
    }
}

Spring Boot 中根据 `request` 实现 IP 白名单可以通过以下几种方式: ### 过滤器(Filter)方式 可以创建一个自定义的过滤器来检查请求IP 地址是否在白名单中。示例代码如下: ```java import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.List; public class IPFilter implements Filter { private static final List<String> WHITELIST = Arrays.asList("127.0.0.1", "192.168.1.100"); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String clientIp = getClientIp(httpRequest); if (!WHITELIST.contains(clientIp)) { httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); return; } chain.doFilter(request, response); } private String getClientIp(HttpServletRequest request) { String xffHeader = request.getHeader("X-Forwarded-For"); if (xffHeader == null) { return request.getRemoteAddr(); } return xffHeader.split(",")[0]; } } ``` 然后在配置类中注册这个过滤器: ```java import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean<IPFilter> ipFilterRegistration() { FilterRegistrationBean<IPFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new IPFilter()); registration.addUrlPatterns("/*"); return registration; } } ``` ### 拦截器(Interceptor)方式 创建一个自定义的拦截器来实现 IP 白名单功能: ```java import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; public class IPInterceptor implements HandlerInterceptor { private static final List<String> WHITELIST = Arrays.asList("127.0.0.1", "192.168.1.100"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String clientIp = getClientIp(request); if (!WHITELIST.contains(clientIp)) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); return false; } return true; } private String getClientIp(HttpServletRequest request) { String xffHeader = request.getHeader("X-Forwarded-For"); if (xffHeader == null) { return request.getRemoteAddr(); } return xffHeader.split(",")[0]; } } ``` 在配置类中注册拦截器: ```java import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new IPInterceptor()).addPathPatterns("/**"); } } ``` ### 注解方式 创建一个自定义注解和切面来实现 IP 白名单功能: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface IPWhitelist { } ``` 创建切面类: ```java import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; @Aspect @Component public class IPWhitelistAspect { private static final List<String> WHITELIST = Arrays.asList("127.0.0.1", "192.168.1.100"); @Around("@annotation(com.example.demo.IPWhitelist)") public Object checkIP(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); HttpServletRequest request = null; for (Object arg : args) { if (arg instanceof HttpServletRequest) { request = (HttpServletRequest) arg; break; } } if (request != null) { String clientIp = getClientIp(request); if (!WHITELIST.contains(clientIp)) { throw new RuntimeException("IP not allowed"); } } return joinPoint.proceed(); } private String getClientIp(HttpServletRequest request) { String xffHeader = request.getHeader("X-Forwarded-For"); if (xffHeader == null) { return request.getRemoteAddr(); } return xffHeader.split(",")[0]; } } ``` 在需要进行 IP 白名单检查的方法上添加注解: ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController public class MyController { @GetMapping("/test") @IPWhitelist public String test(HttpServletRequest request) { return "Success"; } } ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值