springboot自定义注解添加接口白名单访问权限,白名单动态配置。

一、添加自定义注解类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义ip拦截注解
 * @author 牛马
 */
@Target({ElementType.METHOD}) //在方法上运行
@Retention(RetentionPolicy.RUNTIME)
public @interface IpApiFilter{
    /**
     * 也可直接在注解中添加白名单(目前是以数据库添加的方式)
     * @return
     */
    String[] whiteIpList();
}

二、实现自定义拦截器


import com.alibaba.fastjson.JSONObject;
import com.kunyuan.annotation.IpApiFilter;
import com.kunyuan.constant.HttpStatus;
import com.kunyuan.utils.StringUtils;
import com.kunyuan.wangdian.domain.IpWhite;
import com.kunyuan.wangdian.mapper.WangDianMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: kunyuan
 * @description: ip拦截器
 * @author: 牛马
 * @create: 2023-11-30 16:10
 **/

@Component
public class IpInterceptor implements AsyncHandlerInterceptor {
    @Resource
    private WangDianMapper wangDianMapper;

    public static IpInterceptor interceptor;

    @PostConstruct
    private void init() {
        interceptor = this;
        interceptor.wangDianMapper = this.wangDianMapper;
    }

    private static final Logger log = LoggerFactory.getLogger(IpInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1.获取自定义注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 注:判断是否添加了相应注解
        IpApiFilter ipWhite = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), IpApiFilter.class);
        if (ipWhite == null) {
            return true;
        }
        // 2.获取客户端真实ip地址
        String clientIp = getClientIpAddr(request);
        // 3.校验ip地址(这里可以从数据库查ip校验)
        List<IpWhite> whiteIpList = interceptor.wangDianMapper.getIpWhiteList();
        // String[] whiteIpList = ipWhite.whiteIpList();
        for (IpWhite ipList : whiteIpList) {
            if (ipList.getIp().equals(clientIp)) {
                return true;
            }
        }
        fallback(clientIp, response);
        return false;
    }

    private void fallback(String clientIp, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        PrintWriter writer = null;
        try {
            String message = String.format("您的IP地址为[%s],已被系统禁止访问,请联系管理员处理!", clientIp);
            Map<String, Object> map = new HashMap<>();
            map.put("status", HttpStatus.FORBIDDEN);
            map.put("msg", message);
            JSONObject json = new JSONObject(map);
            writer = response.getWriter();
            writer.append(json.toString());
        } catch (IOException e) {
            log.error(String.valueOf(e));
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    private String getClientIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) { // "***.***.***.***".length() = 15
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return ip;
    }
}

三、对应接口controller添加注解,whiteIpList 可以写死ip,但是目前我们使用的是动态读取数据库配置!

   @RequestMapping(value = "/stockout/order/query/trade")
    // ip白名单校验注解
    @IpApiFilter(whiteIpList = {})
    public R getStockoutOrder(@RequestBody WangDianParams wangDianParams) {
        return wangDianService.getStockoutOrder(wangDianParams);
    }

OK完美实现!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值