1. 程式人生 > >Spring Boot Security跨域訪問 cors

Spring Boot Security跨域訪問 cors


使用Spring Security 在Boot 專案中,實現前後端分離的跨域訪問,只需要簡單的配置即可。

未使用Security 的Boot 專案

在未使用Spring Security 的Boot 專案中,只需要在 Application.java 中新增如下程式碼即可

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry)
{ registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("PUT", "DELETE", "GET", "POST", "OPTIONS") .allowedHeaders("*") .exposedHeaders("access-control-allow-headers", "access-control-allow-methods"
, "access-control-allow-origin", "access-control-max-age", "X-Frame-Options") .allowCredentials(true).maxAge(3600); } }; }

或者單獨以Config 的形式

@Configuration
public class WebConfig extends
WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("PUT", "DELETE", "GET", "POST", "OPTIONS") .allowedHeaders("*") .exposedHeaders("access-control-allow-headers", "access-control-allow-methods", "access-control-allow-origin", "access-control-max-age", "X-Frame-Options") .allowCredentials(true).maxAge(3600); } }

使用Security 的情況

使用Security 時,為了讓所有介面都支援跨域,以及支援自定義的 請求方式 (GET POST PUT 等)。只需要增加如下配置:

/**
 * Security 配置
 *
 * @author xuefeihu
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(loginAuthenticationProvider);
        auth.authenticationProvider(tokenAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            // 開啟跨域
            .cors().and()

            .exceptionHandling()
            .authenticationEntryPoint(this.authenticationEntryPoint)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers('/api/login').permitAll()
            .and()
            .addFilterBefore(buildTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
    }

}

使用Security開啟允許iframe巢狀

使用上面的配置,當前端頁面發生巢狀時,會響應如下響應頭,從而不可以巢狀頁面。

在這裡插入圖片描述

此時只需要禁用 X-Frame-Options 頭即可,如下所示:

/**
 * Security 配置
 *
 * @author xuefeihu
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 開啟允許iframe 巢狀
        http.headers().frameOptions().disable();

        http.csrf().disable()
            // 開啟跨域
            .cors().and()

            .exceptionHandling()
            .authenticationEntryPoint(this.authenticationEntryPoint)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers('/api/login').permitAll()
            .and()
            .addFilterBefore(buildTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
    }

}