实现原理:HTTP协议响应头中包含的Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。所以我们可以通过得到响应头中包含的referer来判断其请求来自哪里,如果不是本系统页面的请求则可能是盗链(referer包含的是请求发过来的源页面,而对于浏览器地址栏直接发送的请求referer为空)。
代码实现:
1.添加一个类,继承Filter
package com.app.test.common.security.http;
import com.app.test.common.utils.DataUtil;
import org.springframework.beans.factory.annotation.Value;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/*", filterName = "handAll")
public class RefererFilter implements Filter {
@Value("${test.security.exclude-path}")
private String excludePath;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter初始化...");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
/*禁用缓存*/
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragrma", "no-cache");
response.setDateHeader("Expires", 0);
/* 从请求头中获得的请求全地址*/
String referer = request.getHeader("referer");
String path = request.getServletPath();
if(isExcludePath(path)){
// 如果为referer来源为null, 则表示直接从浏览器地地址输入的
if (referer == null) {
request.getRequestDispatcher("/index.html").forward(request, response);
return; // 不再向下执行
}
/* 发起请求域名或IP*/
String address = request.getServerName();
boolean contains = referer.contains(address);
/*如果不包含, 即发起请求的点不是本站的页面*/
if (!contains) {
request.getRequestDispatcher("/index.html").forward(request, response);
return;
}
// 放行
chain.doFilter(request, response);
}else {
// 放行
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
System.out.println("Filter销毁...");
}
private Boolean isExcludePath(String path) {
Boolean flag = true;
String[] excludeArr = null;
if (DataUtil.isNotEmpty(excludePath)) {
excludeArr = excludePath.split(",");
if (excludeArr.length > 0) {
for (int i = 0; i < excludeArr.length; i++) {
String excludeItem = excludeArr[i];
if (DataUtil.isNotEmpty(excludeItem) && path.indexOf(excludeItem) >= 0) {
return flag = false;
}
}
}
}
return flag;
}
}
2.在spring boot的启动器上添加注解, 将要用到的Filter加入进来
@SpringBootApplication
@ServletComponentScan(basePackageClasses=RefererFilter.class) // RefererFilter为要使用的Filter
public class TestApplication extends Bootup {
public static void main(String[] args) {
try {
new SzydApplication().start(args);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
参考资料:
https://blog.csdn.net/lljxk2008/article/details/81630062