日期:2014-05-16  浏览次数:20932 次

apache2.2 盗链问题
在java 的web应用中除了web-inf目录下的文件不能通过url直接访问外,其他在webapp root下的文件都能通过url直接或者间接下载下来,如css image js等文件,通过url去直接下载别人的js应该是很常见的事了。
对js等文件的下载都是偶尔现象,不会对服务器造成太大压力,但是像mp3、rmvb等大文件就会给服务器造成很大压力,加上baidu google sogou等搜索网站的搜索 被别人大量盗链的数量非常大,这就会导致这些盗链占用很多的带宽,从而导致整个网站变慢。那么怎样能够防止别人盗链呢?
先来介绍一个Http请求头 叫referer,通过下面这句可以取到他的值
String referer = request.getHeader("referer");

referer是干什么的呢? referer可简单的理解为记录了上一个页面的url,直接从url访问一个页面时它的referer为null。
我们就是通过判断referer中的值来决定要不要让这个客户下载我们的资源,可能大家已经想到了 filter可以很简单的完成这个任务 可简单的由下面代码实现
public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = request = (HttpServletRequest) req;
		HttpServletResponse response = response = (HttpServletResponse) resp;
		String referer = request.getHeader("referer");

		if(referer == null || isLegalUrl(referer)){
			chain.doFilter(req, resp);	//合法referer可继续执行
		}else{
			System.out.println("非法请求来源,转到首页"); //转到登录页面或首页   
		}
	}

很简单的一个过滤器 在web.xml中配置一下, 马上试试吧
<filter>
        <filter-name>ResourceAccessFilter</filter-name>
        <filter-class>com.redgateonline.daren.web.filter.ResourceAccessFilter</filter-class>
    </filter>
	<filter-mapping>
        <filter-name>ResourceAccessFilter</filter-name>
		<url-pattern>*.mp3</url-pattern>
    </filter-mapping>

启动两个web app 在 webapp1 webapp2, 在webapp1中加一个超链接 下载webapp2的文件
<a href="http://localhost:8080/webapp2/sss.mp3">下载</a>

ok 准备工作都做好了 点击 ‘下载’。。。
令人惊讶的是居然弹出了下载对话框, 难道拦截器没起作用,看了一下输出:
非法请求来源,转到首页

就是说拦截器起作用了, 侥幸心理让我点击下载对话框的‘保存’,没准在在保存的时候会失败呢 嘿嘿
结果是令人失望的-----保存成功了。
题出在哪儿呢? 忽然想到文件下载对话框的弹出并不是由我们程序控制的,所以应该在更靠前的地方去拦截请求,至少应该在ie或者ie之前 自然而然想到了apache,apache是直接对端口进行监听的 所有的请求进来后遇到的第一个关卡就是apache,所有在这儿对请求进行拦截应该没有错, 有错没错 试试再说 :)
见四楼
1 楼 liangguanhui 2007-07-31  
<a href="http://localhost:8080/webapp2/sss.mp3">下载</a> 
你这个8080端口是apache还是tomcat的?如果是apache的,当然filter不起作用,如果是tomcat的,应该会起作用吧
2 楼 weiqingfei 2007-07-31  
没研究过tomcat的源码,猜想,问题应该出在,tomcat对静态资源的请求方式和servlet是不一样的。
除非你的对静态资源的请求是通过servlet包装了的,否则应该是不管用的。

更何况http请求头是可以随便伪装的,不知道lz的想法现实意义有多大。
3 楼 xly_971223 2007-07-31  
看了一下apache 的文档 有url重写的配置
配置很简单, 把下面这句的#号去掉就可以了
#LoadModule rewrite_module modules/mod_rewrite.so

这样apache就添加了url重写功能了
然后在你的虚拟机配置段下添加
<VirtualHost *:80>
    DocumentRoot C:/eclipseworkspace/daren/web
    ServerName www.webapp2.com
   //以下是配置url重写
    RewriteEngine on
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://www.webapp2.com/demo/.*$  [NC] //NC是忽略大小写
    RewriteRule \.(mp3)$ http://www.sohu.com [R=301,L] //R是redirect L是link
</VirtualHost>

RewriteEngine on 打开url重写引擎
RewriteCond  url重写条件
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://www.webapp2.com/demo/.*$  [NC] 

这两句的意思是 如果referer字段不为空 并且(默认是并且,也可用[OR])不匹配^http://www.webapp2.com/demo/.*$这个正则模式就执行RewriteRule
RewriteRule \.(mp3)$ http://www.sohu.com [R=301,L] 

这句的意思是如果url是以.mp3结尾,就redirect到http://www.sohu.com
这样我们就可以有效的防止别人盗链,上面只是应用了mp3文件 扩展一下可以应用到任何文件。
有一个问题是referer能