SpringSecurity5(11-跨域配置)
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。
public class CorsConfigurer<H extends HttpSecurityBuilder<H>>
extends AbstractHttpConfigurer<CorsConfigurer<H>, H> {
private static final String HANDLER_MAPPING_INTROSPECTOR = "org.springframework.web.servlet.handler.HandlerMappingIntrospector";
private static final String CORS_CONFIGURATION_SOURCE_BEAN_NAME = "corsConfigurationSource";
private static final String CORS_FILTER_BEAN_NAME = "corsFilter";
private CorsConfigurationSource configurationSource;
public CorsConfigurer() {
}
public CorsConfigurer<H> configurationSource(
CorsConfigurationSource configurationSource) {
this.configurationSource = configurationSource;
return this;
}
@Override
public void configure(H http) {
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
CorsFilter corsFilter = getCorsFilter(context);
if (corsFilter == null) {
throw new IllegalStateException(
"Please configure either a " + CORS_FILTER_BEAN_NAME + " bean or a "
+ CORS_CONFIGURATION_SOURCE_BEAN_NAME + "bean.");
}
http.addFilter(corsFilter);
}
private CorsFilter getCorsFilter(ApplicationContext context) {
if (this.configurationSource != null) {
return new CorsFilter(this.configurationSource);
}
// 查找是否有名为corsFilter的Bean对象
boolean containsCorsFilter = context
.containsBeanDefinition(CORS_FILTER_BEAN_NAME);
if (containsCorsFilter) {
return context.getBean(CORS_FILTER_BEAN_NAME, CorsFilter.class);
}
// 查找是否有名为corsConfigurationSource的Bean对象
boolean containsCorsSource = context
.containsBean(CORS_CONFIGURATION_SOURCE_BEAN_NAME);
if (containsCorsSource) {
CorsConfigurationSource configurationSource = context.getBean(
CORS_CONFIGURATION_SOURCE_BEAN_NAME, CorsConfigurationSource.class);
return new CorsFilter(configurationSource);
}
// 查找是否有org.springframework.web.servlet.handler.HandlerMappingIntrospector该类
boolean mvcPresent = ClassUtils.isPresent(HANDLER_MAPPING_INTROSPECTOR,
context.getClassLoader());
if (mvcPresent) {
return MvcCorsFilter.getMvcCorsFilter(context);
}
return null;
}
static class MvcCorsFilter {
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
private static CorsFilter getMvcCorsFilter(ApplicationContext context) {
if (!context.containsBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
throw new NoSuchBeanDefinitionException(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, "A Bean named " + HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME +" of type " + HandlerMappingIntrospector.class.getName()
+ " is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.");
}
// 获取名为mvcHandlerMappingIntrospector的Bean对象
HandlerMappingIntrospector mappingIntrospector = context.getBean(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, HandlerMappingIntrospector.class);
return new CorsFilter(mappingIntrospector);
}
}
}
CorsConfigurationSource(全局跨域)
@Configuration
public class SpringSecurityConfig 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() {
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(全局跨域)
还有一种情况就是支持 OAuth2 相关接口的跨域,比如用户要访问 OAuth2 中的 /oauth/token 等接口,可以配置一个全局的 CorsFilter 跨域过滤器类
@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);
}
}

