SpringSecurity(09)——跨域配置

SpringBoot跨域处理

@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";
    }
}
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping(method = RequestMethod.GET, path = "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

WebMvcConfigurer(全局跨域)

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
 
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")
                .allowedMethods("*")
                .allowedOrigins("*")
                .allowCredentials(true);
    }
}

SpringSecurity跨域处理

如果使用了 Spring Security,上面的跨域配置会失效,因为请求被 Spring Security 拦截了

在项目中使用 Spring Security,我们必须采取额外的步骤确保它与 CORS 协作良好。这是因为 CORS 需要首先处理,否则,Spring Security 会在请求到达 Spring MVC 之前将其拒绝

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
}

可以配置 CORS 以覆盖默认的 Spring Security CORS 处理器。为此,我们需要添加一个 CorsConfigurationSource Bean,使用 CorsConfiguration 实例来处理 CORS 配置。如果添加了 CorsFilter Bean,http.cors() 方法就会使用 CorsFilter,否则就会使用 CorsConfigurationSource。如果两者都未配置,则使用 Spring MVC pattern inspector handler。

CorsConfigurationSource(全局跨域)

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
    
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

CosFilter(全局跨域)

@Configuration
public class GlobalCorsConfig {
    
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        config.addAllowedOrigin("*");
        //是否发送Cookie信息
        config.setAllowCredentials(true);
        //放行哪些原始域(请求方式)
        config.addAllowedMethod("*");
        //放行哪些原始域(头部信息)
        config.addAllowedHeader("*");
        //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
        config.addExposedHeader("*");
 
        //2.添加映射路径
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
 
        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

自定义Filter(全局跨域)

public class CorsFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String orignalHeader = StringUtils.defaultIfBlank(request.getHeader("Origin"), "*");
        // 指定本次预检请求的有效期
        response.setHeader("Access-Control-Max-Age", "3600");
        // 服务器支持的所有头信息字段
        response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
        response.setHeader("Access-Control-Allow-Origin", orignalHeader);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        filterChain.doFilter(request, response);
    }
}
@Configuration
public class WebMvcConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new CorsFilter(), WebAsyncManagerIntegrationFilter.class);
    }
}

你可能感兴趣的:(SpringSecurity,spring,java)