Invalid CORS request; Origin=file://;Method=POST

2,262 views
Skip to first unread message

James REN

unread,
Nov 15, 2016, 11:01:56 AM11/15/16
to HAPI FHIR

Dear all,

I tried to connect the server using my cell phone but I got HTTP 403 forbidden and the server returned:

[INFO] Started Jetty Server
2016-11-15 10:45:01.878:INFO:/gim-fhir:qtp646445398-15: Invalid CORS request; Origin=file://;Method=POST

and the Cross Origin filter setting in WEB-INF/web.xml  is:

<filter>
    <filter-name>cross-origin</filter-name>
    <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    <init-param>
        <param-name>headers</param-name>
        <param-value>Origin=file://</param-value>
    </init-param>
    <init-param>
        <param-name>allowedOrigins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>allowedMethods</param-name>
        <param-value>GET,POST,HEAD</param-value>
    </init-param>
    <init-param>
        <param-name>allowedHeaders</param-name>
        <param-value>X-Requested-With,Content-Type,Accept,Origin</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>cross-origin</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

I was wondering what part went wrong. Please advise. Thanks a lot.

Sincerely,
Ren

James Agnew

unread,
Nov 15, 2016, 11:09:34 AM11/15/16
to James REN, HAPI FHIR

Hmmm.. Is this when connecting to our public server, or your own? If the latter, what does your cors config look like?

sent from my phone.


--
You received this message because you are subscribed to the Google Groups "HAPI FHIR" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+unsubscribe@googlegroups.com.
To post to this group, send email to hapi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hapi-fhir/9a14879f-b83a-4dfc-9372-2a875337d71f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

James REN

unread,
Nov 15, 2016, 12:07:19 PM11/15/16
to HAPI FHIR, rqg...@gmail.com
Hi James,

Thank you for your quick reply. I just tried to connect http://fhirtest.uhn.ca/baseDstu2 and got the same 403 forbidden. I have no clue what went wrong. Please advise. Thank you.

Sincerely,
Ren
To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+...@googlegroups.com.

James REN

unread,
Nov 15, 2016, 12:13:23 PM11/15/16
to HAPI FHIR
Here is the detailed request:

Request URL:http://fhirtest.uhn.ca/baseDstu2/AllergyIntolerance
Request Method:POST
Status Code:403 Forbidden
Remote Address:199.212.7.152:80

Response Headers
view source
Connection:close
Content-Length:0
Content-Type:text/plain; charset=UTF-8
Date:Tue, 15 Nov 2016 16:58:37 GMT
Server:Apache-Coyote/1.1

Request Headers
Accept:application/json+fhir, */*; q=0.01
Accept-Encoding:gzip, deflate
Accept-Language:en-US
Connection:keep-alive
Content-Length:595
Content-Type:application/json+fhir; charset=UTF-8
Host:fhirtest.uhn.ca
Origin:file://
User-Agent:Mozilla/5.0 (Linux; Android 6.0.1; SM-G935T Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/54.0.2840.85 Mobile Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id:431ed192-3bef-4559-99e6-f1aa3996f6a8
X-Requested-With:edu.temple.fhir

Request Payload
{"resourceType":"AllergyIntolerance","onset":"2016-11-11","type":"allergy","category":"food","reaction":{"manifestation":{"coding":{"system":"http://fhirtest.uhn.ca/baseDstu2","code":"abdominal pain and/or pain","display":"abdominal pain and/or pain"},"text":"abdominal pain and/or pain"}},"extension":[{"url":"http://fhirtest.uhn.ca/baseDstu2","valueCoding":{"system":"http://fhirtest.uhn.ca/baseDstu2","code":"Name","display":"Test Allergy"}},{"url":"http://fhirtest.uhn.ca/baseDstu2","valueCoding":{"system":"http://fhirtest.uhn.ca/baseDstu2","code":"Treatment","display":"Test Treatment"}}]}

James Agnew

unread,
Nov 15, 2016, 12:14:41 PM11/15/16
to James REN, HAPI FHIR
Hi James,

I read your original message on my phone and obviously hadn't read it correctly. Obviously you were on your own server, you even supplied the configuration you were using. :)

I'm not totally clear what you're doing though. Given the "file://" URL, are you trying to access the FHIR server from an HTML file you have stored locally on your phone? If so, does it work when you save the same file locally on your computer and access it from a browser there?

Cheers,
James





To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+unsubscribe@googlegroups.com.

To post to this group, send email to hapi...@googlegroups.com.

James REN

unread,
Nov 15, 2016, 1:25:17 PM11/15/16
to HAPI FHIR, rqg...@gmail.com
Hi James,

You are right I was trying to connect my local server; however, I did try to connect the public server. Anyway, I think I found what went wrong.

The org.ebaysf.web.cors.CORSFilter tries to validate the URI in Origin header and considers "file://" as an invalid URI and returns HTTP 403 back.
/**
* Checks if a given origin is valid or not. Criteria:
* <ul>
* <li>If an encoded character is present in origin, it's not valid.</li>
* <li>Origin should be a valid {@link URI}</li>
* </ul>
*
* @param origin
* @see <a href="http://tools.ietf.org/html/rfc952">RFC952</a>
* @return
*/
public static boolean isValidOrigin(String origin) {
// Checks for encoded characters. Helps prevent CRLF injection.
if (origin.contains("%")) {
return false;
}
URI originURI;
try {
originURI = new URI(origin);
} catch (URISyntaxException e) {
return false;
}
// If scheme for URI is null, return false. Return true otherwise.
return originURI.getScheme() != null;
}

