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

Spring?Security中的CORS詳解

 更新時(shí)間:2024年10月08日 10:42:39   作者:興趣廣泛的程序猿  
CORS(Cross-Origin?Resource?Sharing)是一種允許不同源之間進(jìn)行資源共享的W3C標(biāo)準(zhǔn),它通過(guò)在服務(wù)器端設(shè)置特定的HTTP響應(yīng)頭,實(shí)現(xiàn)了跨域請(qǐng)求的功能,這種機(jī)制要求瀏覽器和服務(wù)器的支持,本文給大家介紹Spring?Security中的CORS,感興趣的朋友一起看看吧

一、CORS是什么

        CORS(Cross-Origin Resource Sharing,跨源/域資源共享 )是一個(gè)W3C標(biāo)準(zhǔn),一種允許當(dāng)前域(domain)的資源(比如html/js/web service)被其他域(domain)的腳本(比如AJAX)請(qǐng)求訪問(wèn)的機(jī)制,通常由于同源安全策略,瀏覽器會(huì)禁止這種跨域請(qǐng)求。

        CORS需要瀏覽器和服務(wù)器同時(shí)支持。目前,所有瀏覽器都支持該功能,IE 瀏覽器不能低于 IE10。

        整個(gè)CORS通信過(guò)程,都是瀏覽器自動(dòng)完成,不需要用戶參與。對(duì)于開發(fā)者來(lái)說(shuō),CORS通信與同源的AJAX通信沒(méi)有差別,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn)AJAX請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附件的頭信息,有時(shí)還會(huì)多處一次附件的請(qǐng)求,但用戶不會(huì)有感覺(jué)。

        因此,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS功能(響應(yīng)報(bào)文包括了正確的CORS響應(yīng)頭),就可以被跨源訪問(wèn)(可以指定個(gè)別域或全部域)。

二、同源安全策略

        說(shuō)到跨域請(qǐng)求,就不得不說(shuō)一下“同源安全策略”了,如果沒(méi)有這個(gè)策略的存在,也就沒(méi)有這么多事了,但是,這樣可能會(huì)造成你在網(wǎng)站進(jìn)行一些操作時(shí)存在風(fēng)險(xiǎn)。

        同源策略是一個(gè)重要的安全策略,它用于限制一個(gè)源/域的文檔或它加載的腳本是否能與另一個(gè)源/域的資源進(jìn)行交互。它能幫助阻隔惡意文檔,減少可能被攻擊的媒介。

        出于安全性,瀏覽器會(huì)限制腳本內(nèi)發(fā)起的跨域HTTP請(qǐng)求,例如常見的 XHR、Fetch API 都遵循同源策略。

        如果兩個(gè) URL 的協(xié)議(Protocol)、主機(jī)(Host)、端口(Port,如果有指定的話)都相同的話,那么這兩個(gè) URL 是同源的,否則是不同源的。

        當(dāng)瀏覽器中打開的某個(gè)網(wǎng)頁(yè),有腳本執(zhí)行了跨域請(qǐng)求,那么,瀏覽器的“同源安全策略”就會(huì)介入,大致流程如下:

        瀏覽器直接發(fā)出CORS請(qǐng)求,也就是在頭信息之中,增加一個(gè)Origin字段。這個(gè)字段代表本次請(qǐng)求來(lái)自哪個(gè)源(協(xié)議 + 主機(jī) + 端口),服務(wù)器會(huì)根據(jù)這個(gè)值,決定是否同意這次請(qǐng)求。前面的流程是對(duì)于HTTP簡(jiǎn)單請(qǐng)求,如果是HTTP非簡(jiǎn)單請(qǐng)求,則會(huì)在正式請(qǐng)求前,增加一次預(yù)檢請(qǐng)求。

        如果Origin指定的源,不在許可范圍內(nèi)(服務(wù)器端CORS功能指定),服務(wù)器會(huì)返回一個(gè)正確的HTTP回應(yīng)。瀏覽器發(fā)現(xiàn),這個(gè)回應(yīng)的頭信息沒(méi)有包含Access-Control-Allow-Origin字段,就知道出錯(cuò)了,從而拋出一個(gè)錯(cuò)誤,被XMLHttpRequestonerror回調(diào)函數(shù)捕獲。注意,這種錯(cuò)誤無(wú)法通過(guò)狀態(tài)識(shí)別,因?yàn)镠TTP回應(yīng)的狀態(tài)碼有可能是 200。

        拋出的錯(cuò)誤為“has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.”,如下:

三、Spring Security中CORS的開啟

        在Spring框架中,我們可以在引入Spring Security依賴后,對(duì)Security的HttpSecurity進(jìn)行設(shè)置,來(lái)開啟CORS(跨域/源資源共享),同時(shí)能指定只被部分域/源、部分方法、部分頭部信息訪問(wèn)資源。

        Spring框架提供了CorsFilter,是為了在基于filter的安全框架(如Spring Security)上面支持CORS,或者在使用其他不支持CORS的庫(kù)上支持CORS。

