当前位置: 首页 > article >正文

Spring Security中自定义cors配置

一、为什么要自定义cors配置

        在使用Spring框架时,Spring Security组件提供了简便的cors配置方案,使程序开发者可以快速的实现“同源安全策略”。关于cors,可以参数之前的一篇文章--关于Spring Security的CORS_springsecurity cors-CSDN博客

        由于cors涉及到URL 的协议(Protocol)、主机(Host)、端口(Port,这些东西在每个程序上的情况不同,所以一般情况下都是需要根据实际情况来定制适合的cors配置。

二、配置原理

        我们可以先看下Spring Security组件的一个源码。

        org.springframework.security.config.annotation.web.configurers.CorsConfigurer.class

    @Override
	public void configure(H http) {
		ApplicationContext context = http.getSharedObject(ApplicationContext.class);
		CorsFilter corsFilter = getCorsFilter(context);
		Assert.state(corsFilter != null, () -> "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);
		}
		boolean containsCorsFilter = context.containsBeanDefinition(CORS_FILTER_BEAN_NAME);
		if (containsCorsFilter) {
			return context.getBean(CORS_FILTER_BEAN_NAME, CorsFilter.class);
		}
		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);
		}
		if (mvcPresent) {
			return MvcCorsFilter.getMvcCorsFilter(context);
		}
		return null;
	}

        这段源码简单、清晰,两个方法,一个公有,一个私有。configure(H http)被外部调用,实现了两件事,获取一个corsFilter(过滤器)并把这个filter添加到传入的这个名为“http”的对象中。这里也刚好能看出Configurer和Filter的一些关系--configurer会在拿到filter后,通过addFilter(filter)方法将一个filter添加到HttpSecurity对象中。

        再看下getCorsFilter(ApplicationContext context)方法,4个if分支,最终的任务就是new一个CorsFilter并返回。所以自定义cors配置时,可以选择的方法有很多,这里选择创建一个CorsConfigurationSource类型的Bean。这里的getBean方法参数是name和type。所以我们在创建这个Bean的时候,需要确保Bean的名称为“corsConfigurationSource”(CORS_CONFIGURATION_SOURCE_BEAN_NAME对应的字符串),不然这里的getBean会找不到我们自定义创建的CorsConfigurationSource。

三、自定义配置

@Configuration
public class SecurityConfig {
    /**
     * 跨域资源共享过滤器
     */
    @Autowired
    @Bean
    public CorsFilter corsFilter(UrlBasedCorsConfigurationSource configurationSource){
        return new CorsFilter(configurationSource);
    }
    /**
     * 跨域资源共享过滤器配置
     */
    @Bean
    public UrlBasedCorsConfigurationSource corsConfigurationSource(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOriginPattern("http://localhost*");
        source.registerCorsConfiguration("/**",corsConfiguration);
        return source;
    }
}

        几个要注意的地方:

1、类名上方的@Configuration注解,这个是为了指定该类为配置类,Spring容器启动时,会调用带有@Bean注解的方法来生成对应实例,并将实例注册为与方法名相同的Bean,并管理起来。

2、方法名,第1点说了,注册的Bean名称是和方法名一致的,所以这里的方法名需要是“corsConfigurationSource”,不能自定义方法名。

3、上面代码中的corsFilter()方法,可以不写。因为从前面的Spring Security源码中可以看出,如果没有这个corsFilter的Bean,它也会自己new一个。如果要自定义corsFilter,同样要注意方法名。至于参数,如果有带,需要注意参数类型(参数名可以任意),并在方法名上方多带一个@Autowired注解,这个注解会自动找到类型为UrlBasedCorsConfigurationSource的Bean,并使用它。如果不带参数,那也可以用普通方法,先获取corsConfigurationSource()方法返回的对象,再以些为参数,new一个corsFilter对象。


http://www.kler.cn/news/329802.html

相关文章:

  • 【算法篇】回溯算法类(1)(笔记)
  • 虚拟机U盘启动
  • 使用 Git 帮助文档
  • 养老院管理系统(含源码+sql+视频导入教程+文档)
  • 图解C#高级教程(四):协变、逆变
  • JSR303微服务校验
  • docker-compose 快速部署clickhouse集群
  • Springboot项目在win系统开发部署到linux服务器出现上传文件编码问题
  • 如何改善网站的核心网络生命力
  • TypeScript 封装 Axios 1.7.7
  • 软件测试面试八股文(含答案+文档)
  • 【yolov8】模型导出----pytorch导出为onnx模型
  • windows美化终端
  • go结构体默认值和校验器(go-defaults、go-validator)
  • 【Redis】主从复制(下)--主从复制原理和流程
  • 【数据分享】2001-2023年我国省市县镇四级的逐月平均气温数据(免费获取/Shp/Excel格式)
  • ubuntu 安装kvm 创建windos虚拟机
  • AMD 矩阵核心
  • 搜维尔科技:使用Xsens动作捕捉系统和ai训练人形机器人模仿人类运动,执行复杂任务
  • docker环境下配置cerbot获取免费ssl证书并自动续期
  • java中有两个list列表,尽量少的去循环
  • 模版and初识vector
  • windows系统电脑上scrcpy源码本地调试
  • Java基础——十二、容器
  • 5G NR物理信号
  • git push 远程仓库 linux版
  • 爬虫——爬虫理论+request模块
  • 【Linux】进程周边之优先级
  • 陶建辉先生荣获 2024 年“中国计算机学会(CCF)杰出工程师奖”
  • Harbor系列之12:对接外部redis和pg数据库的harbor容器化部署