最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot集成CSRF防攻擊過程

 更新時間:2025年11月07日 16:16:39   作者:hao_kkkkk  
本文介紹了Springboot集成CSRF防攻擊的方法,通過設(shè)置域名或路徑白名單來過濾未知鏈接,從而達(dá)到防護(hù)目的,主要涉及兩個類:CSRFFilterConfigUtils防護(hù)配置工具類和CsrfFilter防護(hù)過濾類

Springboot集成CSRF防攻擊

CSRF 就是跨域請求偽造,是一種常見的web攻擊方式,解決思路也非常簡單,主要是設(shè)置域名或路徑白名單,對于未知的鏈接予以過濾,從而達(dá)到防護(hù)目的。

總共兩個類:

  • 一個CSRFFilterConfigUtils防護(hù)配置工具類,主要作用是配置防護(hù)開關(guān)、請求路徑白名單以及請求域名白名單;
  • 一個是CsrfFilter防護(hù)過濾類,該類實(shí)質(zhì)是一個攔截器,攔截所有用戶請求,匹配路徑和域名,符合條件的通過,不符合條件的攔截掉;

以下為實(shí)際代碼:

CSRFFilterConfigUtils 防護(hù)配置工具類

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @Auther: GMY
 * @Date: 2022/09/16/9:54
 * @Description: CSRF防護(hù)配置工具類
 */
@Component
public class CSRFFilterConfigUtils {

    /**
     * 跨站點(diǎn)請求路徑白名單,通過英文逗號分隔。在application.properties配置
     */
    public static String csrfWhitePaths;

    /**
     * 跨站點(diǎn)請求域名白名單,通過英文逗號分隔。在application.properties配置
     */
    public static String csrfWhiteDomains;

    /**
     * csrf攻擊防護(hù)開關(guān)配置
     */
    public static Boolean openCsrfProtect;

    /**
     * @param
     * @return java.lang.Boolean
     * @author GMY
     * @date 2022/9/16 10:13
     * @description csrf攻擊防護(hù)開關(guān)配置,默認(rèn)為開啟
     */
    public static Boolean getOpenCsrfProtect() {
        return openCsrfProtect == null ? true : openCsrfProtect;
    }

    /**
     * @param
     * @return java.lang.String[]
     * @author GMY
     * @date 2022/9/16 10:07
     * @description 獲取請求路徑白名單
     */
    public static String[] getCsrfWhitePaths() {
        if (StringUtils.isNotEmpty(csrfWhitePaths)) {
            return csrfWhitePaths.split(",");
        }
        return null;
    }

    /**
     * @param
     * @return java.lang.String[]
     * @author GMY
     * @date 2022/9/16 10:09
     * @description 獲取請求域名白名單
     */
    public static String[] getCsrfWhiteDomains() {
        if (StringUtils.isNotEmpty(csrfWhiteDomains)) {
            return csrfWhiteDomains.split(",");
        }
        return null;
    }


    @Value("${csrf.white.paths}")
    public static void setCsrfWhitePaths(String csrfWhitePaths) {
        CSRFFilterConfigUtils.csrfWhitePaths = csrfWhitePaths;
    }

    @Value("${csrf.white.domains}")
    public static void setCsrfWhiteDomains(String csrfWhiteDomains) {
        CSRFFilterConfigUtils.csrfWhiteDomains = csrfWhiteDomains;
    }

    @Value("${open.csrf.protect}")
    public void setOpenCsrfProtect(Boolean openCsrfProtect) {
        CSRFFilterConfigUtils.openCsrfProtect = openCsrfProtect;
    }
}

CsrfFilter 防護(hù)過濾類

import cn.hutool.json.JSONUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;

/**
 * @Auther: GMY
 * @Date: 2022/09/15/19:54
 * @Description:
 */
@WebFilter(urlPatterns = "/*",filterName = "csrfFilter")
@Configuration
public class CsrfFilter implements Filter {

