springboot的Filter注解与防盗链接

Filter的功能是改变请求与响应

在一个请求到达Servlet 之前 处理request

在离开Servlet的时候处理 response

所以利用Filter可以检查request和response, 根据需要也可以修改request头 和 response头

对于spring boot, Filter配置可以使用原始的配置, 也可以使用新的配置方式

如下只以新的配置方式为例:

1. 创建一个类, 让它继承Filter

public class StealSource implements Filter {...}

2.在类上加@WebFilter注解, 并添加要过滤的请求地址

@WebFilter(urlPatterns="/*", filterName="handAll")
public class StealSource implements Filter {...}

3.在spring boot的启动器上添加注解, 将要用到的Filter加入进来

@SpringBootApplication    // 这个与Filter无关(它只是标注此类为spring boot的启动器)
@ServletComponentScan(basePackageClasses=StealSource.class)    // StealSource为要使用的Filter
public class App extends SpringBootServletInitializer {...}

经过上面简单的配置就可以正常使用了

网络上的资源, 有些我们拿来可以直接访问, 有些不能访问

<video src="xxx"/>

先打开一个网页, 然后找到原码(F12), 这里就可以看到xxx的具体内容是什么

当我们把这个xxx内容拷贝出来放入浏览器地址栏请求, 发现有些有效, 有些无效

经过测试和查找, 无效是由于链接防盗, 它设置了不能从外部域名进入到服务器

如下通过Filter简单设置防盗链接

原理: 请求的域名不等于服务器域名就不能通过

发送一个请求时, 如下:

地址为: https://mp.csdn.net/postedit

域名为: mp.csdn.net

使用request.getHeader("referer");  获取地址

使用request.getServerName(); 获取域名

服务器域名不变, 关键就是看请求的地址中是否有服务器的域名

如果你是从地址输入的, 则后台服务器获取的地址为空

如果是从其它页面中请求的, 则域名不是服务器域名

如果是从服务器中的页面请求的, 则域名与服务器域名相同

实现代码:

@WebFilter(urlPatterns="/*", filterName="handAll")
public class StealSource implements Filter {	
	
	@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");
		
		// 如果为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);
	}

	@Override
	public void destroy() {
		System.out.println("Filter销毁...");
	}
}

最关键是要理解 request.getServletName()

获取的是网站的域名, 比如从index.html 的 a标签 发送的请求

后台使用request.getServletName() 获取到的就是index所属项目的域名

如果是本地创建一个html页面(不在项目中)来发送请求, 获取的就是localhost, 也就是本在ip

所以只能由项目所属页面发送的请求才能通过Filter, 从而达到 防盗 的目的

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值