java 防盗链 referer 疑问-如何真正防盗链
看了一点文章,apache和ngix等防盗链也是使用referer这个参数,怎么能真正的防盗链呢?
防盗链的做法不说了,可能大部分都是使用的referer这个参数,以前面试的时候有个人问我怎么防止用户登录了,但是这个用户就想在打开浏览器输入地址访问后台的action怎么办?
我说在action后加点长的东西,让他没心情输入,他说如果这个用户比较有耐心还是给你输入了,怎么能让他在浏览器里输入的地址不能访问到action呢?当时没回答上来,一直都没在意过这个问题。今天看http协议突然发现referer这个参数,试着弄了一下,果然在输入地址是访问不到action了。可是我新的疑问又来了:
1:如果我自己写个java的方法,通过httpconnection或者别的连接设置了这个参数,你怎么办?
2:我显然可以通过javascript开发工具ie--->>F12修改你别的链接为要访问的action啊,这你怎么控制呢?
3:这个参数是在客户端生成的,也不安全啊。不知道apache的防盗链,或者ngix的防盗链是怎么实现的。有待研究一下。
刚在网上看到的:
如何实现防盗链
要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或文件。换句话说,通过referer,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。有了referer跟踪来源就好办了,这时就可以通过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面。
如果想对自己的网站进行防盗链保护,则需要针对不同的情况进行区别对待。如果网站服务器用的是apache,那么使用apache自带的UrlRewrite功能可以很轻松地防止各种盗链,[color=green]其原理是检查refer,如果refer的信息来自其他网站则重定向到指定图片或网页上。
如果服务器使用的是IIS的话,则需要通过第三方插件来实现防盗链功能了,现在比较常用的一款产品叫做ISAPI_Rewrite,可以实现类似于apache的防盗链功能。另外对于论坛来说还可以使用“登录验证”的方法进行防盗链。
[color=green]如何突破防盗链
针对检查refer的方式,可以在页面中间件里面先进入目的地址的另外一个页面在转到目的页面即可,这样页面的refer就是目的站点自己的,如此,即做到突破。这方面可以使用的工具很多,尤其是成熟的web项目测试包,如HtmlUnit,直接在请求中设置refer都是可以的。[/color]
[/color]
下面把我做的实验奉上,简单的实现了一下:
@Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) arg1; HttpServletRequest request = (HttpServletRequest) arg0; String requestAddress = request.getRequestURL().toString(); String requestHeader = request.getHeader("referer"); if (requestAddress.indexOf("/css/")<0 && requestAddress.indexOf("/js/")<0 && requestAddress.indexOf("/images/")<0 && requestAddress.indexOf("/pages/")<0) { if (!requestAddress .equals("http://localhost:8089/cms/html/renderlink.html")) { if (!requestAddress.equals("http://localhost:8089/cms/login")) { if (!StringUtils.isEmpty(requestHeader)) { if (!requestHeader.startsWith("http://localhost:8089") || !requestHeader .startsWith("http://localhost:8089")) { response.sendRedirect(request.getContextPath() + "/html/renderlink.html"); } } else { response.sendRedirect(request.getContextPath() + "/html/renderlink.html"); } } } } arg2.doFilter(arg0, arg1); }
<filter> <filter-name>renderFilter</filter-name> <filter-class>com.cms.filter.RenderFilter</filter-class> </filter> <filter-mapping> <filter-name>renderFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>