SpringSecurity中的跨域问题处理方案

2025-11-27 19:50

本文主要是介绍SpringSecurity中的跨域问题处理方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringSecurity中的跨域问题处理方案》本文介绍了跨域资源共享(CORS)技术在JavaEE开发中的应用,详细讲解了CORS的工作原理,包括简单请求和非简单请求的处理方式,本文结合实例代码...

跨域问题是实际应用开发中一个非常常见的需求,在Spring框架中对于跨域问题的处理方案有好几种,引入了Spring Security之后,跨域问题的处理方案又增加了。

1.什么是CORS

CORS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求。在JavaEE开发中,最常见的前端跨域请求解决方案是早起的jsONP,但是JSONP只支持GET请求,这是一个很大的缺陷,而CORS则支持多种HTTP请求方法,也是目前主流的跨域解决方案。

CORS中新增了一组HTTP请求头字段,通过这些字段,服务器高炉浏览器,哪些网站通过浏览器有权限访问哪些资源。同时规定,对那些可能修改服务器数据的HTTP请求方法(如GET以外的HTTP请求等),浏览器必须首先使用OPTIONS方法发起一个预检请求(prenightst),预检请求的目的是查看服务端是否支持即将发起的跨域请求,如果服务端允许,才发送实际的HTTP请求。在预检请求的返回中,服务端也可以通知客户端,是否需要携带身份凭证(如Cookies、HTTP认证信息等)。

CORS: 同源/同域 = 协议 + 主机 + 端口

2.简单请求

GET请求为例,如果需要发起一个跨域请求,则请求头如下:

Host: localhost:8080
Origin: http://localhost:8081
Referer: http://localhost:8081/index.html

如果五段支持该跨域请求,那么返回的响应头中将包含如下字段:

Acpythoncess-Control-Allow-Origin: http://localhost:8081

Access-Control-Allow-Origin字段用来告诉浏览器可以访问该资源的域,当浏览器收到这样的响应头信息之后,提取出Access-Control-Allow-Origin字段中的值,发现该值包含当前页面所在的域,就知道这个跨域是被允许的,因此就不再对前端的跨域请求进行限制。这属于简单请求,即不需要进行预检请求的跨域。

3.非简单请求

对于一些非简单请求,会首先发送一个预检请求。预检请求类似下面这样:

OPTIONS /put HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: PUT
Origin: http://localhost:8081
Referer: http://localhost:8081/index.html

请求方法是OPTIONS,请求头Origin编程就钙素服务端当前页面所在域,请求头Access-Control-Request-Methods告诉服务器端即将发起的跨域请求所使用的方法。服务端对此进行判断,如果允许即将发起的跨域请求,则会给出如下响应:

HTTP/1.1 200
Access-Control-Allow-Origin:http://localhost: 8081
Access-Control-Request-Methods: PUT
Access-Control-Max-Age: 3600

Access-Control-Allow-Methods字段表示允许的跨域方法:Access-Control-Max-Age字段表示预检请求的有效期,单位为秒,在有效期内如果发起该跨域请求,则不用再次发起预检请求。预检请求结束后,接下来就会发起一个真正的跨域请求,跨域请求和前面的简单请求跨域步骤类似。

4.Spring跨域解决方案

4.1.@CrossOrigin

Spring中第一种处理跨域的方式是通过@CrossOrigin注解来标记支持跨域,该注解可以添加在方法上,也可以添加在Controller上。当添加在Controller上时,表示Controller中的所有接口都支持跨域,具体配置如下:

@RestController
public class IndexController {
    @GetMapping("/hello")
    @CrossOrigin(origins = "http://localhost:8081")
    public String hello(){
        System.out.println("hello ok");
        return "hello ok";
    }
}

@CrossOrigin注解各属性含义如下:

  • allowCredentials:浏览器是否应当发送凭证信息,如Cookie。
  • allowedHeaders:请求被允许的请求头字段,*表示所有字段。
  • exposedHeaders:哪些响应头可以作为相应的一部分暴露出来。

注意,这里只可以一一列举,通配符 * 在这里是无效的。

  • maxAge:预检请求的有效期,有效期内不必再次发送预检请求,默认是1800秒
  • methods:允许的请求方法,*表示允许的所有方法。
  • origins:允许的域,*表示允许所有域。

4.2.addCrossMapping自定义mvc配置

@CrossOrigin注解需要添加在不同的Controller上。所以还有一种全局配置方法,就是通过重写WebMvcConfigurerComposite#addCorsMappings方法来实现,具体配置如下:

//自定义mvc配置类
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    //用来全局处理跨域
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")   //处理的请求地址
                .allowedMethods("*")
                .allowedOrigins("*")
                .allowedHeaders("*")
                .allowCredentials(false)
                .exposedHeaders("")
                .maxAge(3600);
    }
}

4.3.CorsFilter

CorsFilter是Spring Web中提供的一个处理跨域的过滤器,开发者也可以通过该过滤器处理跨域。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
/**
 * @author zhangKaiTao
 * @date 2022/7/24 10:30
 */
//自定义mvc配置类
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Bean
    FilterRegistrationBean<CorsFilter> corsFilter(){
        FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfigurhttp://www.chinasem.cnation("/**",corsConfiguration);
        registrationBean.setFilter(new CorsFilter(source));
        registrationBean.setOrder(-1);
        return registrationBean;
    }
}

5.SpringSecurity跨域解决方案

当我们为项目添加了Spring Security依赖后,发现上面三种跨域方式有的失效了,有的则可以继续使用,这是怎么回事?

通过@CrossOrigin注解或者重写addCorsMappings方法配置跨域,统统失效了,通过CorsFilter配置的跨域,有没有失效则要看过滤器的优先级,如果过滤器优先级高于SpringSecurity过滤器,即先于Spring Security过滤器执行,则CorsFilter所配置的跨域处理依然有效;如果过滤器优先级地域Spring Security过滤器,则CorsFilyer所配置的跨域处理就会失效。

以下是Filter、DispatcherServlet以及Interceptor执行顺序。

SpringSecurity中的跨域问题处理方案

由于非简单请求都要首先发送一个预检请求(request),而预检请求并不会携带认证信息,所以预检请求就有被Spring Security拦截的可能。因此通过@CrossOrigin注解或者重写addCorsMappings方法配置跨域就会失效。如果使用CorsFilter配置的跨域,只要过滤器优先级高于SpringSecurity过滤器就不会有问题,反之同样会出现问题。

SpringSecurity中的跨域问题处理方案

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	//...
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        htjavascripttp.authorizeHttpRequandroidests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .cors().configurationSource(corsConfigurationSource())
                .and()
                .csrf().disable();//开启csrf
    }
    CorsConfigurationSource corsConfigurationSource(){
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",corsConfiguration);
        return source;
    }
}

到此这篇关于SpringSecurity中的跨域问题处理方案的文章就介绍到这了,更多相关SpringSecurity跨域内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于SpringSecurity中的跨域问题处理方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1156289

相关文章

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

Java方法重载与重写之同名方法的双面魔法(最新整理)

《Java方法重载与重写之同名方法的双面魔法(最新整理)》文章介绍了Java中的方法重载Overloading和方法重写Overriding的区别联系,方法重载是指在同一个类中,允许存在多个方法名相同... 目录Java方法重载与重写:同名方法的双面魔法方法重载(Overloading):同门师兄弟的不同绝

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加