| Index: chrome/browser/resources/gaia_auth/background.js
|
| diff --git a/chrome/browser/resources/gaia_auth/background.js b/chrome/browser/resources/gaia_auth/background.js
|
| index 3baafc2c332103425c7787c50207c86f61b67886..50c72243f18be0bf8e38a7de499dfa1305d280fb 100644
|
| --- a/chrome/browser/resources/gaia_auth/background.js
|
| +++ b/chrome/browser/resources/gaia_auth/background.js
|
| @@ -58,10 +58,10 @@ BackgroundBridgeManager.prototype = {
|
| chrome.webRequest.onHeadersReceived.addListener(
|
| function(details) {
|
| if (this.bridges_[details.tabId])
|
| - this.bridges_[details.tabId].onHeadersReceived(details);
|
| + return this.bridges_[details.tabId].onHeadersReceived(details);
|
| }.bind(this),
|
| {urls: ['*://*/*'], types: ['sub_frame']},
|
| - ['responseHeaders']);
|
| + ['blocking', 'responseHeaders']);
|
|
|
| chrome.webRequest.onCompleted.addListener(
|
| function(details) {
|
| @@ -260,31 +260,86 @@ BackgroundBridge.prototype = {
|
| /**
|
| * Handler or webRequest.onHeadersReceived. It reads the authenticated user
|
| * email from google-accounts-signin-header.
|
| + * @return {!Object} Modified request headers.
|
| */
|
| onHeadersReceived: function(details) {
|
| - if (!this.isDesktopFlow_ ||
|
| - !this.gaiaUrl_ ||
|
| - details.url.lastIndexOf(this.gaiaUrl_) != 0) {
|
| + var headers = details.responseHeaders;
|
| +
|
| + if (this.isDesktopFlow_ &&
|
| + this.gaiaUrl_ &&
|
| + details.url.lastIndexOf(this.gaiaUrl_) == 0) {
|
| // TODO(xiyuan, guohui): CrOS should reuse the logic below for reading the
|
| // email for SAML users and cut off the /ListAccount call.
|
| - return;
|
| + for (var i = 0; headers && i < headers.length; ++i) {
|
| + if (headers[i].name.toLowerCase() == 'google-accounts-signin') {
|
| + var headerValues = headers[i].value.toLowerCase().split(',');
|
| + var signinDetails = {};
|
| + headerValues.forEach(function(e) {
|
| + var pair = e.split('=');
|
| + signinDetails[pair[0].trim()] = pair[1].trim();
|
| + });
|
| + // Remove "" around.
|
| + this.email_ = signinDetails['email'].slice(1, -1);
|
| + this.sessionIndex_ = signinDetails['sessionindex'];
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
| - var headers = details.responseHeaders;
|
| - for (var i = 0; headers && i < headers.length; ++i) {
|
| - if (headers[i].name.toLowerCase() == 'google-accounts-signin') {
|
| - var headerValues = headers[i].value.toLowerCase().split(',');
|
| - var signinDetails = {};
|
| - headerValues.forEach(function(e) {
|
| - var pair = e.split('=');
|
| - signinDetails[pair[0].trim()] = pair[1].trim();
|
| - });
|
| - // Remove "" around.
|
| - this.email_ = signinDetails['email'].slice(1, -1);
|
| - this.sessionIndex_ = signinDetails['sessionindex'];
|
| - return;
|
| + if (!this.isDesktopFlow_) {
|
| + // Check whether GAIA headers indicating the start or end of a SAML
|
| + // redirect are present. If so, synthesize cookies to mark these points.
|
| + for (var i = 0; headers && i < headers.length; ++i) {
|
| + if (headers[i].name.toLowerCase() == 'google-accounts-saml') {
|
| + var action = headers[i].value.toLowerCase();
|
| + if (action == 'start') {
|
| + // GAIA is redirecting to a SAML IdP. Any cookies contained in the
|
| + // current |headers| were set by GAIA. Any cookies set in future
|
| + // requests will be coming from the IdP. Append a cookie to the
|
| + // current |headers| that marks the point at which the redirect
|
| + // occurred.
|
| + headers.push({name: 'Set-Cookie',
|
| + value: 'google-accounts-saml-start=now'});
|
| + return {responseHeaders: headers};
|
| + } else if (action == 'end') {
|
| + // The SAML IdP has redirected back to GAIA. Add a cookie that marks
|
| + // the point at which the redirect occurred occurred. It is
|
| + // important that this cookie be prepended to the current |headers|
|
| + // because any cookies contained in the |headers| were already set
|
| + // by GAIA, not the IdP. Due to limitations in the webRequest API,
|
| + // it is not trivial to prepend a cookie:
|
| + //
|
| + // The webRequest API only allows for deleting and appending
|
| + // headers. To prepend a cookie (C), three steps are needed:
|
| + // 1) Delete any headers that set cookies (e.g., A, B).
|
| + // 2) Append a header which sets the cookie (C).
|
| + // 3) Append the original headers (A, B).
|
| + //
|
| + // Due to a further limitation of the webRequest API, it is not
|
| + // possible to delete a header in step 1) and append an identical
|
| + // header in step 3). To work around this, a trailing semicolon is
|
| + // added to each header before appending it. Trailing semicolons are
|
| + // ignored by Chrome in cookie headers, causing the modified headers
|
| + // to actually set the original cookies.
|
| + var otherHeaders = [];
|
| + var cookies = [{name: 'Set-Cookie',
|
| + value: 'google-accounts-saml-end=now'}];
|
| + for (var j = 0; j < headers.length; ++j) {
|
| + if (headers[j].name.toLowerCase().indexOf('set-cookie') == 0) {
|
| + var header = headers[j];
|
| + header.value += ';';
|
| + cookies.push(header);
|
| + } else {
|
| + otherHeaders.push(headers[j]);
|
| + }
|
| + }
|
| + return {responseHeaders: otherHeaders.concat(cookies)};
|
| + }
|
| + }
|
| }
|
| }
|
| +
|
| + return {};
|
| },
|
|
|
| /**
|
|
|