joker21
joker21

Reputation: 339

How to specify response headers to CORS?

I am building a backend REST API in spring and my friend is building a Angular JS front end app to call my API.I have a token header with key Authorization and a value which gives access to the service otherwise it refuses.From Postman and REST client I am able to receive the API but when tested he says he gets 401 Unauthorized Error on preflight.Below is my doFilterInternal method.

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers","Content-Type, Accept, X-Requested-With, Authorization");
}

But when he calls the API with the token in Angular JS he gets

So I followed this answer here and I added the property

spring.mvc.dispatch-options-request=true

in the application.properties.But stillt he error seems to be like

Response for preflight has invalid https status code 401

Any help is appreciated.

Upvotes: 4

Views: 11617

Answers (3)

David Pham
David Pham

Reputation: 1803

Here is the filter which avoid the preflight error

        @Override
        protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
            LOG.info("Adding CORS Headers ........................");        
            res.setHeader("Access-Control-Allow-Origin", "*");
            res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            res.setHeader("Access-Control-Max-Age", "3600");
            res.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
            res.addHeader("Access-Control-Expose-Headers", "xsrf-token");
            if ("OPTIONS".equals(req.getMethod())) {
             res.setStatus(HttpServletResponse.SC_OK);
            } else { 
             chain.doFilter(req, res);
            }        
        }

Found it from the post Cross Origin Request Blocked Spring MVC Restful Angularjs

Upvotes: 11

Doe Johnson
Doe Johnson

Reputation: 1414

Since you tagged your question with jwt, I almost feel obligated to suggest this excellent demo on spring boot and jwt.

The project includes some useful Security configuration.

Unfortunately it does not configure cors but here are two ways to quickly fix your problem:

The easiest way I know of is to annotate a RestController with @CrossOrigin("*")

The second option is to configure cors with spring security:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure (HttpSecurity http) throws Exception {
         http.cors();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource () {

        UrlBasedCorsConfigurationSource source;
        source = new UrlBasedCorsConfigurationSource();

        CorsConfiguration configuration = new CorsConfiguration();
        List<String> all = Collections.singletonList("*");
        configuration.setAllowedOrigins(all);
        configuration.setAllowedMethods(all);
        configuration.setAllowedHeaders(all);

        source.registerCorsConfiguration("/**", configuration);
        return source;

    }

}

Disclaimer

It's quite obvious that both approaches will allow everything. That's fine during development but a terrible idea when used in production code!

Upvotes: 1

Jorge L. Morla
Jorge L. Morla

Reputation: 630

this can help you, Spring have differents way to configure Cors headers https://spring.io/guides/gs/rest-service-cors/

Upvotes: 2

Related Questions