欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java防止非法盜鏈的幾種解決方案

 更新時間:2023年10月03日 09:32:54   作者:CodeDevMaster  
防止別人通過一些技術(shù)手段盜用本站的資源,本文主要介紹了Java防止非法盜鏈的幾種解決方案,具有一定的參考價值,感興趣的可以了解一下

非法盜鏈概述

非法盜鏈指的是在未獲得授權(quán)的情況下,將別人的資源(如圖片、視頻等)直接鏈接到自己的網(wǎng)站上,從而消耗他人的帶寬和流量,并影響原始資源的安全性。

HTTP Referer請求頭驗證

通過檢查HTTP頭部中的Referer字段,判斷請求來源是否合法。只允許來自特定域名或IP地址的請求才能訪問資源。這種方法較容易實施,不過存在一定的偽造風(fēng)險。

Spring MVC項目

創(chuàng)建RefererFilter類實現(xiàn)Filter接口并重寫3個方法,實現(xiàn)過濾邏輯。

在處理請求時判斷請求頭中的Referer字段,然后通過字符串比較或正則匹配可以判斷請求來源是否合法,如果不合法可以返回錯誤信息或重定向到其他頁面。

public class RefererFilter implements Filter {
? ? @Override
? ? public void init(FilterConfig filterConfig) throws ServletException {
?? ??? ?System.out.println("初始化方法...");
? ? }
? ? /**
? ? ?* @param request
? ? ?* @param response
? ? ?* @param chain
? ? ?*/
? ? @Override
? ? public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
??? ? ? ?System.out.println("攔截請求...");
? ? ? ? HttpServletRequest req = (HttpServletRequest) request;
? ? ? ? HttpServletResponse res = (HttpServletResponse) response;
? ? ? ? //每次請求來源
? ? ? ? String referer = req.getHeader("referer");
? ? ? ? //獲取請求地址
? ? ? ? String serverName = req.getServerName();
? ? ? ? System.out.println("referer:" + referer + "---serverName" + serverName);
? ? ? ? if (referer == null || !referer.contains(serverName)) {
? ? ? ? ? ? req.getRequestDispatcher("/static/images/error.png").forward(req, res);
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? //放行
? ? ? ? chain.doFilter(req, res);
? ? }
? ? @Override
? ? public void destroy() {
?? ??? ?System.out.println("銷毀請求...");
? ? }
}

