lambad
lambad

Reputation: 1066

Cross Origin Resource Sharing not working when used with Servlet Filter and FilterRegistrationBean

Summary: For a cross-origin request, response with valid JSON is being sent. (i.e. empty response is not sent.)

I have a filterRegistrationBean as shown Below:

@Bean
public FilterRegistrationBean corsFilterRegistration() {
    FilterRegistrationBean filterRegistrationBean =
            new FilterRegistrationBean(corsFilter());
    filterRegistrationBean.setUrlPatterns(Collections.singleton("/getToken"));
    return filterRegistrationBean;
}

@Bean
public CORSFilter corsFilter() {
    return new CORSFilter();
}

I have a CORSFilter class as shown below:

@Component
public class CORSFilter implements Filter {
    @Autowired
    UserDao userDao;

    @Autowired
    UserController userController;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest requestToUse = (HttpServletRequest) request;
        HttpServletResponse responseToUse = (HttpServletResponse) response;
        String origin = requestToUse.getHeader("Origin");
        String username = requestToUse.getParameter("username");


        if (requestToUse.getMethod().equalsIgnoreCase("GET") && Util.falseIfAnyStringIsNull(username, origin)) {
            User user = userDao.findByUsername(username);
            if (!ObjectUtils.isEmpty(user)) {
                System.out.println("user.getDomainName()==" + user.getDomainName());
                if (origin.equalsIgnoreCase(user.getDomainName())) {
                    logger.info("Access granted");
                    responseToUse.addHeader("Access-Control-Allow-Origin", origin);
                    responseToUse.addHeader("Access-Control-Allow-Methods", "GET");
                    responseToUse.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                    chain.doFilter(requestToUse, responseToUse);
                } else {
                    responseToUse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Origin.");
                }

            } else {
                responseToUse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Username");
            }

        } else {
            responseToUse.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Credential");
        }
    }


    @Override
    public void destroy() {

    }
}

If a request is made for /getToken then CORSFilter comes into play and validate user and origin.

This is all fine but the problem is when i send a get request to /getToken from an invalid origin then in the browser console, I get a correct message, "No 'Access-Control-Allow-Origin' header is present on the requested resource..." but if i go to network tab then i can see a JSON reponse which has valid token in it.

If i remove the above CORSFilter and filterRegistrationBean then i don't see any response so i am assuming that there is something wrong with the above filter and registrationBean.

Upvotes: 0

Views: 360

Answers (1)

Brian Clozel
Brian Clozel

Reputation: 59191

Spring Framework is providing a org.springframework.web.filter.CorsFilter implementation and various features like @CrossOrigin for that purpose (see the reference documentation).

Rolling your own filter implementation is not a good idea; on the top of my head, your implementation is not handling preflight requests, which might be (one of) the issue(s) you're facing right now.

Upvotes: 2

Related Questions