7

Начало ~ 2wks назад несколько клиентов начали сталкиваться с проблемой, которая препятствует их аутентификации с помощью сервисов Google. Все экземпляры, с которыми я столкнулся, по-видимому, находятся в доменах, отличных от gmail. Кажется, что проблема (см. Раздел различий ниже), что запрос https://accounts.google.com/o/oauth2/auth от gapi.auth.authorize возвращает ответ с заголовком «X-Frame-Options: SAMEORIGIN» для этих конкретных клиентов. Я не смог воспроизвести эту проблему локально, но получил HAR отказавшего запроса.Google OAuth gapi.auth.authorize X-Frame-Options: SAMEORIGIN

Этот же метод аутентификации работает хорошо для множества других клиентов, включая другие размещенные домены (учетные записи без @ gmail).

Любые мысли о том, что может вызвать провал этого запроса? Дальнейшие вещи для расследования или дополнительной информации?

В консоли разработчика https://www.moo.do является действительным Javascript Origin.

В конечном счете, ошибка, отображаемая на консоли пользователя: Загрузка отказана с помощью X-Frame-Options: https://accounts.google.com/o/oauth2/auth? не допускает кадрирование скрещивания.

Сходства

  • Оба этих запросов используют непосредственный = истина при авторизации. При использовании немедленного = false (что заставляет запрос проходить через всплывающее окно учетной записи), учетная запись сбоя успешно обслуживает запрос).

Различия

  • В ответ на отказ счета есть заголовок X-Frame-Options.
  • В ответе на счет сбоя поле response.content.size равно 0. Кроме того, response._transferSize равен 0 и присутствует поле response._error (пустое).
  • В ответе учетной записи сбоя параметр scopes кодируется как «[scope] + [scope] + [scope]», который устарел. [Редактировать: получено другое HAR, которое использует области, не соответствующие устаревшим пространствам, которые все еще не работают]

Ниже представлен успешный и неудачный запрос. Я не понимаю, почему неудачный запрос возвращает дополнительный заголовок. Некоторая информация удалена ([СНЯТИЕ]) или отредактирована (XXXX/YYYY).

Успешный запрос

{ 
    "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" 
} 

ответ

2

Великий.

Проблема/Причина

Серверы авторизации Google прикрепить 'X-Frame-Options: SAMEORIGIN' заголовок Hosted счетов домена (приложения Google), если приложение делает запрос на более чем 7 OAuth областей.Менее 7 (неважно, каковы области), и один и тот же запрос в той же учетной записи не имеет заголовка X-Frame-Options, указанного в обратном вызове.

Есть дополнительные движущиеся части, необходимые для выполнения этого воспроизведения (необходимо предоставить параметр jsh из клиента GAPI JS) и другие сценарии, в которых возвращается заголовок X-Frame-Options. Однако в этом случае файлы воспроизведения показывают, что проблема связана с сервером авторизации Google.

Жаловаться :)

В связи с характером X-Frame-Options заголовка на стороне клиента обнаружения ошибок не будет знать, что запрос был заблокирован, что делает это конкретная ошибка даже больше проблемы , Кроме того, обратный вызов авторизации никогда не будет уведомлен о том, что существует какой-либо отказ, оставляющий запрашивающее приложение в состоянии неопределенности, ожидая какого-либо уведомления.

Проблема Демонстрация

Demos

Есть два файла включены репрографии:

auth_repro.html - Это полностью обходит клиента GAPI JS и демонстрирует проблему. Он использует определенный параметр (jsh), который клиент присоединяет к запросам авторизации, чтобы проблема возникла.

auth_repro_gapi.html - Это использует клиент GAPI JS для воспроизведения проблемы.

Решение

Не ленитесь о уравновешивать/управляющей области, которые вы запрашиваете или ваши запросы авторизации начнут молча терпит неудачу.

Было бы здорово, если бы это было не так. Лучше догадаться, что это мера безопасности пошла не так?