//(Security6.2.4寫法)先創(chuàng)建一個(gè)普通JAVA類,如SecurityConfig.java,實(shí)現(xiàn)如下3個(gè)Bean。
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(
                (authz) -> authz
                        .anyRequest().authenticated())
            .httpBasic(withDefaults())
            .formLogin(withDefaults())
            .csrf((csrf)->csrf.disable())
            .cors(withDefaults()); //開啟CORS(跨域/源資源共享)
        return http.build();
    }
    @Autowired //自動(dòng)裝配參數(shù)configurationSource(下方的Bean)
    @Bean
    public CorsFilter corsFilter(UrlBasedCorsConfigurationSource configurationSource){
        return new CorsFilter(configurationSource);
    }
    // 也可以將方法內(nèi)的實(shí)現(xiàn)整合到上面的corsFilter方法體內(nèi)
    @Bean
    public UrlBasedCorsConfigurationSource configurationSource(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOriginPattern("http://localhost*"); //新版本寫法
        //corsConfiguration.addAllowedOrigin("*"); //老版本寫法
        source.registerCorsConfiguration("/**",corsConfiguration);
        return source;
    }

四、其它處理方法

1、Spring注解

        原理:自Spring Framework 4.2開始,CORS請(qǐng)求(包括OPTIONS method)會(huì)被自動(dòng)分發(fā)到各種注冊(cè)過(guò)的HandlerMappings。它們會(huì)處理CORS的preflight請(qǐng)求,會(huì)攔截CORS簡(jiǎn)單和實(shí)際請(qǐng)求,以便基于你指定的CORS配置,添加相關(guān)的CORS響應(yīng)頭(如 Access-Control-Allow-Origin)。

        實(shí)現(xiàn):在@RequestMapping注解過(guò)的controller method上面添加@CrossOrigin注解,表示已開啟CORS。

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600) //括號(hào)內(nèi)為指定的CORS配置
@RestController
@RequestMapping("/account")
public class AccountController {
    @CrossOrigin("http://domain2.com") //同時(shí)使用controller級(jí)別和method級(jí)別的CORS配置,Spring會(huì)將二者的attributes結(jié)合起來(lái),創(chuàng)建出融合的CORS配置。
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }
}

        除了基于注解@CrossOrigin的配置(細(xì)粒度),還可以定義全局的CORS配置。類似于使用filters,但可以定義在Spring MVC中,并與細(xì)粒度的@CrossOrigin配置相配合。

2、JSONP(JSON with Padding)

        原理:利用<script>標(biāo)簽不受瀏覽器同源策略限制的特性,通過(guò)動(dòng)態(tài)插入<script>標(biāo)簽的方式實(shí)現(xiàn)跨域數(shù)據(jù)訪問(wèn)。
        實(shí)現(xiàn):客戶端創(chuàng)建一個(gè)<script>標(biāo)簽,將請(qǐng)求后端的接口URL拼接一個(gè)回調(diào)函數(shù)名稱作為參數(shù)傳給后端,并設(shè)置給<script>標(biāo)簽的src屬性。后端接收到請(qǐng)求后,將數(shù)據(jù)和回調(diào)函數(shù)名稱拼接成函數(shù)調(diào)用的形式返回??蛻舳嗽诮邮盏巾憫?yīng)后,會(huì)執(zhí)行這個(gè)回調(diào)函數(shù),從而獲取到后端返回的數(shù)據(jù)。

3、使用代理服務(wù)器

        原理:通過(guò)搭建一個(gè)代理服務(wù)器來(lái)轉(zhuǎn)發(fā)客戶端的請(qǐng)求,代理服務(wù)器與目標(biāo)服務(wù)器進(jìn)行通信,然后將返回的數(shù)據(jù)再轉(zhuǎn)發(fā)給客戶端。由于客戶端和代理服務(wù)器、代理服務(wù)器和目標(biāo)服務(wù)器之間的通信都在服務(wù)器端進(jìn)行,因此不受瀏覽器同源策略的限制。
        實(shí)現(xiàn):可以使用Nginx、Node.js等搭建代理服務(wù)器。例如,Nginx可以通過(guò)配置反向代理來(lái)解決跨域問(wèn)題;Node.js可以搭建一個(gè)中間層服務(wù)器,接收客戶端的請(qǐng)求,然后將請(qǐng)求轉(zhuǎn)發(fā)給目標(biāo)服務(wù)器,并將返回的數(shù)據(jù)再轉(zhuǎn)發(fā)給客戶端。

4、前端正向代理

        原理:在客戶端設(shè)置一個(gè)代理服務(wù)器,并指定目標(biāo)服務(wù)器。代理服務(wù)器向目標(biāo)服務(wù)器轉(zhuǎn)交請(qǐng)求,并將獲得的內(nèi)容發(fā)送給客戶端。這種方式在客戶端進(jìn)行了請(qǐng)求轉(zhuǎn)發(fā),但同樣實(shí)現(xiàn)了跨域請(qǐng)求。
        實(shí)現(xiàn):可以通過(guò)在客戶端代碼中配置代理服務(wù)器地址和端口,以及目標(biāo)服務(wù)器的地址和端口來(lái)實(shí)現(xiàn)。在發(fā)送請(qǐng)求時(shí),將請(qǐng)求地址替換為代理服務(wù)器的地址,并在代理服務(wù)器中進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)。

