SpringBoot+Spring Security无法实现跨域的解决方案

网友投稿 947 2022-12-26

SpringBoot+Spring Security无法实现跨域的解决方案

SpringBoot+Spring Security无法实现跨域的解决方案

SpringBoot+Spring Security无法实现跨域

未使用Security时跨域:

import org.slf4j.Logger;

import org.slf4j.LoggTgsZXaUDerFactory;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.autoconfigure.AutoConfigureBefore;

import org.springframework.context.annotation.Configuration;

import org.springframework.format.FormatterRegistry;

import org.springframework.web.servlethttp://.config.annotation.*;

@Configuration

@AutoConfigureBefore(SecurityConfig.class)

public class MyMvcConfigurer implements WebMvcConfigurer {

public void addCorsMappings(CorsRegistry registry){

LOGGER.info("跨域已设置");

registry.addMapping("/**")

.allTgsZXaUDowedOrigins("*")

.allowedMethods("*")

.allowedHeaders("*")

.allowCredentials(true)

.maxAge(3600);

}

}

整合Security时发现只用上述方法前后端分离时仍存在跨域问题,

解决方法如下:

@Configuration

@AutoConfigureBefore(Swagger2Configuration.class)

@EnableWebSecurity

@EnableGlobalMethodSecurity(prePostEnabled = true)

@Order(-1)

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override

protected void configure(HttpSecurity http) throws Exception {

http.formLogin()

.loginProcessingUrl("/user/login")

.loginPage("/singIn.html")

.successHandler(moyuAuthenticationSuccessHandler)

.failureHandler(moyuAuthenticationFailureHandler)

.and()

.apply(moyuSocialSecurityConfig)

.and()

.rememberMe()

.tokenRepository(persistentTokenRepository())

.tokenValiditySeconds(3600*24*7)

.userDetailsService(userDetailsService)

.and()

.authorizeRequests()

.antMatchers("/user/login","/loginhttp://","/singIn.html","**","/**").permitAll()

.anyRequest()

.authenticated()

.and()

.cors()

.and()

.csrf().disable();

}

}

重点加入代码

.and()

.cors()//新加入

.and()

.csrf().disable();

引用Spring Security 项目的跨域处理

最近项目采用了前后端分离的框架,前端和后台接口没有部署到一个站点,出现了跨域问题,什么是跨域,这里就不再赘述,直接说解决办法。

Spring 解决跨域的方式有很多,个人采用了Crosfilter的方式

具体代码如下:

@Bean

public CorsFilter corsFilter() {

final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();

final CorsConfiguration corsConfiguration = new CorsConfiguration();

corsConfiguration.setAllowCredentials(true);

corsConfiguration.addAllowedOrigin("*");

corsConfiguration.addAllowedHeader("*");

corsConfiguration.addAllowedMethod("*");

urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

return new CorsFilter(urlBasedCorsConfigurationSource);

}

配置完成后,测试调用,报错401,依然不行。网上查资料得知,跨域请求会进行两次。具体流程见下图:

每次跨域请求,真正请求到达后端之前,浏览器都会先发起一个preflight request,请求方式为OPTIONS 询问服务端是否接受该跨域请求,具体参数如下图:

但是该请求不能携带cookie和自己定义的header。

由于项目中引入了Spring security ,而我使用的token传递方式是在header中使用authorization 字段,这样依赖Spring Security拦截到 preflight request 发现它没有携带token,就会报错401,没有授权。

解决这个问题很简单,可以使用以下配置

让Spring security 不校验preflight request 。

@Override

public void configure(HttpSecurity http) throws Exception {

ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry

= http.authorizeRequests();

registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();//让Spring security放行所有preflight request

}

再试就搞定了,但是后端直接配置支持跨域会导致两次请求。还使用另一种方式,使用Nginx 转发一下请求也可以。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信小程序在电脑打开(微信小程序在电脑打开如何定位)
下一篇:flutter技术限制(flutterer)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~