【问题标题】:Spring Boot CORS configuration is not accepting authorization headerSpring Boot CORS 配置不接受授权标头
【发布时间】:2017-06-21 07:17:54
【问题描述】:

Angular2 应用正在向 Spring Boot 发送带有 X-AUTH-TOKEN 标头值的 HTTP GET 请求。每次request.getHeader("X-AUTH-TOKEN") 返回null

有趣的是,如果我从 ARC 客户端或任何其他 rest 客户端发送请求,它工作正常。

我还花费了大量时间确保 Angular HTTP GET 请求正在发送 JWT 令牌。

角度代码

getCandidatesByUserId(userId: number): Observable<Candidate[]> {
    let headers = new Headers({ 'X-AUTH-TOKEN': 'let-jwt-test-token-in' });
    console.log('Token is '+ headers.get('X-AUTH-TOKEN'));
    return this.http.get(this.url+userId+'/candidates', {
      headers: headers
    })
      .map((response: Response) => <Candidate[]> response.json())
      .do(data => console.log('All: '+ JSON.stringify(data)))
      .catch(this.handleError);
  }

JWTFilter

@Override
    public void doFilter(ServletRequest request, ServletResponse res, FilterChain filterChain)
            throws IOException, ServletException {

        try {
            final HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "X-AUTH-TOKEN, Content-Type, Accept");
            response.setHeader("Access-Control-Expose-Headers", "X-AUTH-TOKEN, Content-Type");

            HttpServletRequest httpRequest = (HttpServletRequest) request;
            Map<String, String> blackListedTokenMap =
                    (Map<String, String>) ((HttpServletRequest) request)
                            .getSession()
                            .getServletContext()
                            .getAttribute(WebAppListener.TOKEN_BLACK_LIST_MAP);
            String authToken = authenticationService.getToken(httpRequest);
            if (authToken != null && blackListedTokenMap.containsValue(authToken)) {
                throw new RuntimeException("token invalidated");
            }
            UserAuthentication authentication = (UserAuthentication) authenticationService.getAuthentication(httpRequest);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            filterChain.doFilter(request, response);
            SecurityContextHolder.getContext().setAuthentication(null);
        } catch (RuntimeException e) {
            ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }

SpringSecurityConfig

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

        http
            .csrf()
                .csrfTokenRepository(new HttpSessionCsrfTokenRepository())
                .requireCsrfProtectionMatcher(new AntPathRequestMatcher("*/*"));
        http
            .exceptionHandling()
                .and()
            .anonymous()
                .and()
            .servletApi()
                .and()
            .headers()
                .cacheControl();

        http
                //.addFilterBefore(corsFilter, ChannelProcessingFilter.class)
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()// allow for static resources
                .antMatchers("/signup").permitAll()
                .antMatchers("/forgot").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/reset").permitAll()
                .antMatchers("/health").permitAll()
                .antMatchers("/hello").permitAll()
                .antMatchers("/").permitAll()
                .antMatchers("/reset_pw").permitAll()
                .anyRequest().authenticated()
                .and()
            .addFilterAfter(new JJWTFilter(tokenAuthenticationService),
                        UsernamePasswordAuthenticationFilter.class);
    }

控制台日志

【问题讨论】:

  • 你用的是spring boot吗?我最近有一个类似的问题。一个应用程序在过滤器上使用 Authorization 标头而崩溃。它是空的。确定 @EnableWebMvc 注释搞砸了。
  • @LucasHolt 是的。我在后端使用SpringBoot,但在任何地方都没有使用@EnableWebMvc
  • 嗨,有这方面的消息吗?我有同样的问题。我可以通过邮递员拨打电话,但不能通过我的 Angular 应用程序拨打电话。

标签: spring angular spring-boot spring-security


【解决方案1】:

我解决了:

//Define class with this annotation

@Configuration

public class CorsConfig {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        source.registerCorsConfiguration("/**", config);
        // return new CorsFilter(source);
        final FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }

    @Bean
    public WebMvcConfigurer mvcConfigurer() {
        return new WebMvcConfigurerAdapter() {
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "PUT", "POST", "GET", "OPTIONS");
            }
        };
    }
}

你可以定义这个类并在你的启动弹簧类中添加@ComponentScan(basePackageClasses= CorsConfig.class)

或者只是在引导类中使用上述方法。

那么应该可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-25
    • 2018-06-03
    • 2021-06-20
    • 2016-06-25
    • 2020-01-21
    • 2019-03-09
    • 2018-12-31
    • 2018-01-28
    相关资源
    最近更新 更多