Commit 8171be71 authored by Maksim Ivanov's avatar Maksim Ivanov Committed by Commit Bot

Chrome OS Login: known_user for SAML API usage

Store in the Local State (as a known_user preference) the boolean flag
whether the SAML Credentials Passing API (a.k.a. the principals API) was
used during the authentication of this user.

Bug: 971795
Test: browser_tests --gtest_filter="SamlTest.*:OobeTest.*"
Change-Id: I92a7e2c9c029cb02df8b51e581cb6e0f34e3e6f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1662552
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarAchuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/heads/master@{#670057}
parent 79534f5f
...@@ -20,6 +20,10 @@ ...@@ -20,6 +20,10 @@
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/constants/chromeos_switches.h" #include "chromeos/constants/chromeos_switches.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/user.h"
#include "content/public/browser/notification_details.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "google_apis/gaia/gaia_switches.h" #include "google_apis/gaia/gaia_switches.h"
...@@ -85,6 +89,12 @@ IN_PROC_BROWSER_TEST_F(OobeTest, NewUser) { ...@@ -85,6 +89,12 @@ IN_PROC_BROWSER_TEST_F(OobeTest, NewUser) {
FakeGaiaMixin::kEmptyUserServices); FakeGaiaMixin::kEmptyUserServices);
session_start_waiter.Wait(); session_start_waiter.Wait();
const AccountId account_id =
content::Details<const user_manager::User>(session_start_waiter.details())
->GetAccountId();
EXPECT_FALSE(
user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(account_id));
} }
IN_PROC_BROWSER_TEST_F(OobeTest, Accelerator) { IN_PROC_BROWSER_TEST_F(OobeTest, Accelerator) {
......
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
#include "components/policy/policy_constants.h" #include "components/policy/policy_constants.h"
#include "components/policy/proto/chrome_device_policy.pb.h" #include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/user.h" #include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
...@@ -536,6 +537,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) { ...@@ -536,6 +537,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) {
SystemSaltGetter::ConvertRawSaltToHexString( SystemSaltGetter::ConvertRawSaltToHexString(
FakeCryptohomeClient::GetStubSystemSalt())); FakeCryptohomeClient::GetStubSystemSalt()));
EXPECT_EQ(key.GetSecret(), cryptohome_client_->salted_hashed_secret()); EXPECT_EQ(key.GetSecret(), cryptohome_client_->salted_hashed_secret());
EXPECT_TRUE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
} }
// Tests the single password scraped flow. // Tests the single password scraped flow.
...@@ -568,6 +573,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) { ...@@ -568,6 +573,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) {
} while (message != "\"fake_password\""); } while (message != "\"fake_password\"");
session_start_waiter.Wait(); session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
} }
// Tests password scraping from a dynamically created password field. // Tests password scraping from a dynamically created password field.
...@@ -594,6 +603,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedDynamic) { ...@@ -594,6 +603,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedDynamic) {
content::NotificationService::AllSources()); content::NotificationService::AllSources());
SigninFrameJS().TapOn("Submit"); SigninFrameJS().TapOn("Submit");
session_start_waiter.Wait(); session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
} }
// Tests the multiple password scraped flow. // Tests the multiple password scraped flow.
...@@ -619,6 +632,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) { ...@@ -619,6 +632,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) {
content::NotificationService::AllSources()); content::NotificationService::AllSources());
SendConfirmPassword("password1"); SendConfirmPassword("password1");
session_start_waiter.Wait(); session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
} }
// Tests the no password scraped flow. // Tests the no password scraped flow.
...@@ -645,6 +662,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) { ...@@ -645,6 +662,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) {
content::NotificationService::AllSources()); content::NotificationService::AllSources());
SetManualPasswords("Test1", "Test1"); SetManualPasswords("Test1", "Test1");
session_start_waiter.Wait(); session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
} }
// Types |bob@corp.example.com| into the GAIA login form but then authenticates // Types |bob@corp.example.com| into the GAIA login form but then authenticates
......
...@@ -1516,9 +1516,13 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) { ...@@ -1516,9 +1516,13 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
user_manager::UserManager* user_manager = user_manager::UserManager::Get(); user_manager::UserManager* user_manager = user_manager::UserManager::Get();
if (user_manager->IsLoggedInAsUserWithGaiaAccount()) { if (user_manager->IsLoggedInAsUserWithGaiaAccount()) {
if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) {
user_manager::known_user::UpdateUsingSAML(user_context_.GetAccountId(), user_manager::known_user::UpdateUsingSAML(user_context_.GetAccountId(),
true); true);
user_manager::known_user::UpdateIsUsingSAMLPrincipalsAPI(
user_context_.GetAccountId(),
user_context_.IsUsingSamlPrincipalsApi());
}
SAMLOfflineSigninLimiter* saml_offline_signin_limiter = SAMLOfflineSigninLimiter* saml_offline_signin_limiter =
SAMLOfflineSigninLimiterFactory::GetForProfile(profile); SAMLOfflineSigninLimiterFactory::GetForProfile(profile);
if (saml_offline_signin_limiter) if (saml_offline_signin_limiter)
......
...@@ -831,6 +831,8 @@ void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication( ...@@ -831,6 +831,8 @@ void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication(
user_context.SetAuthFlow(using_saml user_context.SetAuthFlow(using_saml
? UserContext::AUTH_FLOW_GAIA_WITH_SAML ? UserContext::AUTH_FLOW_GAIA_WITH_SAML
: UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML); : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
if (using_saml)
user_context.SetIsUsingSamlPrincipalsApi(using_saml_api_);
user_context.SetGAPSCookie(gaps_cookie); user_context.SetGAPSCookie(gaps_cookie);
if (using_saml && ExtractSamlPasswordAttributesEnabled()) { if (using_saml && ExtractSamlPasswordAttributesEnabled()) {
user_context.SetSamlPasswordAttributes(password_attributes); user_context.SetSamlPasswordAttributes(password_attributes);
...@@ -983,6 +985,8 @@ void GaiaScreenHandler::DoCompleteLogin( ...@@ -983,6 +985,8 @@ void GaiaScreenHandler::DoCompleteLogin(
user_context.SetAuthFlow(using_saml user_context.SetAuthFlow(using_saml
? UserContext::AUTH_FLOW_GAIA_WITH_SAML ? UserContext::AUTH_FLOW_GAIA_WITH_SAML
: UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML); : UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
if (using_saml)
user_context.SetIsUsingSamlPrincipalsApi(using_saml_api_);
if (using_saml && ExtractSamlPasswordAttributesEnabled()) { if (using_saml && ExtractSamlPasswordAttributesEnabled()) {
user_context.SetSamlPasswordAttributes(password_attributes); user_context.SetSamlPasswordAttributes(password_attributes);
......
...@@ -334,6 +334,10 @@ class GaiaScreenHandler : public BaseScreenHandler, ...@@ -334,6 +334,10 @@ class GaiaScreenHandler : public BaseScreenHandler,
// If the user authenticated via SAML, this indicates whether the principals // If the user authenticated via SAML, this indicates whether the principals
// API was used. // API was used.
// TODO(emaxx): This is also currently set when the user authenticated via
// Gaia, since Gaia uses the same API for passing the password to Chrome.
// Either fix this behavior, or change the naming and the comments to reflect
// it.
bool using_saml_api_ = false; bool using_saml_api_ = false;
// Test credentials. // Test credentials.
......
...@@ -113,6 +113,10 @@ UserContext::AuthFlow UserContext::GetAuthFlow() const { ...@@ -113,6 +113,10 @@ UserContext::AuthFlow UserContext::GetAuthFlow() const {
return auth_flow_; return auth_flow_;
} }
bool UserContext::IsUsingSamlPrincipalsApi() const {
return is_using_saml_principals_api_;
}
user_manager::UserType UserContext::GetUserType() const { user_manager::UserType UserContext::GetUserType() const {
return user_type_; return user_type_;
} }
...@@ -196,6 +200,11 @@ void UserContext::SetAuthFlow(AuthFlow auth_flow) { ...@@ -196,6 +200,11 @@ void UserContext::SetAuthFlow(AuthFlow auth_flow) {
auth_flow_ = auth_flow; auth_flow_ = auth_flow;
} }
void UserContext::SetIsUsingSamlPrincipalsApi(
bool is_using_saml_principals_api) {
is_using_saml_principals_api_ = is_using_saml_principals_api;
}
void UserContext::SetPublicSessionLocale(const std::string& locale) { void UserContext::SetPublicSessionLocale(const std::string& locale) {
public_session_locale_ = locale; public_session_locale_ = locale;
} }
......
...@@ -79,6 +79,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext { ...@@ -79,6 +79,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext {
bool IsUsingPin() const; bool IsUsingPin() const;
bool IsForcingDircrypto() const; bool IsForcingDircrypto() const;
AuthFlow GetAuthFlow() const; AuthFlow GetAuthFlow() const;
bool IsUsingSamlPrincipalsApi() const;
user_manager::UserType GetUserType() const; user_manager::UserType GetUserType() const;
const std::string& GetPublicSessionLocale() const; const std::string& GetPublicSessionLocale() const;
const std::string& GetPublicSessionInputMethod() const; const std::string& GetPublicSessionInputMethod() const;
...@@ -105,6 +106,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext { ...@@ -105,6 +106,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext {
void SetIsUsingPin(bool is_using_pin); void SetIsUsingPin(bool is_using_pin);
void SetIsForcingDircrypto(bool is_forcing_dircrypto); void SetIsForcingDircrypto(bool is_forcing_dircrypto);
void SetAuthFlow(AuthFlow auth_flow); void SetAuthFlow(AuthFlow auth_flow);
void SetIsUsingSamlPrincipalsApi(bool is_using_saml_principals_api);
void SetPublicSessionLocale(const std::string& locale); void SetPublicSessionLocale(const std::string& locale);
void SetPublicSessionInputMethod(const std::string& input_method); void SetPublicSessionInputMethod(const std::string& input_method);
void SetDeviceId(const std::string& device_id); void SetDeviceId(const std::string& device_id);
...@@ -130,6 +132,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext { ...@@ -130,6 +132,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext {
bool is_using_pin_ = false; bool is_using_pin_ = false;
bool is_forcing_dircrypto_ = false; bool is_forcing_dircrypto_ = false;
AuthFlow auth_flow_ = AUTH_FLOW_OFFLINE; AuthFlow auth_flow_ = AUTH_FLOW_OFFLINE;
bool is_using_saml_principals_api_ = false;
user_manager::UserType user_type_ = user_manager::USER_TYPE_REGULAR; user_manager::UserType user_type_ = user_manager::USER_TYPE_REGULAR;
std::string public_session_locale_; std::string public_session_locale_;
std::string public_session_input_method_; std::string public_session_input_method_;
......
...@@ -43,6 +43,9 @@ const char kAccountTypeKey[] = "account_type"; ...@@ -43,6 +43,9 @@ const char kAccountTypeKey[] = "account_type";
// Key of whether this user ID refers to a SAML user. // Key of whether this user ID refers to a SAML user.
const char kUsingSAMLKey[] = "using_saml"; const char kUsingSAMLKey[] = "using_saml";
// Key of whether this user authenticated via SAML using the principals API.
const char kIsUsingSAMLPrincipalsAPI[] = "using_saml_principals_api";
// Key of Device Id. // Key of Device Id.
const char kDeviceId[] = "device_id"; const char kDeviceId[] = "device_id";
...@@ -72,6 +75,7 @@ const char* kReservedKeys[] = {kCanonicalEmail, ...@@ -72,6 +75,7 @@ const char* kReservedKeys[] = {kCanonicalEmail,
kObjGuidKey, kObjGuidKey,
kAccountTypeKey, kAccountTypeKey,
kUsingSAMLKey, kUsingSAMLKey,
kIsUsingSAMLPrincipalsAPI,
kDeviceId, kDeviceId,
kGAPSCookie, kGAPSCookie,
kReauthReasonKey, kReauthReasonKey,
...@@ -519,6 +523,23 @@ bool IsUsingSAML(const AccountId& account_id) { ...@@ -519,6 +523,23 @@ bool IsUsingSAML(const AccountId& account_id) {
return false; return false;
} }
void USER_MANAGER_EXPORT
UpdateIsUsingSAMLPrincipalsAPI(const AccountId& account_id,
bool is_using_saml_principals_api) {
SetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI,
is_using_saml_principals_api);
}
bool USER_MANAGER_EXPORT
GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id) {
bool is_using_saml_principals_api;
if (GetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI,
&is_using_saml_principals_api)) {
return is_using_saml_principals_api;
}
return false;
}
void SetProfileRequiresPolicy(const AccountId& account_id, void SetProfileRequiresPolicy(const AccountId& account_id,
ProfileRequiresPolicy required) { ProfileRequiresPolicy required) {
DCHECK_NE(required, ProfileRequiresPolicy::kUnknown); DCHECK_NE(required, ProfileRequiresPolicy::kUnknown);
......
...@@ -152,6 +152,15 @@ void USER_MANAGER_EXPORT UpdateUsingSAML(const AccountId& account_id, ...@@ -152,6 +152,15 @@ void USER_MANAGER_EXPORT UpdateUsingSAML(const AccountId& account_id,
// returns false. // returns false.
bool USER_MANAGER_EXPORT IsUsingSAML(const AccountId& account_id); bool USER_MANAGER_EXPORT IsUsingSAML(const AccountId& account_id);
// Setter and getter for the known user preference that stores whether the user
// authenticated via SAML using the principals API.
void USER_MANAGER_EXPORT
UpdateIsUsingSAMLPrincipalsAPI(const AccountId& account_id,
bool is_using_saml_principals_api);
bool USER_MANAGER_EXPORT
GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id);
// Enum describing whether a user's profile requires policy. If kPolicyRequired, // Enum describing whether a user's profile requires policy. If kPolicyRequired,
// the profile initialization code will ensure that valid policy is loaded // the profile initialization code will ensure that valid policy is loaded
// before session initialization completes. // before session initialization completes.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment