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网关配置的跨域 ...
随机推荐
- Spring基础 01 | Ioc
Maven项目的创建 项目所在路径 - 项目一 - 创建Module - 添加Webapp(Project Structure) - 项目二 Spring简介 分层全栈(各层解决方案)轻量级框架,以I ...
- 再制作个WCH-LINK下载器
用CH549可以制作成支持两种模式的WCH-LINK下载器,两种模式指的是RISC-V和DAPLINK模式. 如果用于沁恒的CH32V203等芯片,我们可以将这个下载器设置成RISC-V下载模式. 如 ...
- Dynaimc CRM查找字段自定义过滤视图
实现方式参考官方文档提供的Xrm.Page.getControl(arg).addCustomView(viewId, entityName, viewDisplayName, fetchXml, l ...
- Java验证邮箱是否有用的实现与解析
在现代互联网应用中,邮箱验证是一个常见的需求.通过邮箱验证,开发者可以确保用户提供的邮箱地址是有效的,从而在后续的操作中,如密码重置.通知发送等,依赖这些有效的邮箱地址.本文将详细介绍如何使用Java ...
- .NET 中管理 Web API 文档的两种方式
前言 在 .NET 开发中管理 Web API 文档是确保 API 易用性.可维护性和一致性的关键.今天大姚给大家分享两种在 .NET 中管理 Web API 文档的方式,希望可以帮助到有需要的同学. ...
- WPF test animation robot(simulate blink,mouse talk)
WPF 动画,模拟机器人眨眼,说话. using System; using System.Collections.Generic; using System.Linq; using System.T ...
- runoob-Android 基础入门教程-2
https://www.runoob.com/w3cnote/android-tutorial-textview.html 1.0 Android基础入门教程 1.0.1 2015年最新Android ...
- C 国家名字按字母顺序排序
问题 输入五个国家的名字,并按字母的顺序排列输出 分析 知识点 strcpy(1,2):将字符串2复制到字符数组1中 strcmp(1,2):比较字符串大小 二维数组 代码 #include & ...
- C :文件
一直没有系统学习过该章节,现参考<C语言程序设计 (第四版)谭浩强> C文件基本知识 什么是文件 文件名 文件的分类 文件缓冲区 文件类型指针 typedef struct { short ...
- 从0到1构建开源 vue-uniapp-template:使用 UniApp + Vue3 + TypeScript 和 VSCoe、CLI 开发跨平台移动端脚手架
作者主页: 有来技术 开源项目: youlai-mall︱vue3-element-admin︱youlai-boot︱vue-uniapp-template 仓库主页: GitCode︱ Gitee ...