Cors error when an exception is thrown in the server [JBoss/Spring security]

Create issue
Issue #13 new
Stijn Cremers created an issue

It got a cors exception in the client when an exception is thrown in the server.

I get the following error in the client:

XMLHttpRequest cannot load https://xxxservice-cremersstijn.rhcloud.com/xxx. Origin https://xxx-cremersstijn.rhcloud.com is not allowed by Access-Control-Allow-Origin.

A runtime exception is thrown in the server.

When there is no exception, everything works fine. I expect a 500 when there is an exception.

Comments (10)

  1. Vladimir Dzhuvinov

    Hi Stijn,

    To clarify the issue, you wish the CORSFilter to supply the correct CORS headers despite the underlying servlet throwing a RuntimeException?

    Which server are you using?

  2. Stijn Cremers reporter

    Hi,

    You are correct, it looks like the headers are not set when an exception is thrown.

    I am running on jboss 7.1

    Regards

  3. Vladimir Dzhuvinov

    Could you pass me the stack trace that you're getting in JBoss?

    I looked at the filter code and it should be applying the necessary CORS headers prior to invoking the next filter / end resource.

    // Simple / actual CORS request
    handler.handleActualRequest(request, response);
    chain.doFilter(request, response);
    
  4. Vladimir Dzhuvinov

    Thanks, that will help. It could be that the JBoss server is discarding the response or bits of it when an exception is encountered.

  5. Collin Peters

    We had this same problem just now. For us, it was that Spring Security was active and it seems that when a bad OAuth token came in, Spring Sec was immediately rejecting it and the CORSFilter never even saw it. Successful Spring Sec authentications worked as expected

    Our solution to this was to inject CORSFilter into the Spring Sec filter chain, and not do it at the web app level

    In our Spring WebApplicationInitializer (i.e. Java config over xml config)

    FilterRegistration.Dynamic corsFilter = servletContext.addFilter("apiCorsFilter", DelegatingFilterProxy.class);
    corsFilter.setInitParameter("cors.supportedMethods", "GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS");
    corsFilter.setInitParameter("cors.maxAge", "86400"); // good for a day
    corsFilter.setInitParameter("targetFilterLifecycle", "true");
    

    In my Spring Sec application context (still in XML unfortunately)

    <security:custom-filter ref="apiCorsFilter" before="HEADERS_FILTER" />
    

    Finally, the filter had to be created as a bean in the Spring Java config

    @Bean
    public CORSFilter apiCorsFilter()
    {
        return new CORSFilter();
    }
    
  6. Vladimir Dzhuvinov

    @collin_peters Thanks for sharing this, I'll point people to your workaround if this issue comes up again.

  7. Collin Peters

    Keep in mind that in our case the exception was coming from Spring Security... but I think the core issue is when an exception is thrown in a filter that is before the cors filter

  8. Aarij Siddiqui

    Hi Guys! I am facing a similar issue. When there is normal execution then all the headers are set perfectly but when there is a runtime exception then headers are not set. I am using Jersey (Java) with tomcat 7.0.52. I am adding all the filters in web.xml. Here is my Web.xml...

    <web-app id="WebApp_ID" version="2.4"
        xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        <display-name>Restful Web Application</display-name>
    
        <servlet>
            <servlet-name>jersey-serlvet</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>com.ClViTra.rest</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--  <listener>
            <listener-class>com.ClViTra.rest.Config</listener-class>
        </listener>-->
        <servlet-mapping>
            <servlet-name>jersey-serlvet</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>
    
        <filter>
      <filter-name>CorsFilter</filter-name>
      <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
      <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
      </init-param>
      <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
      </init-param>
      <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
      </init-param>
      <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
      </init-param>
      <init-param>
        <param-name>cors.support.credentials</param-name>
        <param-value>true</param-value>
      </init-param>
      <init-param>
        <param-name>cors.preflight.maxage</param-name>
        <param-value>10</param-value>
      </init-param>
    </filter>
    <filter-mapping>
      <filter-name>CorsFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    </web-app>
    
  9. Log in to comment