简体   繁体   English

Google OAuth gapi.auth.authorize X-Frame-Options:SAMEORIGIN

[英]Google OAuth gapi.auth.authorize X-Frame-Options: SAMEORIGIN

Start ~2wks ago a few customers have started hitting an issue that prevents them from authenticating with Google services. 从2周前开始,一些客户已经开始遇到阻止他们使用Google服务进行身份验证的问题。 All of the instances that I have encountered so far appear to be on non-gmail domains. 到目前为止,我遇到的所有实例似乎都在非gmail域上。 The issue appears to be (see differences section below) that the https://accounts.google.com/o/oauth2/auth request from gapi.auth.authorize is returning a response with the 'X-Frame-Options: SAMEORIGIN' header for these particular clients. 问题似乎是(请参阅下面的差异部分)来自gapi.auth.authorize的https://accounts.google.com/o/oauth2/auth请求正在返回带有'X-Frame-Options:SAMEORIGIN'的响应这些特定客户的标题。 I have been unable to reproduce this issue locally, but was given a HAR of the failed request. 我无法在本地重现此问题,但是给出了失败请求的HAR。

This same authentication method is working well for a variety of other clients including other hosted domains (non-@gmail accounts). 这种相同的身份验证方法适用于各种其他客户端,包括其他托管域(非@gmail帐户)。

Any thoughts on what might be causing this request to fail? 有关可能导致此请求失败的原因的任何想法? Further things to investigate or additional information? 还有待调查的内容或其他信息?

In the developer console https://www.moo.do is a valid Javascript Origin. 在开发人员控制台中, https://www.moo.do是一个有效的Javascript Origin。

Ultimately the error displayed in the user's console: Load denied by X-Frame-Options: https://accounts.google.com/o/oauth2/auth ? 最终用户控制台中显示的错误:X-Frame-Options拒绝加载: https//accounts.google.com/o/oauth2/auth does not permit cross-origin framing. 不允许跨源框架。

Similarities 相似

  • Both of these requests use immediate=true when authorizing. 授权时,这两个请求都使用immediate = true。 When using immediate=false (which causes the request to go through the account selector popup) the failure account successfully services the request). 当使用immediate = false(导致请求通过帐户选择器弹出窗口)时,失败帐户成功地为请求提供服务)。

Differences 差异

  • In the response to the failure account there is an X-Frame-Options header. 在对故障帐户的响应中,存在X-Frame-Options标头。
  • In the response to the failure account the response.content.size field is 0. Additionally the response._transferSize is 0 and there is a response._error field present (its empty). 在对失败帐户的响应中,response.content.size字段为0.此外,response._transferSize为0并且存在response._error字段(其为空)。
  • In the response of the failure account the scopes param is encoded as '[scope]+[scope]+[scope]' which has been deprecated. 在失败帐户的响应中,范围参数被编码为已被弃用的“[范围] + [范围] + [范围]”。 [Edit: Received another HAR that uses the properly non-deprecated space separated scopes that still fails] [编辑:收到另一个使用仍然失败的正确非弃用空格分隔范围的HAR]

Below is a successful and a failed request. 以下是成功和失败的请求。 I'm at a loss for why the failed request is returning the extra header. 我很遗憾为什么失败的请求返回额外的标头。 Some of the information has been removed ([REMOVED]) or redacted (XXXX/YYYY). 部分信息已被删除([删除])或编辑(XXXX / YYYY)。

Successful Request 成功的要求

