0

I'm trying to add an Authorization header to requests made using $http on the client side of my application.

I'm using nodejs to serve my client side app, and java with spring boot for my backend.

I've added the following filter to enable CORS:

public class CorsFilter extends GenericFilterBean {
private static final Logger logger = Logger.getLogger(CorsFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    logger.info("Enable cors filter");
    HttpServletResponse res = (HttpServletResponse) response;
    res.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
    res.addHeader("Access-Control-Allow-Credentials", "true");
    res.addHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS");
    res.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization");
    chain.doFilter(request, response);

   }
}

I'm setting an authorization header containing a token with the following line:

$http.defaults.headers.common.Authorization = 'Bearer ' + token;

yet angular seems to completely ignore this header, when checking the requests made in chrome I see:

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:he-IL,he;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, access-control-expose-headers, authorization
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:3000
Pragma:no-cache
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36

not trace if the authorization header.

I've added 'Authorization' to the Access-Control-Allow-Headers header in my response, the CORS seem to function properly, and I've set my CORS filter ass following:

     @Bean
 public FilterRegistrationBean corsFilter() {
     final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
     registrationBean.setFilter(new CorsFilter());
     registrationBean.addUrlPatterns("/*");
     registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);

     return registrationBean;
  }

So it should occur first and on all URL patterns.
So what am I missing?

1 Answer 1

1

The solution for the problem is in the comments, so I edited these in here:

The request you see in chrome is a CORS request for access. Method = OPTION. This is done by the browser not by angular. You CORSFilter should probably handle OPTION requests.

The problem was caused by a jwt filter that expected the authorization header, also on the OPTION request.

It was solved by adding a condition to only proceed with the jwt validation if the method is not OPTION.

Sign up to request clarification or add additional context in comments.

4 Comments

I think the request you see in chrome is a CORS request for access. Method = OPTION. This is done by the browser not by angular. You CORSFilter should probably handle OPTION requests. I'm not sure how to solve this, but try to google CORS with credentials - this should be a comment on the question - sorry
@popovitsj - tried your suggestion, unfortunately it didnt help.
@Michael - you are right, the method of the request I see in chrome is OPTION, I'll try to look up some more information, thanks.
@Michael - your lead helped me solve my problem, I had a jwt filter that expected the authorization header, and I didn't understand that the browser was sending options request before the actual request was sent. I've added a condtion to only proceed with the jwt validation if the method is not "options" and in works!. thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.