使用場景:明明引用了一個正確的圖片地址,但顯示出來的倒是一個紅叉或寫有「此圖片僅限於***網站用戶交流溝通使用」之類的「假圖片」。用嗅探軟件找到了多媒體資源的真實地址用下載軟件仍然不能下載。下載一些資源時老是出錯,若是確認地址沒錯的話,大多數狀況都是趕上防盜鏈系統了。常見的防盜鏈系統,通常使用在圖片、音視頻、軟件等相關的資源上。javascript
實現原理:把當前請求的主機與服務器的主機進行比對,若是不同則就是惡意連接,反之則是正常連接。css
不說了,直接上代碼:html
使用Request對象設置頁面的防盜鏈前端
所謂的防盜鏈就是當你以一個非正常渠道去訪問某一個Web資源的時候,服務器會將你的請求忽略而且將你的當前請求變爲按正常渠道訪問時的請求並返回到相應的頁面,用戶只有經過該頁面中的相關操做去訪問想要請求的最終資源。java
例如,你有一個訪問某資源的網址,可是你事先不知道這個網址是有防盜鏈的,那麼當你輸入該網址時你可能會發現,並無立刻跳轉到你想要的資源頁面而是一些無關的信息頁面,可是就是在這些信息頁面中你發現有一個超連接或是其餘操做能夠跳轉到你所訪問的最終資源頁面。web
這就是防盜鏈技術了,好了來看一個具體應用:瀏覽器
Request.java package net.csdn.request;import java.io.IOException; import java.io.PrintWriter;import java.util.Enumeration import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Request extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {getDoorChain(request, response);} private void getDoorChain(HttpServletRequest request, HttpServletResponse response) throws IOException { String referer = request.getHeader("referer"); if(referer==null || !referer.endsWith("http://localhost:8080/Request/index.jsp")){ response.sendRedirect("http://localhost:8080/Request/index.jsp"); return; } response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset =utf-8"); PrintWriter pw = response.getWriter(); pw.write("喜劇片《東成西就》"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
index.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":" +request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 這裏是防盜鏈技術的應用檢測! <br> <a href ="/Request/Request" >喜劇片 </a> </body> </html>
效果如圖:服務器
例如我最終想要經過http://lcoalhost:8080/Request/Request這個網址獲取到我想要的《東成西就》 的資源但是當我真正的輸入這個網址時,卻轉到了: http://localhost:8080/Request/index.jsp這個頁面session
只有當你點擊「喜劇片」這個超連接時纔會真正的獲得你想要的資源頁面即:app
好了趕快本身動手試一試吧!
今天咱們來聊聊Java防盜鏈,多說無用,直接上應用案例。
這裏所用的工具是報表軟件FineReport,搭配有決策系統(一個web前端展現系統,主要用於權限控制),能夠採用java防盜鏈的方式來實現頁面權限。
瀏覽器中直接輸入報表URL的時候,它的頭文件是空的,所以,能夠在訪問的時候作兩個判斷:頭文件是否爲空以及以什麼頁面進行跳轉,若是不符合跳到錯誤頁面便可。
什麼是Referer?
這裏的 Referer 指的是HTTP頭部的一個字段,也稱爲HTTP來源地址(HTTP Referer),用來表示從哪兒連接到目前的網頁,採用的格式是URL。換句話說,藉着 HTTP Referer 頭部網頁能夠檢查訪客從哪裏而來,這也常被用來對付僞造的跨網站請求。
什麼是空Referer,何時會出現空Referer?
首先,咱們對空Referer的定義爲,Referer 頭部的內容爲空,或者,一個HTTP請求中根本不包含Referer頭部。
那麼何時HTTP請求會不包含Referer字段呢?根據Referer的定義,它的做用是指示一個請求是從哪裏連接過來,那麼當一個請求並非由連接觸發產生的,那麼天然也就不須要指定這個請求的連接來源。
好比,直接在瀏覽器的地址欄中輸入一個資源的URL地址,那麼這種請求是不會包含Referer字段的,由於這是一個「憑空產生」的HTTP請求,並非從一個地方連接過去的。
在防盜鏈設置中,容許空Referer和不容許空Referer有什麼區別?
在防盜鏈中,若是容許包含空的Referer,那麼經過瀏覽器地址欄直接訪問該資源URL是能夠訪問到的;
但若是不容許包含空的Referer,那麼經過瀏覽器直接訪問也是被禁止的。
操做步驟
一、添加class文件
編寫一個類文件,用來判斷頭文件是否爲空,代碼以下:
package com.fr.test; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class Dodo implements Filter { public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String referer = req.getHeader("referer"); //下面的IP地址是正常頁面請求 if(null != referer && (referer.trim().startsWith("http://localhost:8033")||referer.trim().startsWith("http://www.finereporthelp.com/test/hello.html"))){ System.out.println("正常頁面請求"+referer); chain.doFilter(req, resp); //下面的就是出現不是正常頁面請求的時候跳轉 }else{ System.out.println("盜鏈"+referer); req.getRequestDispatcher("/LdapLogin.jsp").forward(req, resp); } } public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
將Dodo.java編譯成class文件,並放在%TOMCAT_HOME%\WebReport\WEB-INF\classes\com\fr\test目錄下。
二、修改web.xml文件
打開%TOMCAT_HOME%\webapps\WebReport\WEB-INF下的web.xml文件,配置一個過濾filter,在出現ReportServer的時候執行過濾,代碼以下:
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.fr.test.Dodo</filter-class></filter> <filter-mapping> <filter-name>AuthFilter</filter-name> <url-pattern>/ReportServer</url-pattern> </filter-mapping>
兩步就能夠搞定,若是屬於盜鏈,則跳轉至上述的LdapLogin錯誤頁面,這裏沒有LdapLoign頁面,因此直接跳轉404。若是還想實現數據權限,則能夠經過單點登陸或者session注入的方式。
效果測試
準備兩個html文件
假設hello.html是正確的網址
<html> <body> <p>測試</p> <a href="http://localhost:8033/WebReport/ReportServer?reportlet=demo%2Fnewchart%2Fothers%2FLogarithmic_axis.cpt&op=write">防盜鏈測試</a> </body> <html>
假設steal.html是盜鏈的網址
<html> <body> <p>測試,錯誤的連接地址</p> <a href="http://localhost:8033/WebReport/ReportServer?reportlet=demo%2Fnewchart%2Fothers%2FLogarithmic_axis.cpt&op=write">防盜鏈測試</a> </body> </html>
狀況一
經過hello.html跳轉,跳轉連接正確,即referer不爲空且正確
狀況二
經過steal.html跳轉,跳轉連接錯誤,即referer不爲空且錯誤
狀況三
直接訪問URL地址,即referer爲空