防御之前
防御之后
如何防御?
- 通过http请求头中的Referer参数进行判断
代码实现
// 获取域名的工具类
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DomainUtils {
public static String getDomain(String url) {
Pattern pattern = Pattern.compile("//[\\w.]*/");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
return matcher.group(0).substring(2, matcher.group(0).length() - 1);
}
return "";
}
}
// 实现静态资源的过滤器
import com.example.nginx.util.DomainUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@WebFilter(urlPatterns = "/static/imgs/*")
public class ImageFilter implements Filter {
@Value("${custom.domain}")
private String customDomain;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//获取请求头中的Referer域
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String url = httpServletRequest.getHeader("Referer");
System.out.println("请求头中的Referer域: " + url);
if (StringUtils.isEmpty(url)) {
servletRequest.getRequestDispatcher("/static/imgs/error.png").forward(servletRequest, servletResponse);
return;
}
//获取域名
String clientDomain = DomainUtils.getDomain(url);
//验证白名单
if (!clientDomain.equals(customDomain)) {
servletRequest.getRequestDispatcher("/static/imgs/error.png").forward(servletRequest, servletResponse);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
遇到的问题
- SpringBoot2.0版本访问静态资源的方式改变了, 通过以下配置解决, 同时客户端访问的时候需要带上/static/imgs
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
- 访问静态资源的时候, 请求中没有Referer参数. 这个问题困扰了好久, 使用的是chrome, 清了缓存也没用. 最后发现, 将静态资源放到html页面中, 通过img标签访问的场景下, 请求会带上Referer参数. 盗图一般也是这样做的, 所以这种模拟场景还是比较准确的.
- 模拟其他网站盗图, 配置本地域名映射的时候, 需要记得加端口. 模拟自己网站访问静态资源的时候, 由于已经将服务通过natapp映射到外网了, 已经指定了服务的端口, 所以不用加端口.
- 如何配置freemarker? 使用以下配置
# 配置freemarker
spring:
freemarker:
# 设置模板后缀名
suffix: .ftl
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
# 设置ftl文件路径
template-loader-path:
- classpath:/templates
# 设置静态文件路径,js,css等
mvc:
static-path-pattern: /static/**在这里插入代码片
转载:https://blog.csdn.net/juzhenxing/article/details/102150175
查看评论