web.xml配置過濾器

    <filter>
        <filter-name>RefererFilter</filter-name>
        <filter-class>cn.ybzy.demo.fileter.RefererFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RefererFilter</filter-name>
        <url-pattern>/static/images/*</url-pattern>
    </filter-mapping>

Spring Boot項目

創(chuàng)建一個攔截器來對 HTTP Referer 請求頭進(jìn)行驗證

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RefererInterceptor implements HandlerInterceptor {
? ? // 允許的 referer
? ? private static final String ALLOWED_REFERER = "https://www.your-domain.com";
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? String referer = request.getHeader("Referer");
? ? ? ? // 如果請求頭中的 Referer 不是允許的域名,則返回 403 錯誤
? ? ? ? if (referer == null || !referer.startsWith(ALLOWED_REFERER)) {
? ? ? ? ? ? response.sendError(HttpServletResponse.SC_FORBIDDEN);
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? // 否則放行
? ? ? ? return true;
? ? }
}

通過 WebMvcConfigurer 接口和 addInterceptors 方法注冊了名為 RefererInterceptor 的攔截器。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RefererInterceptor());
    }
}

使用Nginx

可以使用Nginx通過配置實現(xiàn)非法盜鏈防護(hù),主要使用valid_referers 參數(shù)

valid_referers:指定允許訪問該網(wǎng)站資源的有效來源,可以設(shè)置為多個值,用空格分隔,如valid_referers example.com *.example.com; 表示只允許來自example.com或者其子域名的訪問。

如果請求的 Referer 頭不存在或者不在 valid_referers 中,則會將 $invalid_referer 設(shè)置為 1,進(jìn)而返回 HTTP 狀態(tài)碼 403

具體實現(xiàn)如下:

location ~ .*\.(jpg|jpeg|JPG|png|gif|icon)$ {
        valid_referers blocked example.com *.example.com;
        if ($invalid_referer) {
            return 403;
        }
    }

限制訪問權(quán)限

在資源服務(wù)器和客戶端上分別進(jìn)行配置,實現(xiàn)認(rèn)證和授權(quán)機(jī)制。服務(wù)端可以使用JavaEE 中的Servlet、Filter 或Spring Security等框架來實現(xiàn)認(rèn)證和授權(quán)??蛻舳藙t需要在請求中攜帶身份認(rèn)證憑證,如token、session id等

客戶端發(fā)送請求時攜帶身份認(rèn)證憑證:

# 用戶身份認(rèn)證憑證
  String token = "123456789";
  HttpURLConnection conn = (HttpURLConnection) new URL("http://www.test.com/img.jpg").openConnection();
  // 在請求頭中添加 Authorization 字段攜帶憑證
  conn.setRequestProperty("Authorization", "Bearer "+token); 

服務(wù)端進(jìn)行認(rèn)證:

 // 獲取請求頭中的認(rèn)證字段
  String authHeader = request.getHeader("Authorization"); 
  if(authHeader != null && authHeader.startsWith("Bearer ")){
    // 提取認(rèn)證憑證
    String token = authHeader.substring(7); 
    // TODO 對憑證進(jìn)行校驗或者查詢授權(quán)信息
  } else{
  }

動態(tài)生成鏈接

在服務(wù)端對每個請求生成唯一的一次性鏈接,在處理請求時驗證該鏈接是否合法??梢允褂肑ava中的UUID類來生成隨機(jī)字符串作為鏈接的參數(shù)。這種方法能夠有效保護(hù)資源的安全,但對服務(wù)器壓力較大。

生成唯一帶簽名的鏈接

private static final String KEY = "YOUR_SECRET_KEY"; // 設(shè)置秘鑰
?? ?/**
? ? ?* 傳入原始鏈接作為參數(shù),即可生成帶有時間戳、隨機(jī)數(shù)和簽名的新鏈接
? ? ?* @param url 訪問URL
? ? ?*/
? ? public static String generateLink(String url) throws NoSuchAlgorithmException {
? ? ? ? // 當(dāng)前時間戳
? ? ? ? String timestamp = System.currentTimeMillis() + "";
? ? ? ? // 隨機(jī)數(shù)
? ? ? ? String nonce = Long.toString(Math.round(Math.random() * 10000));
? ? ? ? // 簽名內(nèi)容
? ? ? ? String rawSignature = url + timestamp + nonce + KEY;
? ? ? ? // 使用 SHA-256 算法生成簽名
? ? ? ? MessageDigest md = MessageDigest.getInstance("SHA-256");
? ? ? ? byte[] signature = md.digest(rawSignature.getBytes());
? ? ? ? // Base64 編碼
? ? ? ? String encodedSignature = Base64.getEncoder().encodeToString(signature);
? ? ? ? // 生成鏈接
? ? ? ? String link = url + "?timestamp=" + timestamp + "&nonce=" + nonce + "&signature=" + encodedSignature;
? ? ? ? return link;
? ? }

校驗鏈接是否合法

校驗步驟:

從鏈接中取出 timestamp、nonce 和 signature 三個參數(shù)

使用與鏈接生成時相同的秘鑰、算法(SHA-256)和編碼方式(Base64)對原始內(nèi)容進(jìn)行簽名,獲得新的簽名值

比較從鏈接中獲得的簽名值和新的簽名值是否一致

如果簽名值一致,并且 timestamp 和 nonce 參數(shù)符合要求(如沒有重復(fù)),則認(rèn)為該鏈接是合法的

private static final String KEY = "YOUR_SECRET_KEY"; // 設(shè)置秘鑰
? ? /**
? ? ?* 如果返回 true 則說明鏈接合法,可以繼續(xù)訪問
? ? ?* 如果返回 false,則說明鏈接不合法,需要返回錯誤信息或者重定向到其他頁面
? ? ?* @param url 訪問URL
? ? ?* @param timestamp 時間戳
? ? ?* @param nonce 隨機(jī)數(shù)
? ? ?* @param signature 簽名
? ? ?*/
? ? public static boolean isValidLink(String url, String timestamp, String nonce, String signature) throws NoSuchAlgorithmException {
? ? ? ? // 簽名內(nèi)容
? ? ? ? String rawSignature = url + timestamp + nonce + KEY;
? ? ? ? // 使用 SHA-256 算法生成簽名
? ? ? ? MessageDigest md = MessageDigest.getInstance("SHA-256");
? ? ? ? byte[] newSignature = md.digest(rawSignature.getBytes());
? ? ? ? // Base64 編碼
? ? ? ? String encodedSignature = Base64.getEncoder().encodeToString(newSignature);
? ? ? ? // 校驗簽名值和其他參數(shù)
? ? ? ? return encodedSignature.equals(signature);
? ? }

測試