James Agnew

unread,
Nov 15, 2016, 1:41:43 PM11/15/16
to James REN, HAPI FHIR
Hmm yup, I'd say you're correct.

I guess I could just patch it to accept "file://" too if that's explicitly configured (which is probably only something you'd ever want to do in a non-production situation).

Or would it make sense to just switch to a different CORS provider... This ebay one was apparently merged into Tomcat and isn't being maintained as a standalone product any more. All in all, I'm surprised by how lacking the various CORS filters in Java seem to be. Surely people must have tripped over these issues before! Maybe it would be easier to just maintain a fork of the eBay one permanently in HAPI. Sigh.

Cheers,
James

To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+unsubscribe@googlegroups.com.

To post to this group, send email to hapi...@googlegroups.com.

James REN

unread,
Nov 15, 2016, 1:59:14 PM11/15/16
to HAPI FHIR, rqg...@gmail.com
Tomcat 8.0.x did correct it by adding 'if (origin.startsWith("file://")) { return True}'. Is there a way to switch the CORS filters to Tomcat CORS filters please? Thank you.


/**
     * Checks if a given origin is valid or not. Criteria:
     * <ul>
     * <li>If an encoded character is present in origin, it's not valid.</li>
     * <li>If origin is "null", it's valid.</li>
     * <li>Origin should be a valid {@link URI}</li>
     * </ul>
     *
     * @param origin
     * @see <a href="http://tools.ietf.org/html/rfc952">RFC952</a>
     */
    protected static boolean isValidOrigin(String origin) {
        // Checks for encoded characters. Helps prevent CRLF injection.
        if (origin.contains("%")) {
            return false;
        }

        // "null" is a valid origin
        if ("null".equals(origin)) {
            return true;
        }

        // RFC6454, section 4. "If uri-scheme is file, the implementation MAY
        // return an implementation-defined value.". No limits are placed on
        // that value so treat all file URIs as valid origins.
        if (origin.startsWith("file://")) {
            return true;
        }

        URI originURI;
        try {
            originURI = new URI(origin);
        } catch (URISyntaxException e) {
            return false;
        }
        // If scheme for URI is null, return false. Return true otherwise.
        return originURI.getScheme() != null;

    }

James REN

unread,
Nov 15, 2016, 3:37:32 PM11/15/16
to HAPI FHIR, rqg...@gmail.com
 I think I have successfully switched to the Tomcat CORS filter:

Remove org.ebaysf.web and add the following dependency:
<dependency>
   <groupId>org.apache.tomcat</groupId>
   <artifactId>tomcat-catalina</artifactId>
   <version>8.0.38</version>
</dependency> 

then add Tomcat CORS filter in web.xml:
<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>false</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>

James Agnew

unread,
Nov 15, 2016, 4:58:42 PM11/15/16
to James REN, HAPI FHIR
I tried this and it works for me too. Cool!

It brings another annoying issue though, if I include the dependency in my project, it brings in TONS of chained dependencies.

What platform are you deploying to? Do you end up with tons of tomcat jars in your war file? 

I'm assuming you can just do this without the maven dependency if you're deploying to Tomcat directly...

Cheers,
James


To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+unsubscribe@googlegroups.com.

To post to this group, send email to hapi...@googlegroups.com.

James REN

unread,
Nov 16, 2016, 9:43:59 AM11/16/16
to HAPI FHIR, rqg...@gmail.com

You were right. I have removed the maven dependency and deployed to Tomcat directly without any issue. Thank you for your suggestion. 

Best,
Ren

James Agnew

unread,
Nov 22, 2016, 6:42:35 AM11/22/16
to James REN, HAPI FHIR
So as one more follow up to this..

I spent some time switching all of our examples to using the Tomcat filter, only to run into weird problems with the JPA server. It seems like Spring detects that it's running under Tomcat when it find the Tomcat JARs on the classpath and gets in a really weird state if it's actually running under Jetty or another container.

I've come to the conclusion that it's probably better for the docs to show how to do this with the Tomcat plugin, but also with Spring (since Spring should run under any container without conflict) and also make it clear in the docs that you can even do this without Spring under most containers since they typically ship with some equivalent to CorsFilter.

To that end I've added a new HAPI interceptor called CorsInterceptor which uses Spring's implementation and tries to add sensible default configuration for FHIR. That interceptor will be in the next release of HAPI.

Cheers,
James


To unsubscribe from this group and stop receiving emails from it, send an email to hapi-fhir+unsubscribe@googlegroups.com.

To post to this group, send email to hapi...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages