如何在 Spring Boot 中使用 Spring Security 启用 CORS
Posted
技术标签:
【中文标题】如何在 Spring Boot 中使用 Spring Security 启用 CORS【英文标题】:How to enable CORS in spring boot with spring security 【发布时间】:2020-05-29 14:36:34 【问题描述】:我已经实现了WebMvcConfigurerAdapter
并添加了CorsFilter
并配置了标头。
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter
@Override
public void addCorsMappings( CorsRegistry registry )
registry.addMapping("/**").allowedOrigins("http://localhost:3000").allowCredentials(false);
@Slf4j
public class CustomCorsFilter implements javax.servlet.Filter
@Override
public void init( FilterConfig filterConfig ) throws ServletException
@Override
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
throws IOException, ServletException
if( req instanceof HttpServletRequest && res instanceof HttpServletResponse )
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// Access-Control-Allow-Origin
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
response.setHeader("Vary", "Origin");
// Access-Control-Max-Age
response.setHeader("Access-Control-Max-Age", "3600");
// Access-Control-Allow-Credentials
response.setHeader("Access-Control-Allow-Credentials", "false");
// Access-Control-Allow-Methods
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
// Access-Control-Allow-Headers
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, " + "X-CSRF-TOKEN");
log.info("********************** Configured ****************************************");
chain.doFilter(req, res);
@Override
public void destroy()
我还有另外两个过滤器,分别是 Authentication
和 Authorisation
。但是当本地系统中的前端应用程序尝试访问 API 时,我收到以下错误,
Access to XMLHttpRequest at 'http://3.12.228.75:8090/rest/noauth/otp/sandesha@test.com' from origin 'http://0.0.0.0:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
如何解决这个问题?我正在使用spring-boot 1.5.10
我的WebSecurityConfig
班级是,
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private CustomLogoutHandler logoutHandler;
@Autowired
private HttpLogoutSuccessHandler logoutSuccessHandler;
@Autowired
private UserModelRepository userModelRepository;
@Autowired
private RefreshTokenService refreshTokenService;
@Autowired
private AuthTokenModelRepository authTokenModelRepository;
@Autowired
private UserActivitiesRepository userActivitiesRepository;
@Autowired
private UserSubscriptionRepository userSubscriptionRepository;
@Autowired
private HandlerExceptionResolver handlerExceptionResolver;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private UserService userService;
@Override
protected void configure( HttpSecurity http ) throws Exception
http.csrf().disable()
.authorizeRequests()
.antMatchers("/rest/noauth/**").permitAll()
.antMatchers("/rest/login").permitAll()
.antMatchers("/rest/logout").permitAll()
.antMatchers("/static/**").permitAll()
.antMatchers("/ws/**").permitAll()
.antMatchers("/rest/razorpay/hook").permitAll()
.antMatchers("/rest/user/cc").permitAll()
.antMatchers("/v2/api-docs/**", "/configuration/ui/**", "/swagger-resources/**",
"/configuration/security/**", "/swagger-ui.html/**", "/webjars/**")
.permitAll()
.antMatchers("/rest/file/invoiceFileDownload", "/rest/file/fileDownload", "/rest/file/fileDownload/**")
.permitAll()
.anyRequest().authenticated()
.and()
.logout().addLogoutHandler(logoutHandler).logoutSuccessHandler(logoutSuccessHandler)
.logoutUrl("/rest/logout")
.and()
.addFilterBefore(
new JWTAuthenticationFilter("/rest/login", tokenService(), refreshTokenService,
authTokenModelRepository, userService, userActivitiesRepository,
handlerExceptionResolver, bCryptPasswordEncoder, redisTemplate),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthorizationFilter(authenticationManager(), authTokenModelRepository,
userSubscriptionRepository, handlerExceptionResolver, redisTemplate),
UsernamePasswordAuthenticationFilter.class);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
@Override
public void configure( AuthenticationManagerBuilder auth ) throws Exception
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
@Bean
public TokenService tokenService()
return new TokenService(userModelRepository);
【问题讨论】:
【参考方案1】:您必须保持配置的值与您实际请求的值相同。
在这里,您从0.0.0.0:3000
请求并将标头设置为localhost:3000
。 org.springframework.web.cors.CorsConfiguration#checkOrigin
中发生了字符串比较,在您的情况下将失败。
【讨论】:
我也改成了0.0.0.0:3000
,但是失败了以上是关于如何在 Spring Boot 中使用 Spring Security 启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章
如何结合 Spring Boot HornetQAutoConfiguration 和 CachingConnectionFactory?