[ 
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

Reply via email to