如何在 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()
    

    

我还有另外两个过滤器,分别是 AuthenticationAuthorisation 。但是当本地系统中的前端应用程序尝试访问 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:3000org.springframework.web.cors.CorsConfiguration#checkOrigin 中发生了字符串比较,在您的情况下将失败。

【讨论】:

我也改成了0.0.0.0:3000,但是失败了

以上是关于如何在 Spring Boot 中使用 Spring Security 启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

如何结合 Spring Boot HornetQAutoConfiguration 和 CachingConnectionFactory?

如何在 Spring Boot pom.xml 中临时禁用依赖项 [关闭]

构建一个简单的Spring Boot项目

找不到带有spring boot的html页面

Spring Boot 获得帮助

使用带有spring数据缓存的redis时如何启用分布式/集群缓存