{
  "startedDateTime": "2016-03-03T15:52:27.625Z",
  "time": 84.7660000436008,
  "request": {
    "method": "GET",
    "url": "https://accounts.google.com/o/oauth2/auth?client_id=597847337936.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.appdata%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcontacts.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&immediate=true&login_hint=YYYYY%40YYYY.com&authuser=-1&include_granted_scopes=true&proxy=oauth2relay593501023&redirect_uri=postmessage&origin=https%3A%2F%2Fwww.moo.do&response_type=token&state=867674703%7C0.1520984533&jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.d1w1l2mcNcs.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCMuer-UxvQzEv7JYzkFSQh2Kou7xA",
    "httpVersion": "unknown",
    "headers": [
      {
        "name": "pragma",
        "value": "no-cache"
      },
      {
        "name": "accept-encoding",
        "value": "gzip, deflate, sdch"
      },
      {
        "name": "accept-language",
        "value": "en-US,en;q=0.8"
      },
      {
        "name": "upgrade-insecure-requests",
        "value": "1"
      },
      {
        "name": "user-agent",
        "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36"
      },
      {
        "name": "accept",
        "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
      },
      {
        "name": "cache-control",
        "value": "no-cache"
      },
      {
        "name": ":authority",
        "value": "accounts.google.com"
      },
      {
        "name": "cookie",
        "value": [REMOVED]
      },
      {
        "name": ":scheme",
        "value": "https"
      },
      {
        "name": "x-chrome-connected",
        "value": "id=108229145437218213687,mode=0,enable_account_consistency=false"
      },
      {
        "name": "referer",
        "value": "https://www.moo.do/app/"
      },
      {
        "name": "x-client-data",
        "value": "CKO2yQEIwbbJAQj9lcoB"
      },
      {
        "name": ":method",
        "value": "GET"
      }
    ],
    "queryString": [
      {
        "name": "client_id",
        "value": "597847337936.apps.googleusercontent.com"
      },
      {
        "name": "scope",
        "value": "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.appdata%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcontacts.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive"
      },
      {
        "name": "immediate",
        "value": "true"
      },
      {
        "name": "login_hint",
        "value": "YYYYY%40YYYY.com"
      },
      {
        "name": "authuser",
        "value": "-1"
      },
      {
        "name": "include_granted_scopes",
        "value": "true"
      },
      {
        "name": "proxy",
        "value": "oauth2relay593501023"
      },
      {
        "name": "redirect_uri",
        "value": "postmessage"
      },
      {
        "name": "origin",
        "value": "https%3A%2F%2Fwww.moo.do"
      },
      {
        "name": "response_type",
        "value": "token"
      },
      {
        "name": "state",
        "value": "867674703%7C0.1520984533"
      },
      {
        "name": "jsh",
        "value": "m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.d1w1l2mcMcs.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCMuer-UxvQzEv7JYzkFSQh2Kou7xA"
      }
    ],
    "cookies": [
      {
        "name": "LSOLH",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "SMSV",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "RMME",
        "value": "false",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "ACCOUNT_CHOOSER",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "GALX",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "GoogleAccountsLocale_session",
        "value": "en",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "expor",
        "value": "3100077",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "GMAIL_RTT",
        "value": "151",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "S",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "SID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "LSID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "HSID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "SSID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "APISID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "SAPISID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "GAPS",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "LSOLH",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "OGPC",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "NID",
        "value": [REMOVED],
        "expires": null,
        "httpOnly": false,
        "secure": false
      }
    ],
    "headersSize": -1,
    "bodySize": 0
  },
  "response": {
    "status": 200,
    "statusText": "OK",
    "httpVersion": "unknown",
    "headers": [
      {
        "name": "pragma",
        "value": "no-cache"
      },
      {
        "name": "date",
        "value": "Thu, 03 Mar 2016 15:52:27 GMT"
      },
      {
        "name": "content-encoding",
        "value": "gzip"
      },
      {
        "name": "x-content-type-options",
        "value": "nosniff"
      },
      {
        "name": "server",
        "value": "GSE"
      },
      {
        "name": "content-language",
        "value": "en"
      },
      {
        "name": "status",
        "value": "200"
      },
      {
        "name": "cache-control",
        "value": "no-cache, no-store, max-age=0, must-revalidate"
      },
      {
        "name": "content-type",
        "value": "text/html; charset=UTF-8"
      },
      {
        "name": "alt-svc",
        "value": "quic=\":443\"; ma=2592000; v=\"30,29,28,27,26,25\""
      },
      {
        "name": "alternate-protocol",
        "value": "443:quic,p=1"
      },
      {
        "name": "x-xss-protection",
        "value": "1; mode=block"
      },
      {
        "name": "expires",
        "value": "Fri, 01 Jan 1990 00:00:00 GMT"
      }
    ],
    "cookies": [],
    "content": {
      "size": 2096,
      "mimeType": "text/html"
    },
    "redirectURL": "",
    "headersSize": -1,
    "bodySize": -1,
    "_transferSize": 1051
  },
  "cache": {},
  "timings": {
    "blocked": 1.07300002127886,
    "dns": -1,
    "connect": -1,
    "send": 0.39199995808303,
    "wait": 81.3200001139194,
    "receive": 1.9809999503195002,
    "ssl": -1
  },
  "connection": "2025013",
  "pageref": "page_1"
}