5、配置瀏覽器插件或工具

        有些瀏覽器插件或工具(如Postman、curl等)可以繞過(guò)瀏覽器的同源策略限制,直接發(fā)送跨域請(qǐng)求。但這種方法主要用于開發(fā)和測(cè)試階段,不建議在生產(chǎn)環(huán)境中使用。

補(bǔ)充:關(guān)于Spring Security的CSRF

關(guān)于Spring Security的CSRF

一、CSRF是什么

        CSRF(Cross-Site Request Forgery,跨站請(qǐng)求偽造)是一種常見的網(wǎng)絡(luò)攻擊方式,攻擊者通過(guò)偽裝用戶的請(qǐng)求,利用用戶在其他網(wǎng)站上已經(jīng)登錄的身份權(quán)限來(lái)執(zhí)行惡意操作。為了防止 CSRF 攻擊,Spring Security 提供了內(nèi)置的 CSRF 保護(hù)功能。

二、Spring Security中的CSRF保護(hù)

        在Spring框架中,如果引入了Spring Security依賴,除了會(huì)默認(rèn)開啟身份驗(yàn)證,同時(shí)還會(huì)開啟CSRF保護(hù)功能。

        啟用此功能可確保,在會(huì)更改狀態(tài)的HTTP請(qǐng)求上,如果沒(méi)有帶上有效的X-CSRFToken,則會(huì)出現(xiàn) 403 錯(cuò)誤。

        HTTP狀態(tài)碼403表示禁止訪問(wèn),即服務(wù)器理解請(qǐng)求客戶端的請(qǐng)求,但是拒絕執(zhí)行這個(gè)請(qǐng)求。這通常是由于客戶端沒(méi)有足夠的權(quán)限訪問(wèn)該資源所導(dǎo)致的。

        可以認(rèn)為安全的方法都是只讀的方法(GET, HEAD, OPTIONS),這些類型的請(qǐng)求不會(huì)改變資源狀態(tài),被認(rèn)為是冪等的,即調(diào)用相同的URL多次得到的結(jié)果不變。

        DELETE方法的語(yǔ)義表示刪除服務(wù)器上的一個(gè)資源,第一次刪除成功后該資源就不存在了,資源狀態(tài)改變了,所以DELETE方法不具備安全特性。然而HTTP協(xié)議規(guī)定DELETE方法是冪等的,每次刪除該資源都要返回狀態(tài)碼200 OK,服務(wù)器端要實(shí)現(xiàn)冪等的DELETE方法,必須記錄所有已刪除資源的元數(shù)據(jù)(Metadata),否則,第二次刪除后返回的響應(yīng)碼就會(huì)類似404 Not Found了。

        PUT和POST方法語(yǔ)義中都有修改資源狀態(tài)的意思,因此都不是安全的。但是PUT方法是冪等的,POST方法不是冪等的,這么設(shè)計(jì)的理由是:

        HTTP協(xié)議規(guī)定,POST方法修改資源狀態(tài)時(shí),URL指示的是該資源的父級(jí)資源,待修改資源的ID信息在請(qǐng)求體中攜帶。而PUT方法修改資源狀態(tài)時(shí),URL直接指示待修改資源。因此,同樣是創(chuàng)建資源,重復(fù)提交POST請(qǐng)求可能產(chǎn)生兩個(gè)不同的資源,而重復(fù)提交PUT請(qǐng)求只會(huì)對(duì)其URL中指定的資源起作用,也就是只會(huì)創(chuàng)建一個(gè)資源。

        因此,當(dāng)Spring Security使用默認(rèn)配置,或手動(dòng)開啟CSRF保護(hù)功能時(shí),我們會(huì)發(fā)現(xiàn),GET請(qǐng)求是正常的,但是POST請(qǐng)求會(huì)報(bào)403錯(cuò)誤。

三、處理方法

處理方法一:跳過(guò)安全檢查(不推薦,因?yàn)檫@個(gè)一般是用于靜態(tài)資源等)

@Bean
//(Spring Security6.2.4寫法)
public WebSecurityCustomizer webSecurityCustomizer() {
    // 匹配的路徑,直接跳過(guò)安全檢查
    return (web) -> web.ignoring().requestMatchers("/static/**");
}

 處理方法二:關(guān)閉CSRF保護(hù)功能

@Bean
//(Spring Security6.2.4寫法)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(
            (authz) -> authz
                .anyRequest().authenticated())
                .httpBasic(withDefaults())
                .formLogin(withDefaults())
                .csrf((csrf)->csrf.disable());
                //只對(duì)匹配路徑關(guān)閉CSRF
                //.csrf((csrf)->csrf.ignoringRequestMatchers("/路徑"));
    return http.build();
}

處理方法三:正常在請(qǐng)求時(shí)帶上X-CSRFToken

到此這篇關(guān)于關(guān)于Spring Security的CORS的文章就介紹到這了,更多相關(guān)Spring Security的CORS內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論