使用spring security的auth api调用的cors错误

Posted

技术标签:

【中文标题】使用spring security的auth api调用的cors错误【英文标题】:cros error for auth api calls using spring security 【发布时间】:2020-08-09 15:24:01 【问题描述】:

我已经为带有 spring 安全性的 spring boot 应用程序设置了如下的 cros。 带有 Spring Security 和 jwt 令牌的 Spring-boot 应用程序。

我正在使用其他域的 api,所以我在所有控制器上使用跨域。

所有不需要身份验证令牌(JWT)的 api 调用在以下配置下都可以正常工作。但是使用所需 jwt 令牌的 api 调用失败并出现以下错误。

我正在尝试添加过滤器,但它没有按预期工作。有人可以在这里帮助我吗?

谢谢。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    private final AuthenticationManagerBuilder authenticationManagerBuilder;

    private final DomainUserDetailsService userDetailsService;

    private final TokenProvider tokenProvider;

//    private final CorsFilter corsFilter;
    private final SecurityProblemSupport problemSupport;

    @Autowired
    public SecurityConfig(AuthenticationManagerBuilder authenticationManagerBuilder, DomainUserDetailsService userDetailsService, TokenProvider tokenProvider, SecurityProblemSupport problemSupport) 
        this.authenticationManagerBuilder = authenticationManagerBuilder;
        this.userDetailsService = userDetailsService;
        this.tokenProvider = tokenProvider;
//        this.corsFilter = corsFilter;
        this.problemSupport = problemSupport;
    

        @PostConstruct
    public void init() 
        try 
            authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
         catch (Exception e) 
            throw new BeanInitializationException("Security configuration failed", e);
        
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.cors().disable().csrf().ignoringAntMatchers("/api/**", "/reports/**", "/utils/**").and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
                .antMatchers("/", "/*.html", "/**/*.js", "/**/*.png", "/**/*.css", "/**/*.woff2", "/**/*.woff",
                        "/**/*.ico", "/**/*.ttf", "/**/*.jpg")
                .permitAll().antMatchers("/api/auth/**", "/api/util/**", "/api/feed/getJobs", // feed can be seen
                                                                                                // without auth
                        "/api/user/user-details/**", // user details can be seen without auth
                        "/v2/api-docs/**", "/actuators/**", "/api-docs/**", "/utils/**")
                .permitAll().anyRequest().authenticated().and().apply(securityConfigurerAdapter()).and()
                // handle an authorized attempts
                .exceptionHandling()
                .authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED));
    

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    

    @Bean
    public CorsFilter corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    

    private JWTConfigurer securityConfigurerAdapter() 
        return new JWTConfigurer(tokenProvider, userDetailsService);
    

不带 jwt 的 GET、POST、PUT、DELETE api 调用正常工作。

使用 JWT 的 API 调用无法正常工作并低于错误

Access to XMLHttpRequest at 'http://localhost:8082/api/feed/posted-by-me' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

谁能告诉我我做错了什么??

我在前端使用 Angular 9 来调用 api。

【问题讨论】:

删除configure(HttpSecurity http)中的cors().disable()并重试 @PatelRomil,试过但没有运气。还是一样的错误Access to XMLHttpRequest at 'http://localhost:8082/api/feed/posted-by-me' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. 您在其他类(例如控制器级别或 yml 或属性文件中)是否有任何与 CORS 相关的配置? @PatelRomil,我将@CrossOrigin(origins = "*", maxAge = 3600) 保留在控制器中。除此之外,我没有任何配置。 能否请您从控制器中删除@CrossOrigin 并重试 【参考方案1】:

问题是我在上述课程中使用的过滤器不起作用。所以我创建了如下所示的新过滤器类,然后它开始按执行方式工作。

package com.happyconnects.web.api.config;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter 

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException 

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, Authorization, Cache-control, remember-me");

        chain.doFilter(req, res);
    

    @Override
    public void init(FilterConfig filterConfig) 
    

    @Override
    public void destroy() 
    

【讨论】:

以上是关于使用spring security的auth api调用的cors错误的主要内容,如果未能解决你的问题,请参考以下文章

spring security 和auth2.0的区别

Spring Security 配置:Basic Auth + Spring Cloud Gateway

使用spring security的auth api调用的cors错误

使用Spring Security进行auth api调用时出现Cros错误

Auth0 + Grails 3 + Spring Security

手动设置spring security auth记住我