[
https://issues.apache.org/jira/browse/SHINDIG-1927?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mike Pawlowski updated SHINDIG-1927:
------------------------------------
Attachment: JsonRpcServlet.java.patch
> JSON RPC servlet does not support CORS properly
> -----------------------------------------------
>
> Key: SHINDIG-1927
> URL: https://issues.apache.org/jira/browse/SHINDIG-1927
> Project: Shindig
> Issue Type: Bug
> Components: Java
> Affects Versions: 2.5.0
> Environment: * Jetty 9.0.3.v20130506
> * Apache Tomcat 7.0.42 (64-bit)
> Reporter: Mike Pawlowski
> Priority: Minor
> Attachments: JsonRpcServlet.java.patch
>
>
> ----------------------------------------------------------------------------------------
> Problem
> ----------------------------------------------------------------------------------------
> * Like other customers, we have the following requirement: Shindig running on
> different domain than container REVISITED
> => http://markmail.org/message/qqfnyjg6dfunfw3h
> * JSON RPC servlet does not support CORS properly.
> => org.apache.shindig.protocol.JsonRpcServlet
> => Causes cross-domain XHRs to get gadget metadata to fail
> - Servlet does not handle OPTIONS preflight requests, so CORS
> requests automatically fail
> - http://www.html5rocks.com/static/images/cors_server_flowchart.png
>
> * However, the RPC servlet does specify the "Access-Control-Allow-Origin"
> header
> => This interferes with Jetty / Tomcat CORS servlet filters and causes the
> actual POST request to fail
> => Cause: "If the response includes zero or more than oneĀ
> Access-Control-Allow-OriginĀ header values, return fail and terminate this
> algorithm."
> - http://www.w3.org/TR/cors/#resource-sharing-check
> - The servlet filter is already providing a value for the
> "Access-Control-Allow-Origin" header downstream
>
> ----------------------------------------------------------------------------------------
> Patch
> ----------------------------------------------------------------------------------------
> Since, the CORS support is incomplete and does not work out-of-the-box, it is
> probably safer to just remove the CORS specific header setting in the RPC
> servlet altogether
> i.e. HttpUtil.setCORSheader(servletResponse,
> containerConfig.<String>getList(token.getContainer(),
> "gadgets.parentOrigins"));
> Will attach patch.
>
> ----------------------------------------------------------------------------------------
> Background Information
> ----------------------------------------------------------------------------------------
> * Shindig does not have out-of-the-box (OOTB) support for OpenSocial gadget
> containers hosted from one domain and the OpenSocial gadget renderer hosted
> from another domain
> => e.g.
> - Examples application (OS gadget container):
> http://localhost:9081/examples/gadgets
> - Shindig application (OS gadget renderer):
> http://localhost:9082/rpc, http://localhost:9082/gadgets/ifr, etc.
> => Deploying Shindig as a separate application in the Jazz Platform
> ecosystem is advantageous
> - Prevents the requirement for each application that hosts
> OpenSocial gadgets to serve it's own local copy of Shindig
> - Facilitates the sandboxing / compartmentalization / segregation of
> Shindig binaries from Jazz Platform related binaries
> * Only the request to get gadget metadata needs to be executed via a
> cross-domain XHR
> => Executed by common container API (osapi.container) outside of the
> yet-to-be constructed gadget iframe before making a request to render the
> gadget iframe (needs gadget metadata to render the gadget)
>
> * Possible solutions to fix the cross-domain XHR from the OS gadget container
> to OS gadget renderer to get the gadget metadata
> => (1) Use a transparent proxy on the gadget container server to proxy the
> metadata request to Shindig
> - Complicates server configuration & deployment
> - Causes support issues for customers with custom server setups
> (e.g. proxies, firewalls)
> => (2) Use HTML5 Cross-Origin Resource Sharing (CORS) support
> - http://www.w3.org/TR/cors/
> => (3) Use JSONP
> - http://www.ibm.com/developerworks/library/wa-aj-jsonp1/
> - Only supports GET HTTP requests
> - RPC servlet relies on POST HTTP requests
> => (4) Request metadata from server-side JSP and inline the JSON response
> in the gadget container page response
> - Not dynamic. Cannot add a gadget to the container on-the-fly via
> AJAX (i.e. without a full page reload)
> => (5) Use a hidden iframe source from the Shindig server on the gadget
> container page to get the gadget metadata
> - Need to define a special document on the Shindig server to fetch
> the gadget metadata and communicate back to the parent container via HTML5
> postMessage API
> => (6) Inject custom JavaScript into the gadget iframe (when constructed)
> to get the gadget metadata
> - "Chicken & the egg problem". Need the gadget metadata in order to
> render the gadget iframe
> - Too hacky. Need to interfere with the internal workings & flow of
> control of the common container
> ----------------------------------------------------------------------------------------
> Selected Solution (CORS)
> ----------------------------------------------------------------------------------------
> * Decided to implement option (2) CORS approach
> => Use common container preloadGadget API to fetch the gadget metadata and
> force Shindig to cache the response
> -
> http://opensocial-resources.googlecode.com/svn/spec/2.5/Core-Container.xml#osapi.container.Container.preloadGadget
> => Use common container navigateGadget API to render the gadget (e.g.
> Create iframe, etc.) using cached gadget metadata
> -
> http://opensocial-resources.googlecode.com/svn/spec/2.5/Core-Container.xml#osapi.container.Container.navigateGadget
> - Note: If preloadGadget call is omitted, then the navigateGadget
> call will try to fetch the gadget metadata itself and fail due to
> cross-domain security failures
> * On Jetty, use built-in Cross Origin Filter feature
>
> http://download.eclipse.org/jetty/7.6.11.v20130520/apidocs/org/eclipse/jetty/servlets/CrossOriginFilter.html
> http://wiki.eclipse.org/Jetty/Feature/Cross_Origin_Filter
> * On Tomcat, use built-in CORS filter feature
> http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter
> ----------------------------------------------------------------------------------------
> Jetty Cross Origin Filter Configuration
> ----------------------------------------------------------------------------------------
> <filter>
> <filter-name>cross-origin</filter-name>
> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
> <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,OPTIONS,PUT</param-value>
> </init-param>
> <init-param>
> <param-name>allowedHeaders</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>preflightMaxAge</param-name>
> <param-value>1800</param-value>
> </init-param>
> <init-param>
> <param-name>allowCredentials</param-name>
> <param-value>true</param-value>
> </init-param>
> <init-param>
> <param-name>chainPreflight</param-name>
> <param-value>false</param-value>
> </init-param>
> </filter>
> <filter-mapping>
> <filter-name>cross-origin</filter-name>
> <url-pattern>/*</url-pattern>
> </filter-mapping>
> ----------------------------------------------------------------------------------------
> Tomcat CORS Filter Configuration
> ----------------------------------------------------------------------------------------
> <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.support.credentials</param-name>
> <param-value>true</param-value>
> </init-param>
> <init-param>
> <param-name>cors.preflight.maxage</param-name>
> <param-value>1800</param-value>
> </init-param>
> </filter>
> <filter-mapping>
> <filter-name>CorsFilter</filter-name>
> <url-pattern>/*</url-pattern>
> </filter-mapping>
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira