4

I am trying to secure my Web Application via JWT token, but when I try to make a request from my Angular app (localhost:4200) to my Spring Boot app (localhost: 8080) I get the following error:

enter image description here

From the message alone I can see that it is a CORS issue, the problem is that I've already enabled requests from different origin at my back-end, and here is the code for it:

UPDATE: I've added OPTIONS into allowedMethods(), but the error remains the same.

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

Here is the code from my Angular app as well :

    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())
    }
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Stefan Radonjic
  • 1,449
  • 4
  • 19
  • 38
  • You should add also `OPTION`. Should be like `.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTION")` – Tan Duong Apr 14 '18 at 13:43
  • You get a 403 when doing the options request. Can you show the response headers / body (if one) for that request. Is Options enabled at the webserver level? – David Apr 14 '18 at 15:27
  • Possible duplicate of [CORS issue - No 'Access-Control-Allow-Origin' header is present on the requested resource](https://stackoverflow.com/questions/42016126/cors-issue-no-access-control-allow-origin-header-is-present-on-the-requested) – dur Apr 15 '18 at 09:24

3 Answers3

3

Create a java class "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);
    }
  }
  }

Then call it to your 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);

}
Denny Danu
  • 61
  • 2
1

You have to allow the OPTIONS method too:

@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);
        }
    };
}}
Ratan
  • 603
  • 6
  • 19
  • Thank you for quick reply. Sadly this did not fix my issue. Error remains the same. – Stefan Radonjic Apr 14 '18 at 14:37
  • Does the OPTIONS response return the CORS headers now? Since you seem to get a 403 status as well there might be an additional issue with the security configuration. Can you provide more config regarding Spring Security? – Georg Wittberger Apr 15 '18 at 10:36
0

I've managed to fix the issue by adding jwt_token into configuration:

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

Thank you all for your help!

Stefan Radonjic
  • 1,449
  • 4
  • 19
  • 38