Failed Request 请求失败

{
  "startedDateTime": "2016-03-03T10:12:35.752Z",
  "time": 442.6579999853857,
  "request": {
    "method": "GET",
    "url": "https://accounts.google.com/o/oauth2/auth?client_id=597847337936.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.appdata+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcontacts.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly&immediate=true&login_hint=XXXXX%40XXXX.com&authuser=-1&include_granted_scopes=true&proxy=oauth2relay235542267&redirect_uri=postmessage&origin=https%3A%2F%2Fwww.moo.do&response_type=token&state=638324187%7C0.1211244794&jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.de.7pJmZpTVQp8.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCOmU_zLoubGrUI-_ZI9ZhB7rGP1Sw",
    "httpVersion": "unknown",
    "headers": [
      {
        "name": "Accept",
        "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
      },
      { 
        "name": "Referer",
        "value": "https://www.moo.do/app/"
      },
      {
        "name": "Upgrade-Insecure-Requests",
        "value": "1"
      },
      {
        "name": "User-Agent",
        "value": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"
      }
    ],
    "queryString": [
      {
        "name": "client_id",
        "value": "597847337936.apps.googleusercontent.com"
      },
      {
        "name": "scope",
        "value": "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.appdata+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcontacts.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly"
      },
      {
        "name": "immediate",
        "value": "true"
      },
      {
        "name": "login_hint",
        "value": "XXXXX%40XXXX.com"
      },
      {
        "name": "authuser",
        "value": "-1"
      },
      {
        "name": "include_granted_scopes",
        "value": "true"
      },
      {
        "name": "proxy",
        "value": "oauth2relay235542267"
      },
      {
        "name": "redirect_uri",
        "value": "postmessage"
      },
      {
        "name": "origin",
        "value": "https%3A%2F%2Fwww.moo.do"
      },
      {
        "name": "response_type",
        "value": "token"
      },
      {
        "name": "state",
        "value": "638324187%7C0.1211244794"
      },
      {
        "name": "jsh",
        "value": "m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.de.7pJmZpTVQp8.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCOmU_zLoubGrUI-_ZI9ZhB7rGP1Sw"
      }
    ],
    "cookies": [],
    "headersSize": -1,
    "bodySize": 0
  },
  "response": {
    "status": 200,
    "statusText": "OK",
    "httpVersion": "unknown",
    "headers": [
      {
        "name": "pragma",
        "value": "no-cache"
      },
      {
        "name": "date",
        "value": "Thu, 03 Mar 2016 10:12:35 GMT"
      },
      {
        "name": "content-encoding",
        "value": "gzip"
      },
      {
        "name": "x-content-type-options",
        "value": "nosniff"
      },
      {
        "name": "server",
        "value": "GSE"
      },
      {
        "name": "x-frame-options",
        "value": "SAMEORIGIN"
      },
      {
        "name": "content-language",
        "value": "de"
      },
      {
        "name": "status",
        "value": "200"
      },
      {
        "name": "cache-control",
        "value": "no-cache, no-store, max-age=0, must-revalidate"
      },
      {
        "name": "content-type",
        "value": "text/html; charset=UTF-8"
      },
      {
        "name": "alt-svc",
        "value": "quic=\":443\"; ma=2592000; v=\"30,29,28,27,26,25\""
      },
      {
        "name": "alternate-protocol",
        "value": "443:quic,p=1"
      },
      {
        "name": "x-xss-protection",
        "value": "1; mode=block"
      },
      {
        "name": "expires",
        "value": "Fri, 01 Jan 1990 00:00:00 GMT"
      }
    ],
    "cookies": [],
    "content": {
      "size": 0,
      "mimeType": "text/html"
    },
    "redirectURL": "",
    "headersSize": -1,
    "bodySize": -1,
    "_transferSize": 0,
    "_error": ""
  },
  "cache": {},
  "timings": {
    "blocked": 0.944999977946281,
    "dns": -1,
    "connect": -1,
    "send": 0.3190000134054589,
    "wait": 151.53400000417625,
    "receive": 289.85999998985767,
    "ssl": -1
  },
  "pageref": "page_1"
}