    // 后臺日志打印
    private Logger log = LoggerFactory.getLogger(CsrfFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @return void
     * @author GMY
     * @date 2022/9/16 9:51
     * @description 執(zhí)行CRSF過濾操作
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse res = (HttpServletResponse) servletResponse;
        // 判斷CSRF防護(hù)是否開啟,如果沒開啟則直接略過過濾操作
        if (!CSRFFilterConfigUtils.getOpenCsrfProtect()) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            String referer = req.getHeader("Referer");
            if (!StringUtils.isBlank(referer)) {
                // 獲取Referer參數(shù)中的地址和端口
                String refererHostAndPort = getHostAndPort(req,referer);
                // 獲取RequestURL參數(shù)中的地址和端口
                String requestHostAndPort = getHostAndPort(req,null);
                // 同域名和同端口,即同一個域的系統(tǒng),通過
                if (requestHostAndPort.equalsIgnoreCase(refererHostAndPort)) {
                    filterChain.doFilter(servletRequest, servletResponse);
                }else {
                    // 如果不同域名或端口,繼續(xù)判斷域名是否在白名單中,如果在白名單中則通過
                    if(isCsrfWhiteDomains(refererHostAndPort)) {
                        filterChain.doFilter(servletRequest, servletResponse);
                        return;
                    }
                    // 獲取RequestURL參數(shù)中的路徑信息
                    String path = new URL(req.getRequestURL().toString()).getPath();
                    log.info("request請求路徑 path = " + path);
                    // 將路徑中的域名去除,只保留具體路徑
                    String actionPath = path.replaceAll(servletRequest.getServletContext().getContextPath(), "");
                    // 判斷路徑是否在訪問路徑白名單中,如果在白名單中,則通過,繼續(xù)后續(xù)執(zhí)行
                    if(isCsrfWhitePaths(actionPath)) {
                        filterChain.doFilter(servletRequest, servletResponse);
                        return;
                    }
                    log.warn("csrf跨站點(diǎn)偽造請求已經(jīng)被攔截:");
                    log.warn("requestURL = " + req.getRequestURL().toString());
                    log.warn("referer = " + referer);
                    res.sendRedirect(req.getContextPath() + "/illegal");
                    return;
                }
            }else{
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    /**
     * @param request
     * @param referer
     * @return java.lang.String
     * @author GMY
     * @date 2022/9/16 9:34
     * @description 獲取請求地址和端口
     */
    protected String getHostAndPort(HttpServletRequest request, String referer) throws IOException {
        URL url;
        if (StringUtils.isNotEmpty(referer)) {
            url = new URL(referer);
        } else {
            url = new URL(request.getRequestURL().toString());
        }
        String requestHostAndPort;
        if(url.getPort() == -1) {
            requestHostAndPort = url.getHost();
        }else {
            requestHostAndPort = url.getHost() + ":" + url.getPort();
        }
        return requestHostAndPort;

    }

    @Override
    public void destroy() {

    }

    /**
     * @param path
     * @return boolean
     * @author GMY
     * @date 2022/9/16 9:52
     * @description 判斷請求路徑是否在路徑白名單中
     */
    private boolean isCsrfWhitePaths(String path) {

        if(CSRFFilterConfigUtils.getCsrfWhitePaths() != null && CSRFFilterConfigUtils.getCsrfWhitePaths().length > 0) {
            for (String csrfWhitePath : CSRFFilterConfigUtils.getCsrfWhitePaths()) {
                if(!StringUtils.isBlank(csrfWhitePath)) {
                    if(csrfWhitePath.equals(path)) {
                        log.info("跨站點(diǎn)請求所有路徑白名單:csrfWhitePaths = " + JSONUtil.toJsonStr(CSRFFilterConfigUtils.getCsrfWhitePaths()));
                        log.info("符合跨站點(diǎn)請求路徑白名單:path = " + path);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * @param refererHostAndPort
     * @return boolean
     * @author GMY
     * @date 2022/9/16 9:52
     * @description 判斷請求域名是否在域名白名單中
     */
    private boolean isCsrfWhiteDomains(String refererHostAndPort) {

        if(CSRFFilterConfigUtils.getCsrfWhiteDomains() != null && CSRFFilterConfigUtils.getCsrfWhiteDomains().length > 0) {
            for (String csrfWhiteDomain : CSRFFilterConfigUtils.getCsrfWhiteDomains()) {
                if(!StringUtils.isBlank(csrfWhiteDomain)) {
                    if(csrfWhiteDomain.equals(refererHostAndPort)) {
                        log.info("跨站點(diǎn)請求所有【域名】]白名單:csrfWhiteDomains = " + JSONUtil.toJsonStr(CSRFFilterConfigUtils.getCsrfWhiteDomains()));
                        log.info("符合跨站點(diǎn)請求【域名】白名單:refererHost = " + refererHostAndPort);
                        return true;
                    }
                }
            }
            log.info("跨站點(diǎn)請求非法【域名】:refererHost = " + refererHostAndPort);
        }
        return false;
    }
}

總結(jié)

以上代碼僅供學(xué)習(xí)交流使用,代碼中涉及到真實(shí)項(xiàng)目信息的內(nèi)容我都做了相應(yīng)修改

當(dāng)然,這些僅為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java的內(nèi)存泄漏和性能瓶頸解讀

    Java的內(nèi)存泄漏和性能瓶頸解讀

    這篇文章主要介紹了Java的內(nèi)存泄漏和性能瓶頸,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Java使用UTF-8或GBK編碼后還是亂碼問題的解決辦法

    Java使用UTF-8或GBK編碼后還是亂碼問題的解決辦法

    在java中處理字符時,經(jīng)常會發(fā)生亂碼,下面這篇文章主要給大家介紹了關(guān)于Java使用UTF-8或GBK編碼后還是亂碼問題的解決辦法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java通過在主循環(huán)中判斷Boolean來停止線程的方法示例

    Java通過在主循環(huán)中判斷Boolean來停止線程的方法示例

    這篇文章主要介紹了Java通過在主循環(huán)中判斷Boolean來停止線程的方法,結(jié)合具體實(shí)例形式分析了java針對線程的判斷與停止操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • mybatis-plus?Wrapper條件構(gòu)造器updateForSet更新方式

    mybatis-plus?Wrapper條件構(gòu)造器updateForSet更新方式

    這篇文章主要介紹了mybatis-plus?Wrapper條件構(gòu)造器updateForSet更新方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • JAXB解析xml轉(zhuǎn)換成類的實(shí)現(xiàn)方式

    JAXB解析xml轉(zhuǎn)換成類的實(shí)現(xiàn)方式

    本文主要介紹了如何使用JAXB將XML配置項(xiàng)轉(zhuǎn)換為Java類,JAXB提供了多種注解,如@XmlRootElement、@XmlElement、@XmlElementWrapper、@XmlAttribute等,可以方便地將XML元素映射為Java對象,并且可以控制生成的XML結(jié)構(gòu),同時,文章也提到了一些需要注意的問題
    2025-11-11
  • 用java實(shí)現(xiàn)楊輝三角的示例代碼

    用java實(shí)現(xiàn)楊輝三角的示例代碼

    本篇文章主要介紹了用java實(shí)現(xiàn)楊輝三角的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Spring Boot 實(shí)現(xiàn)敏感詞及特殊字符過濾處理

    Spring Boot 實(shí)現(xiàn)敏感詞及特殊字符過濾處理

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)敏感詞及特殊字符過濾處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java?Spring?boot日期和時間統(tǒng)一設(shè)置三種方法

    Java?Spring?boot日期和時間統(tǒng)一設(shè)置三種方法

    時間和日期的統(tǒng)一設(shè)置在項(xiàng)目中經(jīng)常是會遇到的,下面這篇文章主要給大家介紹了關(guān)于Java?Spring?boot日期和時間統(tǒng)一設(shè)置的三種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • Maven私服倉庫Nexus配置小結(jié)

    Maven私服倉庫Nexus配置小結(jié)

    Maven 私服是一種特殊的Maven遠(yuǎn)程倉庫,它是架設(shè)在局域網(wǎng)內(nèi)的倉庫服務(wù),本文就來介紹一下Maven私服倉庫Nexus配置小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • MyBatis-Plus中如何使用ResultMap的方法示例

    MyBatis-Plus中如何使用ResultMap的方法示例

    本文主要介紹了MyBatis-Plus中如何使用ResultMap,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論

龙海市| 镶黄旗| 兴山县| 天水市| 左贡县| 白山市| 西平县| 车险| 东乡族自治县| 诏安县| 安康市| 哈巴河县| 于田县| 武夷山市| 昌邑市| 讷河市| 元氏县| 漳平市| 台南市| 牟定县| 西吉县| 大厂| 呼和浩特市| 渭南市| 阿城市| 施甸县| 斗六市| 华蓥市| 延安市| 邢台县| 阳春市| 梁河县| 临安市| 中超| 澄城县| 沙湾县| 雅江县| 申扎县| 五指山市| 沙坪坝区| 元阳县|