?public static void main(String[] args) throws Exception {
? ? ? ? String link = DynamicLink.generateLink("/test");
? ? ? ? // link = /test?timestamp=1683100020877&nonce=9081&signature=vD2S/Ki7a/SLhRj19mcqDmylKKO3OTKTtpA/CUZJMg0=
? ? ? ? System.out.println("link = " + link);
? ? ? ? boolean validLink = DynamicLink.isValidLink("/test", "1683100020877", "9081", "vD2S/Ki7a/SLhRj19mcqDmylKKO3OTKTtpA/CUZJMg0=");
? ? ? ? System.out.println("validLink = " + validLink);
? ? }
link = /test?timestamp=1683100020877&nonce=9081&signature=vD2S/Ki7a/SLhRj19mcqDmylKKO3OTKTtpA/CUZJMg0=
validLink = true

添加水印

在資源服務(wù)器上進(jìn)行配置,在服務(wù)端對資源進(jìn)行加水印處理,并在客戶端顯示處理后的結(jié)果。Java可以使用Graphics2D工具類來添加水印。

參考:Java實現(xiàn)添加文字水印、圖片水印功能

CDN防盜鏈

利用CDN服務(wù)商的防盜鏈功能,限制只有經(jīng)過授權(quán)的域名才能訪問資源。

訪問頻率限制

通過IP地址或用戶會話ID等方式限制同一客戶端在一段時間內(nèi)對資源的訪問頻率,防止非法爬取和盜鏈。

到此這篇關(guān)于Java防止非法盜鏈的幾種解決方案的文章就介紹到這了,更多相關(guān)Java防止非法盜鏈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 查找native方法的本地實現(xiàn)函數(shù)native_function詳解

    查找native方法的本地實現(xiàn)函數(shù)native_function詳解

    JDK開放給用戶的源碼中隨處可見Native方法,被Native關(guān)鍵字聲明的方法說明該方法不是以Java語言實現(xiàn)的,而是以本地語言實現(xiàn)的,Java可以直接拿來用。這里介紹下查找native方法的本地實現(xiàn)函數(shù)native_function,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • Spring依賴注入的幾種方式分享梳理總結(jié)

    Spring依賴注入的幾種方式分享梳理總結(jié)

    這篇文章主要介紹了Spring依賴注入的幾種方式分享梳理總結(jié),文章圍繞主題展開詳細(xì),具有一定參考價值,需要的朋友可以參考一下
    2022-07-07
  • jackson 如何將實體轉(zhuǎn)json json字符串轉(zhuǎn)實體

    jackson 如何將實體轉(zhuǎn)json json字符串轉(zhuǎn)實體

    這篇文章主要介紹了jackson 實現(xiàn)將實體轉(zhuǎn)json json字符串轉(zhuǎn)實體,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java編程redisson實現(xiàn)分布式鎖代碼示例

    Java編程redisson實現(xiàn)分布式鎖代碼示例

    這篇文章主要介紹了Java編程redisson實現(xiàn)分布式鎖代碼示例,小編覺得還是比較不錯的,這里給大家分享下,供需要的朋友參考。
    2017-10-10
  • 基于Hadoop實現(xiàn)Knn算法

    基于Hadoop實現(xiàn)Knn算法

    這篇文章主要為大家詳細(xì) 介紹了基于Hadoop實現(xiàn)Knn算法的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 一文精通Java中的volatile關(guān)鍵字

    一文精通Java中的volatile關(guān)鍵字

    volatile是java中的關(guān)鍵詞之一,這篇文章主要給大家介紹了關(guān)于Java中volatile關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot利用注解來實現(xiàn)Redis分布式鎖

    SpringBoot利用注解來實現(xiàn)Redis分布式鎖

    有些業(yè)務(wù)請求,屬于耗時操作,需要加鎖,防止后續(xù)的并發(fā)操作,同時對數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行操作,需要避免對之前的業(yè)務(wù)造成影響。本文將利用注解來實現(xiàn)Redis分布式鎖,需要的可以參考一下
    2022-09-09
  • 詳解IntelliJ IDEA 中如何配置多個jdk版本即(1.7和1.8兩個jdk都可用)

    詳解IntelliJ IDEA 中如何配置多個jdk版本即(1.7和1.8兩個jdk都可用)

    這篇文章主要介紹了詳解IntelliJ IDEA 中如何配置多個jdk版本即(1.7和1.8兩個jdk都可用),非常具有實用價值,需要的朋友可以參考下
    2017-11-11
  • Springboot啟動擴(kuò)展點超詳細(xì)教程小結(jié)

    Springboot啟動擴(kuò)展點超詳細(xì)教程小結(jié)

    這篇文章主要介紹了Springboot啟動擴(kuò)展點超詳細(xì)教程小結(jié),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 使用Post方法模擬登陸爬取網(wǎng)頁的實現(xiàn)方法

    使用Post方法模擬登陸爬取網(wǎng)頁的實現(xiàn)方法

    下面小編就為大家?guī)硪黄褂肞ost方法模擬登陸爬取網(wǎng)頁的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論