简体   繁体   中英

Spring Boot CORS configuration is not accepting authorization header

Angular2 app is sending a HTTP GET request with X-AUTH-TOKEN header value to the Spring Boot. Every time request.getHeader("X-AUTH-TOKEN") returns null .

Interestingly it works fine if I send the request from ARC client or any other rest client.

I have also spent a great amount of time making sure that Angular HTTP GET request is sending JWT token.

Angular code

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);
    }

Console Logs 在此输入图像描述

I resolved with :

//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");
            }
        };
    }
}

You can define this class and add in your boot spring class @ComponentScan(basePackageClasses= CorsConfig.class)

Or just use the above method inside the boot class.

Then should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM