【问题标题】:CORS error and 403 response with JWT tokenCORS 错误和带有 JWT 令牌的 403 响应
【发布时间】:2018-09-24 16:51:13
【问题描述】:

我正在尝试通过 JWT 令牌保护我的 Web 应用程序,但是当我尝试从我的 Angular 应用程序 (localhost:4200) 向我的 Spring Boot 应用程序 (localhost:8080) 发出请求时,我收到以下错误:

仅从消息中我可以看出这是一个CORS 问题,问题是我已经在后端启用了来自不同来源的请求,这里是它的代码:

更新:我已将 OPTIONS 添加到 allowedMethods(),但错误仍然相同。

@Configuration
public class AppConfiguration {

@Autowired
private Environment env;

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:4200")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD","OPTIONS")
                    .allowedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
                    .exposedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
                    .maxAge(3600);
        }
    };
}

这也是我的 Angular 应用程序的代码:

    baseUrl = 'http://localhost:8080/api/';

    constructor(private http: Http) { }


    private postaviHeadere() : RequestOptions{
        let headers = new Headers();

        console.log("***************** Set Headers *****************");
        console.log('Getting token from local storage:');
        console.log(localStorage.getItem('jwt_token'))
        console.log("***********************************************");

        headers.append('JWT_TOKEN', localStorage.getItem('JWT_TOKEN'));
        let options = new RequestOptions({headers : headers});
        console.log(options);
        return options;
    }

    getUserByToken(): any {
        return this.http.get(this.baseUrl + 'user/secured', this.postaviHeadere())
    }

【问题讨论】:

标签: java spring angular spring-boot spring-security


【解决方案1】:

创建一个java类“CorsFilterConfig”:

@Component
public class CorsFilterConfig extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
    response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
    if ("OPTIONS".equals(request.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
    } else {
        filterChain.doFilter(request, response);
    }
  }
  }

然后将其调用到您的 WebSecurityConfig :

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity

            .csrf().disable()
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()

            // don't create session
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

            .authorizeRequests()

            // Un-secure H2 Database
            .antMatchers("/h2-console/**/**").permitAll()
            //whitelist swagger configuration
            .antMatchers(
                    "/swagger-resources/**",
                    "/api/swagger-resources/**",
                    "/api/**",
                    "/null/**",
                    "/v2/api-docs/**",
                    "/webjars/springfox-swagger-ui/**",
                    "/"
            ).permitAll()

            .anyRequest().authenticated();
    httpSecurity.cors();

    // Custom JWT based security filter
    JwtAuthorizationTokenFilter authenticationTokenFilter =
            new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);
    httpSecurity.addFilterBefore(new CorsFilterConfig(), ChannelProcessingFilter.class);
    httpSecurity
            .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

}

【讨论】:

    【解决方案2】:

    您也必须允许 OPTIONS 方法:

    @Configuration
    public class AppConfiguration {
    
    @Autowired
    private Environment env;
    
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:4200")
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
                        .allowedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
                        .exposedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
                        .maxAge(3600);
            }
        };
    }}
    

    【讨论】:

    • 感谢您的快速回复。可悲的是,这并没有解决我的问题。错误保持不变。
    • OPTIONS 响应现在是否返回 CORS 标头?由于您似乎也获得了 403 状态,因此安全配置可能存在其他问题。你能提供更多关于 Spring Security 的配置吗?
    【解决方案3】:

    我已通过将 jwt_token 添加到配置中来解决此问题:

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:4200")
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD","OPTIONS")
                        .allowedHeaders("Content-Type", "Date", "Total-Count", "loginInfo","jwt_token")
                        .exposedHeaders("Content-Type", "Date", "Total-Count", "loginInfo", "jwt_token")
                        .maxAge(3600);
            }
        };
    }
    

    感谢大家的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      • 2018-03-16
      • 2017-03-11
      • 2016-05-08
      • 2018-09-21
      • 2014-08-04
      • 1970-01-01
      相关资源
      最近更新 更多