集成springSecurity遇到的跨域问题

引言

该项目主要使用技术:sprinboot、springSecurity、vue,其它的技术就不介绍了

其中springSecurity是我参考网上的案例去进行的集成,虽然集成成功了,但是还不是太懂。

下面就开始介绍一下我遇到的问题

问题重现

由于我项目后端集成了springSecurity,所以项目的登录验证和鉴权就是使用的springSecury来进行的,前端的话使用的element-ui-admin作为模板进行二开。

起初前端在进行登录的时候是可以正常访问后端不会出现跨域的问题,直到到了后面请求我的一个delete接口,这个时候就出现了跨域的问题,通过f12可以看见报403错误以及options错误

尝试修改Configuration(×)

然后我就去调我后端之前配置的跨域配置,如下是我原来的配置:

/**
 * <p>
 * 解决跨域问题
 * </p>
 *
 * @author:雷子杰
 * @date:2022/10/29
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("*")//允许任何方法
                .allowCredentials(true)
        		.maxAge(3600);
    }
}

其实我这个配置是没问题的,所以改来改去还是没啥作用。

尝试增加@CrossOrigin(×)

然后我就想到在Controller层增加@CrossOrigin,但是加了后还是没啥用

尝试更改前端跨域(×)

前端跨域就是webpack来进行请求代理,在vue.config.js中去添加以下即可,但是我添加了后,似乎是没了跨域的问题,但出现了新的问题,前端传过去的request中的数据是null(无法获取登录时用户传过去的数据,但前端确实是传过去了的)

devServer: {
  port: port,
  open: true,
  overlay: {
    warnings: false,
    errors: true
  },
  before: require('./mock/mock-server.js'),
  proxy: {
    '/api': {
      // 代理名称   凡是使用/api开头的地址都是用此代理
      target: 'http://192.168.1.6:8888', // 需要代理访问的api地址
      changeOrigin: true, // 允许跨域请求
      secure: false, // 忽略 HTTPS 安全提示
      pathRewrite: {
        // 重写路径,替换请求地址中的指定路径
        '^/api': '' // 将请求地址中的/api替换为空,也就是请求地址中不会包含/api/
      }
    }
  },
  disableHostCheck: true
}

问题原因

产生问题的原因在标题就已经说明了,就是跨域的问题,但是产生的原因的话,不太清楚,我后面看了下我之前下载的编程不良人springSecurity的笔记,发现他在笔记中写道如下:

后端跨域问题的解决的三种解决方案

  • @CrossOrigin

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

    @RestController
    public Class HelloController{
    	@CrossOrigin (origins ="http://localhost:8081")
    	@PostMapping ("/post")
    	public String post (){
    		return "hello post";
    	}
    }
    
  • addCrosMapping

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

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer{
      Override
      public void addCorsMappings (CorsRegistry registry){
        registry.addMapping("/**") //处理的请求地址
        .allowedMethods ("*")allowedorigins("*")
        .allowedHeaders ("*")
        .allowCredentials (false)
        •exposedHeaders ("")
        .maxAge (3600) ;
      }
    }
    
  • CrosFilter

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

    @Configuration
    public class WebMvcConfig {
        @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.registerCorsConfiguration("/**", corsConfiguration);
            registrationBean.setFilter(new CorsFilter(source));
            registrationBean.setOrder(-1);//filter 0 1
            return registrationBean;
        }
    }
    

SprngSecurity跨域原理分析

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

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

为了理清楚这个问题,我们先简略了解一下 Filter、DispatchserServlet 以及Interceptor 执行顺序。

image-20220521074711128

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

解决方案

Spring Security 中也提供了更专业的方式来解决预检请求所面临的问题。如:

关键位置:configurationSource().cors().configurationSource(configurationSource())

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
		@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .and()
                .cors() //跨域处理方案
                .configurationSource(configurationSource())
                .and()
                .csrf().disable();
    }

    //这个是配置跨域方法
    CorsConfigurationSource configurationSource() {
        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;
    }
}

最终我解决的方式就是去掉我之前配置的addCrosMapping,在springSecurity的配置文件中去进行跨域配置操作

总结

在学习的路上总是会遇到许多问题,一时无法解决不要紧,只要找准了方向,就一定能够解决!

Spring Security 是一个基于 Spring 的安全框架,主要用于为 Java Web 应用程序提供身份验证和授权功能。而跨域请求通常是指在浏览器环境下,前端页面使用 AJAX 发起跨域请求,而后端服务器需要响应跨域请求的场景。 Spring Security 提供了解决跨域请求的方式,其中比较常用的是 CORS(跨域资源共享)机制。CORS 机制通过在服务器端设置响应头来允许跨域访问,具体步骤如下: 1. 在 Spring Security 的配置中添加 cors() 方法,如下: ``` @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors() .and() //其他配置 .csrf().disable(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOrigin("*"); configuration.addAllowedHeader("*"); configuration.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } } ``` 2. 在 CorsConfigurationSource 中设置允许跨域访问的源、方法和头信息。以上代码中的 configuration.addAllowedOrigin("*") 表示允许所有来源跨域访问,configuration.addAllowedHeader("*") 表示允许所有头信息,configuration.addAllowedMethod("*") 表示允许所有 HTTP 方法。 以上就是 Spring Security 解决跨域请求的方法,希望对您有所帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的大雄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值