SpringSecurity5(11-跨域配置)的更多相关文章
- asp.net core api 跨域配置
项目前后端分离,前端请求接口例如使用axios发送请求时浏览器会提示跨域错误,需要后端配置允许接口跨域 配置步骤: 1.通过NuGet安装Microsoft.AspNetCore.Cors.dll类库 ...
- windows上 nginx 配置代理服务,配置多域名,以及最简单实现跨域配置
Nginx,不用多说啦,大家都熟悉的不能再熟悉了,它是一款轻量级的高性能Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,最近在本地研究将nginx和resin配合使用,使服务 ...
- 014.Nginx跨域配置
一 跨域概述 1.1 同源策略 同源策略是一个安全策略.同源,指的是协议,域名,端口相同.浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的 ...
- Asp.Net Core跨域配置
在没有设置跨域配置的时候,Ajax请求时会报以下错误 已拦截跨源请求:同源策略禁止读取位于 http://localhost:5000/Home/gettime 的远程资源.(原因:CORS 头缺少 ...
- Springboot统一跨域配置
前言:跨域是什么? 要知道跨域的概念,我们先明确怎样算是同一个域: 同一个域指的是同一协议,同一ip,同一端口 如果这三同中有一者不同就产生了跨域. 在做前后端分离的项目中,通过ajax请求后台端口时 ...
- Asp.net跨域配置
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Contro ...
- asp.net (webapi) core 2.1 跨域配置
原文:asp.net (webapi) core 2.1 跨域配置 官方文档 ➡️ https://docs.microsoft.com/zh-cn/aspnet/core/security/cors ...
- .net core api服务端跨域配置
第1步:添加包引用(.net core 2.2 已自带此包,可跳过此步骤) Install-Package Microsoft.AspNetCore.Cors 第2步:在Startup.cs文件的Co ...
- nginx-springboot-vue前后端分离跨域配置
nginx-springboot-vue前后端分离跨域配置 引言 接着上篇--简单的springboot-vue前后端分离登录Session拦截的demo,其中跨域是通过springboot后端全局设 ...
- 常见跨域解决方案以及Ocelot 跨域配置
常见跨域解决方案以及Ocelot 跨域配置 Intro 我们在使用前后端分离的模式进行开发的时候,如果前端项目和api项目不是一个域名下往往会有跨域问题.今天来介绍一下我们在Ocelot网关配置的跨域 ...
随机推荐
- 编译Ubuntu 24.04 LTS 内核(BuildYourOwnKernel)
1.配置环境 修改apt源 修改 /etc/apt/sources.list.d/ubuntu.sources ,添加 "deb-src"到 Types:,修改后的文件内容如下: ...
- 更改高通xbl串口log波特率
本修改基于高通QCM6125平台,目的是为了满足客户无聊的需求. 注意事项: 基准时钟频率需要是硬件和驱动支持的频率,时钟频率和分频系数可以从AP侧驱动中找到 最低分频系数需要满足分频公式(能够被整除 ...
- 记录vue和element-ui导出表格到excell
1.安装插件 npm install 'file-saver' npm install 'xlsx' 2.引入插件 import FileSaver from 'file-saver' import ...
- Appium_iOS 配置
一. iOS Driver 配置 options = AppiumOptions()options.load_capabilities({ "platformName": &quo ...
- Docker安装Redis并设置密码
1. 镜像下载 docker pull redis 2. 创建目录 mkdir -p /etc/redis/redis.conf mkdir -p /data/redis 3. 启动容器 docker ...
- c# UWP 墨迹 手写识别
<InkCanvas Name="inkCanvas"></InkCanvas> <Button Name="btnRecognize&qu ...
- MySQL主从复制与读写分离原理
目录1 主从复制与读写分离的意义 1.1 什么是主从复制 1.2 主从数据库的好处和缺点 2 主从复制 2.1 主从复制的形式 2.2 主从复制的原理 2.3 主从复制的模式 异步模式 半同步模式 - ...
- Kotlin:【对象】object关键字、对象表达式、伴生对象、嵌套类、数据类、copy、解构声明、使用数据类的条件、运算符重载、枚举类、代数数据类型、密封类
- HiJobQueue:一个简单的线程安全任务队列
HiJobQueue:一个简单的线程安全任务队列 概述 HiJobQueue 是一个线程安全的任务队列,用于在多线程环境中管理和执行异步任务.它的设计参考了 Cobalt 项目中的 JobQueue, ...
- Sa-Token v1.20.0 发布,新增临时Token认证
框架介绍 Sa-Token是一个轻量级Java权限认证框架,主要解决:登录认证.权限认证.分布式Session会话.单点登录.OAuth2.0 等一系列权限相关问题. 框架针对踢人下线.自动续签.前后 ...