spring拦截器简易处理防盗链

实体类:

package org.wangbiao.safetychain.handler;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

@Component
@ConfigurationProperties("img-protect")
public class ImageProtected {
    private boolean enabled;
    private boolean allowBrowser;
    private String allowReferer;
    private ArrayList<String> type;

    public ArrayList<String> getType() {
        return type;
    }

    public void setType(ArrayList<String> type) {
        this.type = type;
    }


    public boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public boolean getAllowBrowser() {
        return allowBrowser;
    }

    public void setAllowBrowser(boolean allowBrowser) {
        this.allowBrowser = allowBrowser;
    }

    public String getAllowReferer() {
        return allowReferer;
    }


    public void setAllowReferer(String allowReferer) {
        this.allowReferer = allowReferer;
    }
}

 web配置注册自定义拦截器:

package org.wangbiao.safetychain.handler;

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 {
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptorHandler()).addPathPatterns("/**");
    }
}

 自定义拦截器:

package org.wangbiao.safetychain.handler;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Component
public class MyInterceptorHandler implements HandlerInterceptor {


    @Autowired
    private ImageProtected imageProtected;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //是否启用防盗链
        if (!imageProtected.getEnabled()) {
            //没开启 直接请求
            return true;
        }
        String requestUrl = request.getRequestURI().toString();
        int i = requestUrl.lastIndexOf(".JPEG");
        String substring = "";
        if (i != -1) {
            substring = requestUrl.substring(i + 1);
            if (!ObjectUtils.isEmpty(substring)) {
                substring = substring.toLowerCase();
            }
        }
        if (!ObjectUtils.isEmpty(substring)&&imageProtected.getType().contains(substring)) {
            String referer = request.getHeader("Referer");
            if (!ObjectUtils.isEmpty(referer) && imageProtected.getAllowBrowser()) {
                //是浏览器请求 可以访问
                return true;
            } else if (!ObjectUtils.isEmpty(referer) || isAllowedDomain(referer)) {
                //是允许放的的主机域名则放过
                return true;
            } else {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                return false;
            }

        }
        //非图片资源请求 进行放过
        return true;
    }


    private boolean isAllowedDomain(String referer) {
        // 获取允许的域名
        String allowedReferrers = imageProtected.getAllowReferer();
        // 如果允许的域名不为空
        if (allowedReferrers.trim() != null && !"".equals(allowedReferrers.trim())) {
            // 将允许的域名分割成字符串数组
            Set<String> allowedDomains = new HashSet<>(Arrays.asList(allowedReferrers.split(",")));
            // 遍历允许的域名
            for (String allowedDomain : allowedDomains) {
                // 如果请求的域名包含允许的域名,则返回true
                if (referer.contains(allowedDomain.trim())) {
                    return true;
                }
            }
        }
        // 否则返回false
        return false;
    }
}

 配置文件:

spring.application.name=safetychain
#图片防盗链保护开关
img-protect.enabled=true
#是否允许浏览器直接访问
img-protect.allowBrowser=false
#图片防盗链白名单,多个用逗号分隔【不填则所有网站都拦截】
img-protect.allowReferer=localhost
img-protect.type=jpg,jpeg,png,gif

 

posted @ 2025-02-06 17:39  余生请多指教ANT  阅读(17)  评论(0)    收藏  举报