facebookspring-securityfacebook-canvasx-frame-optionsspring-social-facebook

Top level redirect at client side Facebook Canvas / X-Frame-Options Deny


I am trying to build Facebook Canvas application using Java/Spring Social Facebook library.

When an user first time access the Canvas page(apps.facebook.com/mycanvasapp), facebook is doing HTTP POST with 'signed_request' in the body to my app url.

As the user is first time accessing the app, facebook sends empty 'oauth_token' in the POST body; hence my app returns HTTP 200 code with below Java Script code to present authorization dialog box to the user.

top.location.href='https://www.facebook.com/v2.5/dialog/oauth?client_id=12345&redirect_uri=https://myapp.com/canvas/';

This is to do top level redirect at client/browser side as HTTP server redirect is not allowed in iframe.

However, I do get below error in browser/Chrome logs and fails to present the authorization window to the user.

Refused to display 'https://myapp.com/canvas/' in a frame because it set 'X-Frame-Options' to 'DENY'.

Similar question asked in other post - Web App in Facebook Canvas / X-Frame-Options Deny Case where it suggested to do browser side top level redirect instead of HTTP server redirect.

I am doing top level browser redirect only using 'top.location.href' in Java Script, but still experiencing same problem.

When i replay the request in the curl/command line, here is the response that my app is returning that seems to be okay to me.

 HTTP/1.1 200 OK
 Connection: keep-alive
 Server: Apache-Coyote/1.1
 X-Content-Type-Options: nosniff
 X-Xss-Protection: 1; mode=block
 Cache-Control: no-cache, no-store, max-age=0, must-revalidate
 Pragma: no-cache
 Expires: 0
 Strict-Transport-Security: max-age=31536000 ; includeSubDomains
 X-Frame-Options: DENY
 Access-Control-Allow-Origin: *
 Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE
 Access-Control-Max-Age: 3600
 Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, X-Auth-Token
 Content-Language: en-US
 Transfer-Encoding: chunked
 Date: Sat, 09 Jul 2016 04:40:17 GMT
 Via: 1.1 vegur
<script>top.location.href='https://www.facebook.com/v2.5/dialog/oauth?client_id=12345&redirect_uri=https://myapp.com/canvas/';</script>

Tweaking 'X-Frame-Options' header field seems not helping much.

What am I missing ? Can some one please suggest a workable solution ?

There are some suggestions on using Facebook Java Script SDK library. But as my app contains within Facebook Canvas page, upon accessing the Canvas page Facebook does HTTP Post to my server, so wondering how to load HTML/Java Script to load Facebook Java Script SDK library before this process kicks in.

PS: I am using org.springframework.social.facebook.web.CanvasSignInController Spring pre-built controller in my app.


Solution

  • I resolved this problem by disabling/suppressing be security headers for the POST response from my server,

    X-Content-Type-Options: nosniff X-Xss-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Strict-Transport-Security: max-age=31536000 ; includeSubDomains X-Frame-Options: DENY Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE Access-Control-Max-Age: 3600 Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, X-

    The key is to exclude X-Frame-Options & Strict-Transport-Security in the headers, that resolved the problem for me now.