Great. 大。

Problem/Cause 问题/原因

The Google authorization servers attach the 'X-Frame-Options: SAMEORIGIN' header to Hosted Domain accounts (Google Apps) if the app makes a request for more than 7 OAuth scopes. 如果应用程序请求超过7个OAuth范围,则Google授权服务器会将“X-Frame-Options:SAMEORIGIN”标头附加到托管域帐户(Google Apps)。 Less than 7 (it doesn't matter what the scopes are) and the same request on the same account does not have the X-Frame-Options header specified in the return call. 小于7(无论范围是什么)并且同一帐户上的相同请求没有在返回调用中指定的X-Frame-Options标头。

There are additional moving parts that are required to make this repro happen (must supply the jsh param from the GAPI JS client) and other scenarios where the X-Frame-Options header is returned. 还有其他移动部件需要进行此重现(必须提供来自GAPI JS客户端的jsh参数)以及返回X-Frame-Options标头的其他方案。 At this point however the repro files show that there appears to be an issue with the Google authorization server. 此时,repro文件显示Google授权服务器似乎存在问题。

Complaining :) 抱怨:)

Due to the nature of the X-Frame-Options header, client-side error detecting will not know that a request has been blocked which makes this particular error even more of a problem. 由于X-Frame-Options标头的性质,客户端错误检测不会知道请求已被阻止,这使得此特定错误更加严重。 Additionally the authorization callback will never be notified that there was any kind of failure leaving the requesting app in a state of limbo waiting for any kind of notification. 此外,永远不会通知授权回调有任何类型的故障,使请求的应用程序处于等待任何类型的通知的状态。

Problem Demonstration 问题演示

Demos 演示

There are two repro files included: 有两个repro文件包括:

auth_repro.html - This entirely sidesteps the GAPI JS client and demonstrates the issue. auth_repro.html - 这完全避开了GAPI JS客户端并演示了这个问题。 It does use a specific param (jsh) that the client attaches to the authorization requests to make the problem happen. 它确实使用客户端附加到授权请求的特定参数(jsh)来解决问题。

auth_repro_gapi.html - This uses the GAPI JS client to reproduce the issue. auth_repro_gapi.html - 这使用GAPI JS客户端重现该问题。

Solution

Don't be lazy about trimming/managing scopes that you are requesting or your authorization requests will start silently failing. 不要懒于修剪/管理您请求的范围,否则您的授权请求将以静默方式启动失败。

It would also be great if this behavior wasn't a thing. 如果这种行为不是一件好事也会很棒。 Best guess is that it's a security measure gone wrong? 最好的猜测是,这是一个出错的安全措施?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 谷歌视图在框架中,因为它将'X-Frame-Options'设置为'SAMEORIGIN' - Google Views in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN' 从“ X-Frame-Options”到“ SAMEORIGIN”。 错误 - 'X-Frame-Options' to 'SAMEORIGIN'. error gapi.auth.authorize:TypeError:cv(...)为null - gapi.auth.authorize: TypeError: cv(…) is null 带立即数的gapi.auth.authorize:true不起作用 - gapi.auth.authorize with immediate: true is not working gapi.auth.authorize:TypeError:_.Uu不是函数 - gapi.auth.authorize: TypeError: _.Uu is not a function 拒绝在框架中显示“url”,因为它将“X-Frame-Options”设置为“sameorigin”。 嵌入谷歌 tresns 图 - Refused to display 'url' in a frame because it set 'X-Frame-Options' to 'sameorigin'. embed a google tresns graph 拒绝在框架中显示谷歌,因为它将'X-Frame-Options'设置为'SAMEORIGIN' - Refused to display google in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN' 拒绝显示在一个框架中,因为它将'X-Frame-Options'设置为'SAMEORIGIN' - Refused to display in a frame , because it set 'X-Frame-Options' to 'SAMEORIGIN' 错误:在框架中,因为它将“X-Frame-Options”设置为“sameorigin” - Error : in a frame because it set 'X-Frame-Options' to 'sameorigin' 如何在没有iframe /对象的情况下嵌入translate.google.com(X-Frame-Options为SAMEORIGIN) - How to embed translate.google.com without iframe/object (X-Frame-Options is SAMEORIGIN)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM