Retrieve RAPT for reauth sign-in flow
Add implementation that obtains a Reauth proof token (RAPT) from Gaia
during the user authentication at the Login Screen. This RAPT will be
used later for the Cryptohome Recovery project, in order to prove the
successful authentication when making a client-server request.
RART will be obtained by a client-server request in the future, but in
this temporary prototype we're configuring it manually.
Bug: b:197615068
Change-Id: I55259cd1bd4348c2d43ade5618d0360a38e66027
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3106127
Commit-Queue: Yunke Zhou <yunkez@google.com>
Reviewed-by: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: Roman Sorokin [CET] <rsorokin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#915652}
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc
index 8ba150e..9c32839 100644
--- a/ash/constants/ash_switches.cc
+++ b/ash/constants/ash_switches.cc
@@ -553,6 +553,11 @@
// Sets the throttle fps for compositor frame submission.
const char kFrameThrottleFps[] = "frame-throttle-fps";
+// A reauth request token that will be passed in the Gaia embedded sign-in URL.
+// The token will be obtained by a client-server request in the future, but in
+// this temporary prototype we're configuring it manually.
+const char kGaiaReauthRequestToken[] = "gaia-reauth-request-token";
+
// Indicates that the browser is in "browse without sign-in" (Guest session)
// mode. Should completely disable extensions, sync and bookmarks.
const char kGuestSession[] = "bwsi";
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h
index d9c9a882..c8899f8 100644
--- a/ash/constants/ash_switches.h
+++ b/ash/constants/ash_switches.h
@@ -182,6 +182,7 @@
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kForceTabletPowerButton[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kFormFactor[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kFrameThrottleFps[];
+COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kGaiaReauthRequestToken[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kGuestSession[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kGuestWallpaperLarge[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kGuestWallpaperSmall[];
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js
index 83317ac..8d8e281 100644
--- a/chrome/browser/resources/gaia_auth_host/authenticator.js
+++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -219,6 +219,7 @@
'doSamlRedirect', // True if the authentication is done via external IdP.
'enableCloseView', // True if authenticator should wait for the closeView
// message from Gaia.
+ 'rart', // Encrypted reauth request token.
];
// Timeout in ms to wait for the message from Gaia indicating end of the flow.
@@ -453,9 +454,9 @@
this.closeViewReceived_ = false;
window.addEventListener(
- 'message', this.onMessageFromWebview_.bind(this), false);
- window.addEventListener('focus', this.onFocus_.bind(this), false);
- window.addEventListener('popstate', this.onPopState_.bind(this), false);
+ 'message', e => this.onMessageFromWebview_(e), false);
+ window.addEventListener('focus', () => this.onFocus_(), false);
+ window.addEventListener('popstate', e => this.onPopState_(e), false);
/**
* @type {boolean}
@@ -466,7 +467,7 @@
this.initializeAfterDomLoaded_();
} else {
document.addEventListener(
- 'DOMContentLoaded', this.initializeAfterDomLoaded_.bind(this));
+ 'DOMContentLoaded', () => this.initializeAfterDomLoaded_());
}
}
@@ -526,37 +527,36 @@
new cr.login.SamlHandler(this.webview_, false /* startsOnSamlPage */);
this.webviewEventManager_.addEventListener(
this.samlHandler_, 'insecureContentBlocked',
- this.onInsecureContentBlocked_.bind(this));
+ e => this.onInsecureContentBlocked_(e));
this.webviewEventManager_.addEventListener(
- this.samlHandler_, 'authPageLoaded',
- this.onAuthPageLoaded_.bind(this));
+ this.samlHandler_, 'authPageLoaded', e => this.onAuthPageLoaded_(e));
this.webviewEventManager_.addEventListener(
- this.samlHandler_, 'videoEnabled', this.onVideoEnabled_.bind(this));
+ this.samlHandler_, 'videoEnabled', e => this.onVideoEnabled_(e));
this.webviewEventManager_.addEventListener(
this.samlHandler_, 'apiPasswordAdded',
- this.onSamlApiPasswordAdded_.bind(this));
+ e => this.onSamlApiPasswordAdded_(e));
this.webviewEventManager_.addEventListener(
this.samlHandler_, 'challengeMachineKeyRequired',
- this.onChallengeMachineKeyRequired_.bind(this));
+ e => this.onChallengeMachineKeyRequired_(e));
this.webviewEventManager_.addEventListener(
- this.webview_, 'droplink', this.onDropLink_.bind(this));
+ this.webview_, 'droplink', e => this.onDropLink_(e));
this.webviewEventManager_.addEventListener(
- this.webview_, 'newwindow', this.onNewWindow_.bind(this));
+ this.webview_, 'newwindow', e => this.onNewWindow_(e));
this.webviewEventManager_.addEventListener(
- this.webview_, 'contentload', this.onContentLoad_.bind(this));
+ this.webview_, 'contentload', e => this.onContentLoad_(e));
this.webviewEventManager_.addEventListener(
- this.webview_, 'loadabort', this.onLoadAbort_.bind(this));
+ this.webview_, 'loadabort', e => this.onLoadAbort_(e));
this.webviewEventManager_.addEventListener(
- this.webview_, 'loadcommit', this.onLoadCommit_.bind(this));
+ this.webview_, 'loadcommit', e => this.onLoadCommit_(e));
this.webviewEventManager_.addWebRequestEventListener(
this.webview_.request.onCompleted,
- this.onRequestCompleted_.bind(this),
+ details => this.onRequestCompleted_(details),
{urls: ['<all_urls>'], types: ['main_frame']}, ['responseHeaders']);
this.webviewEventManager_.addWebRequestEventListener(
this.webview_.request.onHeadersReceived,
- this.onHeadersReceived_.bind(this),
+ details => this.onHeadersReceived_(details),
{urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']},
['responseHeaders']);
}
@@ -808,6 +808,9 @@
if (data.isDeviceOwner) {
url = appendParam(url, 'is_device_owner', '1');
}
+ if (data.rart) {
+ url = appendParam(url, 'rart', data.rart);
+ }
return url;
}
@@ -1016,11 +1019,8 @@
// does not expect it to be called immediately.
// TODO(xiyuan): Change to synchronous call when iframe based code
// is removed.
- const invokeConfirmPassword =
- (function() {
- this.confirmPasswordCallback(
- this.email_, this.samlHandler_.scrapedPasswordCount);
- }).bind(this);
+ const invokeConfirmPassword = () => this.confirmPasswordCallback(
+ this.email_, this.samlHandler_.scrapedPasswordCount);
window.setTimeout(invokeConfirmPassword, 0);
return;
}
@@ -1069,7 +1069,7 @@
if (!gaiaDone) {
// Start `gaiaDoneTimer_` if user info is not available.
this.gaiaDoneTimer_ = window.setTimeout(
- this.onGaiaDoneTimeout_.bind(this), GAIA_DONE_WAIT_TIMEOUT_MS);
+ () => this.onGaiaDoneTimeout_(), GAIA_DONE_WAIT_TIMEOUT_MS);
return;
}
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index aff201b..296bcdd 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -555,6 +555,13 @@
}
}
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kGaiaReauthRequestToken)) {
+ params.SetStringKey(
+ "rart", base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kGaiaReauthRequestToken));
+ }
+
was_security_token_pin_canceled_ = false;
frame_state_ = FRAME_STATE_LOADING;
diff --git a/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc b/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc
index 92b8c8e..a8c4495 100644
--- a/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc
+++ b/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc
@@ -26,6 +26,7 @@
const char kGAPSCookie[] = "GAPS";
const char kOAUTHCodeCookie[] = "oauth_code";
+const char kRAPTCookie[] = "RAPT";
constexpr base::TimeDelta kCookieDelay = base::TimeDelta::FromSeconds(20);
} // namespace
@@ -226,13 +227,15 @@
void OnlineLoginHelper::OnGetCookiesForCompleteAuthentication(
const net::CookieAccessResultList& cookies,
const net::CookieAccessResultList& excluded_cookies) {
- std::string auth_code, gaps_cookie;
+ std::string auth_code, gaps_cookie, rapt;
for (const auto& cookie_with_access_result : cookies) {
const auto& cookie = cookie_with_access_result.cookie;
if (cookie.Name() == login::kOAUTHCodeCookie)
auth_code = cookie.Value();
else if (cookie.Name() == login::kGAPSCookie)
gaps_cookie = cookie.Value();
+ else if (cookie.Name() == login::kRAPTCookie)
+ rapt = cookie.Value();
}
if (auth_code.empty()) {
@@ -249,6 +252,8 @@
user_context.SetAuthCode(auth_code);
if (!gaps_cookie.empty())
user_context.SetGAPSCookie(gaps_cookie);
+ if (!rapt.empty())
+ user_context.SetReauthProofToken(rapt);
std::move(complete_login_callback_).Run(user_context);
}
diff --git a/chromeos/login/auth/user_context.cc b/chromeos/login/auth/user_context.cc
index 64c62580..57f3995 100644
--- a/chromeos/login/auth/user_context.cc
+++ b/chromeos/login/auth/user_context.cc
@@ -138,6 +138,10 @@
return gaps_cookie_;
}
+const std::string& UserContext::GetReauthProofToken() const {
+ return reauth_proof_token_;
+}
+
const absl::optional<password_manager::PasswordHashData>&
UserContext::GetSyncPasswordData() const {
return sync_password_data_;
@@ -235,6 +239,10 @@
gaps_cookie_ = gaps_cookie;
}
+void UserContext::SetReauthProofToken(const std::string& reauth_proof_token) {
+ reauth_proof_token_ = reauth_proof_token;
+}
+
void UserContext::SetSyncPasswordData(
const password_manager::PasswordHashData& sync_password_data) {
sync_password_data_ = {sync_password_data};
diff --git a/chromeos/login/auth/user_context.h b/chromeos/login/auth/user_context.h
index 359b4aaf..ad80f76 100644
--- a/chromeos/login/auth/user_context.h
+++ b/chromeos/login/auth/user_context.h
@@ -85,6 +85,7 @@
const std::string& GetPublicSessionInputMethod() const;
const std::string& GetDeviceId() const;
const std::string& GetGAPSCookie() const;
+ const std::string& GetReauthProofToken() const;
const absl::optional<password_manager::PasswordHashData>&
GetSyncPasswordData() const;
const absl::optional<SamlPasswordAttributes>& GetSamlPasswordAttributes()
@@ -129,6 +130,7 @@
void SetPublicSessionInputMethod(const std::string& input_method);
void SetDeviceId(const std::string& device_id);
void SetGAPSCookie(const std::string& gaps_cookie);
+ void SetReauthProofToken(const std::string& reauth_proof_token);
void SetSyncPasswordData(
const password_manager::PasswordHashData& sync_password_data);
void SetSamlPasswordAttributes(
@@ -168,6 +170,7 @@
std::string public_session_input_method_;
std::string device_id_;
std::string gaps_cookie_;
+ std::string reauth_proof_token_;
bool is_under_advanced_protection_ = false;
std::string managed_guest_session_launch_extension_id_;
// |login_input_method_used_| is non-empty if login password/code was used,