<option id="mwy0y"><strong id="mwy0y"></strong></option>
  • <ul id="mwy0y"><sup id="mwy0y"></sup></ul>
  • <ul id="mwy0y"></ul>
  • <del id="mwy0y"><dfn id="mwy0y"></dfn></del><ul id="mwy0y"><sup id="mwy0y"></sup></ul>
  • <abbr id="mwy0y"></abbr>

    千鋒教育-做有情懷、有良心、有品質的職業教育機構

    400-811-9990
    手機站
    千鋒教育

    千鋒學習站 | 隨時隨地免費學

    千鋒教育

    掃一掃進入千鋒手機站

    領取全套視頻
    千鋒教育

    關注千鋒學習站小程序
    隨時隨地免費學習課程

    上海
    • 北京
    • 鄭州
    • 武漢
    • 成都
    • 西安
    • 沈陽
    • 廣州
    • 南京
    • 深圳
    • 大連
    • 青島
    • 杭州
    • 重慶
    當前位置:長沙千鋒IT培訓  >  技術要點  >  Spring Security系列教程解決Spring Security環境中的跨域問題

    Spring Security系列教程解決Spring Security環境中的跨域問題

    來源:千鋒教育
    發布人:千鋒長沙
    時間: 2021-10-29 16:49:06

           在本篇文章中,將會帶大家進行代碼實現,看看在Spring Security環境中如何解決跨域問題。

           一. 啟用Spring Security 的CORS支持

           1. 創建web接口

           我先在SpringBoot環境中,創建一個端口號為8080的web項目,注意這個web項目沒有引入Spring Security的依賴包。然后在其中創建一個IndexController,定義兩個測試接口以便被ajax進行跨域訪問。8080項目的代碼結構:

    @RestController

    public class IndexController {

    @GetMapping("/hello")

    public String hello() {

    return "get hello";

    }

    @PostMapping("/hello")

    public String hello2() {

    return "post hello";

    }

    }

    請參考如下代碼結構進行項目創建。

    圖片1

           2. 執行ajax請求

           我們接下來再創建另一個端口號為8082的web項目,注意這個web項目也沒有引入Spring Security的依賴包。接著在這里定義一個index.html頁面,利用ajax跨域訪問8080項目中的web接口。

    8082項目的代碼結構:

    <!DOCTYPE html>

    <html lang="en">

    <head>

    <meta charset="UTF-8">

    <title>Index</title>

    <script type="text/javascript" src="jquery-2.1.0.js"></script>

    </head>

    <body>

    <div id="app"></div>

    <input type="button" onclick="btnClick()" value="get請求">

    <input type="button" onclick="btnClick2()" value="post請求">

    <script>

    function btnClick() {

    $.get('http://localhost:8080/hello', function (msg) {

    $("#app").html(msg);

    });

    }

    function btnClick2() {

    $.post('http://localhost:8080/hello', function (msg) {

    $("#app").html(msg);

    });

    }

    </script>

    </body>

    </html>

    請參考如下代碼結構進行項目創建。

    圖片2

    3. 發起跨域請求

    我們訪問8082項目中的index.html頁面,然后分別執行get與post請求,這時候就可以在瀏覽器的控制臺上看到產生了CORS跨域問題,出現了CORS error狀態,在請求頭中出現了Referer Policy: strict-origin-when-cross-origin。

    圖片3

    圖片4

           4. 解決跨域問題

           既然現在產生了跨域問題,那么該怎么解決呢?其實我們可以采用如下兩種方式之一來解決跨域問題。

    方式1:在接口方法上利用@CrossOrigin注解解決跨域問題

    @RestController

    public class IndexController {

    @CrossOrigin(value = "http://localhost:8082")

    @GetMapping("/hello")

    public String hello() {

    return "get hello";

    }

    @CrossOrigin(value = "http://localhost:8082")

    @PostMapping("/hello")

    public String hello2() {

    return "post hello";

    }

    }

    方式2:通過實現WebMvcConfigurer接口來解決跨域問題

    @Configuration

    public class WebMvcConfig implements WebMvcConfigurer {

    @Override

    public void addCorsMappings(CorsRegistry registry) {

    registry.addMapping("/**")

    .allowedOrigins("http://localhost:8082")

    .allowedMethods("*")

    .allowedHeaders("*");

    }

    }

    當進行了跨域設置之后,我們再次進行跨域請求,就可以看到請求成功了。

    圖片5

           二. Spring Security環境下的跨域問題解決

           1. 引入Spring Security依賴

           通過上面的配置,我們已經解決了Ajax的跨域請求問題,但是這個案例中也有潛在的威脅存在,常見的就是 CSRF(Cross-site request forgery) 跨站請求偽造。跨站請求偽造也被稱為 one-click attack 或者 session riding,通常縮寫為 CSRF 或者 XSRF,是一種挾制用戶在當前已登錄的 Web 應用程序上執行非本意的操作的攻擊方法。

           所以為了提高網站的安全性,我在上面Spring Boot項目的基礎之上,添加Spring Security的依賴包,但是暫時不進行任何別的操作。

    <dependencies>

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-security</artifactId>

    </dependency>

    </dependencies>

           2. 重啟8080項目進行測試

           接著我就重啟8080這個Spring Boot項目,然后在8082項目中再次進行跨域請求,我們會發現在引入Spring Security后,再次產生了跨域問題。

    圖片6

           3. 解決Spring Security環境下跨域問題的3種方案

           通過實驗可知,如果使用了 Spring Security,上面的跨域配置會失效,因為請求會被 Spring Security 攔截。那么在Spring Security環境中,如何解決跨域問題呢?這里我們有3種方式可以開啟 Spring Security 對跨域的支持。

           3.1 方式一:開啟cors方法

           我們在上面的案例之上,編寫一個SecurityConfig配置類,在configure方法中,利用cors() 開啟Spring Security 對 CORS 的支持:

    @EnableWebSecurity

    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()

    .anyRequest()

    .permitAll()

    .and()

    .formLogin()

    .permitAll()

    .and()

    .httpBasic()

    .and()

    //支持跨域訪問

    .cors()

    .and()

    .csrf()

    .disable();

    }

    }

          3.2 方式二:進行全局配置

          第二種方式是去除上面的跨域配置,直接在 Spring Security 中做全局配置,如下:

    @EnableWebSecurity

    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()

    .anyRequest()

    .permitAll()

    .and()

    .formLogin()

    .permitAll()

    .and()

    .httpBasic()

    .and()

    //支持跨域訪問

    .cors()

    .configurationSource(corsConfigurationSource())

    .and()

    .csrf()

    .disable();

    }

    @Bean

    public CorsConfigurationSource corsConfigurationSource() {

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

    CorsConfiguration configuration = new CorsConfiguration();

    configuration.setAllowCredentials(true);

    configuration.setAllowedOrigins(Collections.singletonList("*"));

    configuration.setAllowedMethods(Collections.singletonList("*"));

    configuration.setAllowedHeaders(Collections.singletonList("*"));

    configuration.setMaxAge(Duration.ofHours(1));

    source.registerCorsConfiguration("/**", configuration);

    return source;

    }

    }

    以上2個方法,都可以實現在Spring Security環境下的跨域訪問。

           3.3 方式三:支持OAuth2的跨域訪問

           我們開發時,還有一種情況就是支持 OAuth2 相關接口的跨域,比如用戶要訪問 OAuth2 中的 /oauth/token 等接口。我們可以配置一個全局的 CorsFilter 跨域過濾器類,核心代碼如下:

    /**

    * 跨域配置方式3:定義全局跨域過濾器

    **/

    @Configuration

    public class GlobalCorsConfiguration {

    @Bean

    public CorsFilter corsFilter() {

    CorsConfiguration corsConfiguration = new CorsConfiguration();

    corsConfiguration.setAllowCredentials(true);

    corsConfiguration.addAllowedOrigin("*");

    corsConfiguration.addAllowedHeader("*");

    corsConfiguration.addAllowedMethod("*");

    UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();

    urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

    return new CorsFilter(urlBasedCorsConfigurationSource);

    }

    }

    @EnableWebSecurity

    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(HttpSecurity http) throws Exception {

    //跨域方式3:

    http.requestMatchers()

    .antMatchers(HttpMethod.OPTIONS, "/oauth/**")

    .and()

    .csrf()

    .disable()

    .formLogin()

    .and()

    .cors();

    }

    }

    該方式也可以實現Spring Security中的跨域訪問。

           4. 代碼結構

           以下是本案例的代碼結構,可以參考下圖進行項目創建:

    圖片7

           至此,我就帶各位解決了Spring Security環境中的跨域問題,你學會了嗎?

    圖片8

    關注WX公眾號【Java架構棧】,跟著千鋒一起學Java

           

    聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。

    猜你喜歡LIKE

    最新文章NEW

    相關推薦HOT

    更多>>

    快速通道 更多>>

    最新開班信息 更多>>

    網友熱搜 更多>>