Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/login/login_handler.h" | 5 #include "chrome/browser/ui/login/login_handler.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "components/url_formatter/elide_url.h" | 25 #include "components/url_formatter/elide_url.h" |
| 26 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/notification_registrar.h" | 27 #include "content/public/browser/notification_registrar.h" |
| 28 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
| 29 #include "content/public/browser/render_frame_host.h" | 29 #include "content/public/browser/render_frame_host.h" |
| 30 #include "content/public/browser/resource_dispatcher_host.h" | 30 #include "content/public/browser/resource_dispatcher_host.h" |
| 31 #include "content/public/browser/resource_request_info.h" | 31 #include "content/public/browser/resource_request_info.h" |
| 32 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 33 #include "content/public/common/origin_util.h" | 33 #include "content/public/common/origin_util.h" |
| 34 #include "net/base/auth.h" | 34 #include "net/base/auth.h" |
| 35 #include "net/base/host_port_pair.h" | |
| 35 #include "net/base/load_flags.h" | 36 #include "net/base/load_flags.h" |
| 36 #include "net/http/http_auth_scheme.h" | 37 #include "net/http/http_auth_scheme.h" |
| 37 #include "net/http/http_transaction_factory.h" | 38 #include "net/http/http_transaction_factory.h" |
| 38 #include "net/url_request/url_request.h" | 39 #include "net/url_request/url_request.h" |
| 39 #include "net/url_request/url_request_context.h" | 40 #include "net/url_request/url_request_context.h" |
| 40 #include "ui/base/l10n/l10n_util.h" | 41 #include "ui/base/l10n/l10n_util.h" |
| 41 #include "ui/gfx/text_elider.h" | 42 #include "ui/gfx/text_elider.h" |
| 42 | 43 |
| 43 #if defined(ENABLE_EXTENSIONS) | 44 #if defined(ENABLE_EXTENSIONS) |
| 44 #include "components/guest_view/browser/guest_view_base.h" | 45 #include "components/guest_view/browser/guest_view_base.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 58 | 59 |
| 59 namespace { | 60 namespace { |
| 60 | 61 |
| 61 // Helper to remove the ref from an net::URLRequest to the LoginHandler. | 62 // Helper to remove the ref from an net::URLRequest to the LoginHandler. |
| 62 // Should only be called from the IO thread, since it accesses an | 63 // Should only be called from the IO thread, since it accesses an |
| 63 // net::URLRequest. | 64 // net::URLRequest. |
| 64 void ResetLoginHandlerForRequest(net::URLRequest* request) { | 65 void ResetLoginHandlerForRequest(net::URLRequest* request) { |
| 65 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request); | 66 ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request); |
| 66 } | 67 } |
| 67 | 68 |
| 68 // Helper to create a PasswordForm for PasswordManager to start looking for | |
| 69 // saved credentials. | |
| 70 PasswordForm MakeInputForPasswordManager(const GURL& request_url, | |
| 71 net::AuthChallengeInfo* auth_info) { | |
| 72 PasswordForm dialog_form; | |
| 73 if (base::LowerCaseEqualsASCII(auth_info->scheme, net::kBasicAuthScheme)) { | |
| 74 dialog_form.scheme = PasswordForm::SCHEME_BASIC; | |
| 75 } else if (base::LowerCaseEqualsASCII(auth_info->scheme, | |
| 76 net::kDigestAuthScheme)) { | |
| 77 dialog_form.scheme = PasswordForm::SCHEME_DIGEST; | |
| 78 } else { | |
| 79 dialog_form.scheme = PasswordForm::SCHEME_OTHER; | |
| 80 } | |
| 81 std::string host_and_port(auth_info->challenger.ToString()); | |
| 82 if (auth_info->is_proxy) { | |
| 83 std::string origin = host_and_port; | |
| 84 // We don't expect this to already start with http:// or https://. | |
| 85 DCHECK(origin.find("http://") != 0 && origin.find("https://") != 0); | |
| 86 origin = std::string("http://") + origin; | |
|
asanka
2016/06/14 18:50:48
vabr: This logic doesn't distinguish between http
vabr (Chromium)
2016/06/15 08:50:06
Thanks for the heads-up. I agree with your argumen
| |
| 87 dialog_form.origin = GURL(origin); | |
| 88 } else if (!auth_info->challenger.Equals( | |
| 89 net::HostPortPair::FromURL(request_url))) { | |
| 90 dialog_form.origin = GURL(); | |
| 91 NOTREACHED(); // crbug.com/32718 | |
| 92 } else { | |
| 93 dialog_form.origin = GURL(request_url.scheme() + "://" + host_and_port); | |
|
asanka
2016/06/14 18:50:48
vabr: Note that host_and_port will always contain
vabr (Chromium)
2016/06/15 08:50:06
Acknowledged.
| |
| 94 } | |
| 95 dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info); | |
| 96 return dialog_form; | |
| 97 } | |
| 98 | |
| 99 void ShowLoginPrompt(const GURL& request_url, | |
| 100 net::AuthChallengeInfo* auth_info, | |
| 101 LoginHandler* handler) { | |
| 102 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 103 WebContents* parent_contents = handler->GetWebContentsForLogin(); | |
| 104 if (!parent_contents) | |
| 105 return; | |
| 106 prerender::PrerenderContents* prerender_contents = | |
| 107 prerender::PrerenderContents::FromWebContents(parent_contents); | |
| 108 if (prerender_contents) { | |
| 109 prerender_contents->Destroy(prerender::FINAL_STATUS_AUTH_NEEDED); | |
| 110 return; | |
| 111 } | |
| 112 | |
| 113 base::string16 authority = l10n_util::GetStringFUTF16( | |
| 114 auth_info->is_proxy ? IDS_LOGIN_DIALOG_PROXY_AUTHORITY | |
| 115 : IDS_LOGIN_DIALOG_AUTHORITY, | |
| 116 url_formatter::FormatUrlForSecurityDisplay(request_url)); | |
| 117 base::string16 explanation; | |
| 118 if (!content::IsOriginSecure(request_url)) { | |
| 119 explanation = | |
| 120 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_NON_SECURE_TRANSPORT); | |
| 121 } | |
| 122 | |
| 123 password_manager::PasswordManager* password_manager = | |
| 124 handler->GetPasswordManagerForLogin(); | |
| 125 | |
| 126 if (!password_manager) { | |
| 127 #if defined(ENABLE_EXTENSIONS) | |
| 128 // A WebContents in a <webview> (a GuestView type) does not have a password | |
| 129 // manager, but still needs to be able to show login prompts. | |
| 130 const auto* guest = | |
| 131 guest_view::GuestViewBase::FromWebContents(parent_contents); | |
| 132 if (guest && | |
| 133 extensions::GetViewType(guest->owner_web_contents()) != | |
| 134 extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
| 135 handler->BuildViewWithoutPasswordManager(authority, explanation); | |
| 136 return; | |
| 137 } | |
| 138 #endif | |
| 139 handler->CancelAuth(); | |
| 140 return; | |
| 141 } | |
| 142 | |
| 143 if (password_manager && | |
| 144 password_manager->client()->GetLogManager()->IsLoggingActive()) { | |
| 145 password_manager::BrowserSavePasswordProgressLogger logger( | |
| 146 password_manager->client()->GetLogManager()); | |
| 147 logger.LogMessage( | |
| 148 autofill::SavePasswordProgressLogger::STRING_SHOW_LOGIN_PROMPT_METHOD); | |
| 149 } | |
| 150 | |
| 151 PasswordForm observed_form( | |
| 152 MakeInputForPasswordManager(request_url, auth_info)); | |
| 153 handler->BuildViewWithPasswordManager(authority, explanation, | |
| 154 password_manager, observed_form); | |
| 155 } | |
| 156 | |
| 157 } // namespace | 69 } // namespace |
| 158 | 70 |
| 159 // ---------------------------------------------------------------------------- | 71 // ---------------------------------------------------------------------------- |
| 160 // LoginHandler | 72 // LoginHandler |
| 161 | 73 |
| 162 LoginHandler::LoginModelData::LoginModelData( | 74 LoginHandler::LoginModelData::LoginModelData( |
| 163 password_manager::LoginModel* login_model, | 75 password_manager::LoginModel* login_model, |
| 164 const autofill::PasswordForm& observed_form) | 76 const autofill::PasswordForm& observed_form) |
| 165 : model(login_model), form(observed_form) { | 77 : model(login_model), form(observed_form) { |
| 166 DCHECK(model); | 78 DCHECK(model); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 } | 417 } |
| 506 | 418 |
| 507 // Closes the view_contents from the UI loop. | 419 // Closes the view_contents from the UI loop. |
| 508 void LoginHandler::CloseContentsDeferred() { | 420 void LoginHandler::CloseContentsDeferred() { |
| 509 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 421 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 510 CloseDialog(); | 422 CloseDialog(); |
| 511 if (interstitial_delegate_) | 423 if (interstitial_delegate_) |
| 512 interstitial_delegate_->Proceed(); | 424 interstitial_delegate_->Proceed(); |
| 513 } | 425 } |
| 514 | 426 |
| 515 // This callback is run on the UI thread and creates a constrained window with | 427 // static |
| 516 // a LoginView to prompt the user. If the prompt is triggered because of | 428 std::string LoginHandler::GetSignonRealm( |
| 517 // a cross origin navigation in the main frame, a blank interstitial is first | 429 const GURL& url, |
| 518 // created which in turn creates the LoginView. Otherwise, a LoginView is | 430 const net::AuthChallengeInfo& auth_info) { |
| 519 // directly in this callback. In both cases, the response will be sent to | 431 std::string signon_realm; |
| 520 // LoginHandler, which then routes it to the net::URLRequest on the I/O thread. | 432 if (auth_info.is_proxy) { |
| 521 void LoginDialogCallback(const GURL& request_url, | 433 // Historically we've been storing the signon realm for proxies using |
| 522 net::AuthChallengeInfo* auth_info, | 434 // net::HostPortPair::ToString(). |
| 523 LoginHandler* handler, | 435 net::HostPortPair host_port_pair = |
| 524 bool is_main_frame) { | 436 net::HostPortPair::FromURL(GURL(auth_info.challenger.Serialize())); |
| 437 signon_realm = host_port_pair.ToString(); | |
| 438 signon_realm.append("/"); | |
| 439 } else { | |
| 440 // Take scheme, host, and port from the url. | |
| 441 signon_realm = url.GetOrigin().spec(); | |
| 442 // This ends with a "/". | |
| 443 } | |
| 444 signon_realm.append(auth_info.realm); | |
| 445 return signon_realm; | |
| 446 } | |
| 447 | |
| 448 // static | |
| 449 PasswordForm LoginHandler::MakeInputForPasswordManager( | |
| 450 const GURL& request_url, | |
| 451 const net::AuthChallengeInfo& auth_info) { | |
| 452 PasswordForm dialog_form; | |
| 453 if (base::LowerCaseEqualsASCII(auth_info.scheme, net::kBasicAuthScheme)) { | |
| 454 dialog_form.scheme = PasswordForm::SCHEME_BASIC; | |
| 455 } else if (base::LowerCaseEqualsASCII(auth_info.scheme, | |
| 456 net::kDigestAuthScheme)) { | |
| 457 dialog_form.scheme = PasswordForm::SCHEME_DIGEST; | |
| 458 } else { | |
| 459 dialog_form.scheme = PasswordForm::SCHEME_OTHER; | |
| 460 } | |
| 461 if (auth_info.is_proxy) { | |
| 462 dialog_form.origin = GURL(auth_info.challenger.Serialize()); | |
| 463 } else if (auth_info.challenger != url::Origin(request_url)) { | |
|
meacer
2016/06/16 01:12:14
Why not use !IsSameOrigin here? It sounds a bit he
asanka
2016/06/16 16:25:47
The addition of the operator follows the style gui
| |
| 464 dialog_form.origin = GURL(); | |
| 465 NOTREACHED(); // crbug.com/32718 | |
| 466 } else { | |
| 467 dialog_form.origin = GURL(auth_info.challenger.Serialize()); | |
| 468 } | |
| 469 dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, auth_info); | |
| 470 return dialog_form; | |
| 471 } | |
| 472 | |
| 473 // static | |
| 474 void LoginHandler::GetDialogStrings(const GURL& request_url, | |
| 475 const net::AuthChallengeInfo& auth_info, | |
| 476 base::string16* authority, | |
| 477 base::string16* explanation) { | |
| 478 GURL authority_url; | |
| 479 | |
| 480 if (auth_info.is_proxy) { | |
| 481 *authority = l10n_util::GetStringFUTF16( | |
| 482 IDS_LOGIN_DIALOG_PROXY_AUTHORITY, | |
| 483 url_formatter::FormatOriginForSecurityDisplay( | |
| 484 auth_info.challenger, url_formatter::SchemeDisplay::SHOW)); | |
| 485 authority_url = GURL(auth_info.challenger.Serialize()); | |
| 486 } else { | |
| 487 *authority = l10n_util::GetStringFUTF16( | |
| 488 IDS_LOGIN_DIALOG_AUTHORITY, | |
| 489 url_formatter::FormatUrlForSecurityDisplay(request_url)); | |
| 490 authority_url = request_url; | |
| 491 } | |
| 492 | |
| 493 if (!content::IsOriginSecure(authority_url)) { | |
| 494 // TODO(asanka): The string should be different for proxies and servers. | |
|
vabr (Chromium)
2016/06/15 08:50:06
nit: Could you please make this a TODO(crbug.com/X
asanka
2016/06/16 16:25:47
Added one. The plan is to pretty much fix it immed
vabr (Chromium)
2016/06/16 16:43:21
Acknowledged.
| |
| 495 *explanation = | |
| 496 l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_NON_SECURE_TRANSPORT); | |
| 497 } else { | |
| 498 explanation->clear(); | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 // static | |
| 503 void LoginHandler::ShowLoginPrompt(const GURL& request_url, | |
| 504 net::AuthChallengeInfo* auth_info, | |
| 505 LoginHandler* handler) { | |
| 506 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 507 WebContents* parent_contents = handler->GetWebContentsForLogin(); | |
| 508 if (!parent_contents) | |
| 509 return; | |
| 510 prerender::PrerenderContents* prerender_contents = | |
| 511 prerender::PrerenderContents::FromWebContents(parent_contents); | |
| 512 if (prerender_contents) { | |
| 513 prerender_contents->Destroy(prerender::FINAL_STATUS_AUTH_NEEDED); | |
| 514 return; | |
| 515 } | |
| 516 | |
| 517 base::string16 authority; | |
| 518 base::string16 explanation; | |
| 519 GetDialogStrings(request_url, *auth_info, &authority, &explanation); | |
| 520 | |
| 521 password_manager::PasswordManager* password_manager = | |
| 522 handler->GetPasswordManagerForLogin(); | |
| 523 | |
| 524 if (!password_manager) { | |
| 525 #if defined(ENABLE_EXTENSIONS) | |
| 526 // A WebContents in a <webview> (a GuestView type) does not have a password | |
| 527 // manager, but still needs to be able to show login prompts. | |
| 528 const auto* guest = | |
| 529 guest_view::GuestViewBase::FromWebContents(parent_contents); | |
| 530 if (guest && | |
| 531 extensions::GetViewType(guest->owner_web_contents()) != | |
| 532 extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
| 533 handler->BuildViewWithoutPasswordManager(authority, explanation); | |
| 534 return; | |
| 535 } | |
| 536 #endif | |
| 537 handler->CancelAuth(); | |
| 538 return; | |
| 539 } | |
| 540 | |
| 541 if (password_manager && | |
| 542 password_manager->client()->GetLogManager()->IsLoggingActive()) { | |
| 543 password_manager::BrowserSavePasswordProgressLogger logger( | |
| 544 password_manager->client()->GetLogManager()); | |
| 545 logger.LogMessage( | |
| 546 autofill::SavePasswordProgressLogger::STRING_SHOW_LOGIN_PROMPT_METHOD); | |
| 547 } | |
| 548 | |
| 549 PasswordForm observed_form( | |
| 550 LoginHandler::MakeInputForPasswordManager(request_url, *auth_info)); | |
| 551 handler->BuildViewWithPasswordManager(authority, explanation, | |
| 552 password_manager, observed_form); | |
| 553 } | |
| 554 | |
| 555 // static | |
| 556 void LoginHandler::LoginDialogCallback(const GURL& request_url, | |
| 557 net::AuthChallengeInfo* auth_info, | |
| 558 LoginHandler* handler, | |
| 559 bool is_main_frame) { | |
| 525 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 560 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 526 WebContents* parent_contents = handler->GetWebContentsForLogin(); | 561 WebContents* parent_contents = handler->GetWebContentsForLogin(); |
| 527 if (!parent_contents || handler->WasAuthHandled()) { | 562 if (!parent_contents || handler->WasAuthHandled()) { |
| 528 // The request may have been canceled, or it may be for a renderer not | 563 // The request may have been canceled, or it may be for a renderer not |
| 529 // hosted by a tab (e.g. an extension). Cancel just in case (canceling twice | 564 // hosted by a tab (e.g. an extension). Cancel just in case (canceling twice |
| 530 // is a no-op). | 565 // is a no-op). |
| 531 handler->CancelAuth(); | 566 handler->CancelAuth(); |
| 532 return; | 567 return; |
| 533 } | 568 } |
| 534 | 569 |
| 535 // Check if this is a main frame navigation and | 570 // Check if this is a main frame navigation and |
| 536 // (a) if the request is cross origin or | 571 // (a) if the request is cross origin or |
| 537 // (b) if an interstitial is already being shown. | 572 // (b) if an interstitial is already being shown. |
| 538 // | 573 // |
| 539 // For (a), there are two different ways the navigation can occur: | 574 // For (a), there are two different ways the navigation can occur: |
| 540 // 1- The user enters the resource URL in the omnibox. | 575 // 1- The user enters the resource URL in the omnibox. |
| 541 // 2- The page redirects to the resource. | 576 // 2- The page redirects to the resource. |
| 542 // In both cases, the last committed URL is different than the resource URL, | 577 // In both cases, the last committed URL is different than the resource URL, |
| 543 // so checking it is sufficient. | 578 // so checking it is sufficient. |
| 544 // Note that (1) will not be true once site isolation is enabled, as any | 579 // Note that (1) will not be true once site isolation is enabled, as any |
| 545 // navigation could cause a cross-process swap, including link clicks. | 580 // navigation could cause a cross-process swap, including link clicks. |
| 546 // | 581 // |
| 547 // For (b), the login interstitial should always replace an existing | 582 // For (b), the login interstitial should always replace an existing |
| 548 // interstitial. This is because |LoginHandler::CloseContentsDeferred| tries | 583 // interstitial. This is because |LoginHandler::CloseContentsDeferred| tries |
| 549 // to proceed whatever interstitial is being shown when the login dialog is | 584 // to proceed whatever interstitial is being shown when the login dialog is |
| 550 // closed, so that interstitial should only be a login interstitial. | 585 // closed, so that interstitial should only be a login interstitial. |
| 551 if (is_main_frame && (parent_contents->ShowingInterstitialPage() || | 586 if (is_main_frame && |
| 552 parent_contents->GetLastCommittedURL().GetOrigin() != | 587 (parent_contents->ShowingInterstitialPage() || auth_info->is_proxy || |
|
meacer
2016/06/16 01:12:14
nit: Can you update the comment above and add the
asanka
2016/06/16 16:25:47
Done. Thanks, missed the comment in the first pass
| |
| 553 request_url.GetOrigin())) { | 588 parent_contents->GetLastCommittedURL().GetOrigin() != |
| 589 request_url.GetOrigin())) { | |
| 554 // Show a blank interstitial for main-frame, cross origin requests | 590 // Show a blank interstitial for main-frame, cross origin requests |
| 555 // so that the correct URL is shown in the omnibox. | 591 // so that the correct URL is shown in the omnibox. |
| 556 base::Closure callback = | 592 base::Closure callback = |
| 557 base::Bind(&ShowLoginPrompt, request_url, base::RetainedRef(auth_info), | 593 base::Bind(&LoginHandler::ShowLoginPrompt, request_url, |
| 558 base::RetainedRef(handler)); | 594 base::RetainedRef(auth_info), base::RetainedRef(handler)); |
| 559 // The interstitial delegate is owned by the interstitial that it creates. | 595 // The interstitial delegate is owned by the interstitial that it creates. |
| 560 // This cancels any existing interstitial. | 596 // This cancels any existing interstitial. |
| 561 handler->SetInterstitialDelegate( | 597 handler->SetInterstitialDelegate( |
| 562 (new LoginInterstitialDelegate(parent_contents, request_url, callback)) | 598 (new LoginInterstitialDelegate( |
| 599 parent_contents, auth_info->is_proxy ? GURL() : request_url, | |
| 600 callback)) | |
| 563 ->GetWeakPtr()); | 601 ->GetWeakPtr()); |
| 564 } else { | 602 } else { |
| 565 ShowLoginPrompt(request_url, auth_info, handler); | 603 ShowLoginPrompt(request_url, auth_info, handler); |
| 566 } | 604 } |
| 567 } | 605 } |
| 568 | 606 |
| 569 // ---------------------------------------------------------------------------- | 607 // ---------------------------------------------------------------------------- |
| 570 // Public API | 608 // Public API |
| 571 | 609 |
| 572 LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info, | 610 LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info, |
| 573 net::URLRequest* request) { | 611 net::URLRequest* request) { |
| 574 bool is_main_frame = (request->load_flags() & net::LOAD_MAIN_FRAME) != 0; | 612 bool is_main_frame = (request->load_flags() & net::LOAD_MAIN_FRAME) != 0; |
| 575 LoginHandler* handler = LoginHandler::Create(auth_info, request); | 613 LoginHandler* handler = LoginHandler::Create(auth_info, request); |
| 576 BrowserThread::PostTask( | 614 BrowserThread::PostTask( |
| 577 BrowserThread::UI, FROM_HERE, | 615 BrowserThread::UI, FROM_HERE, |
| 578 base::Bind(&LoginDialogCallback, request->url(), | 616 base::Bind(&LoginHandler::LoginDialogCallback, request->url(), |
| 579 base::RetainedRef(auth_info), base::RetainedRef(handler), | 617 base::RetainedRef(auth_info), base::RetainedRef(handler), |
| 580 is_main_frame)); | 618 is_main_frame)); |
| 581 return handler; | 619 return handler; |
| 582 } | 620 } |
| 583 | 621 |
| 584 // Get the signon_realm under which this auth info should be stored. | |
| 585 // | |
| 586 // The format of the signon_realm for proxy auth is: | |
| 587 // proxy-host/auth-realm | |
| 588 // The format of the signon_realm for server auth is: | |
| 589 // url-scheme://url-host[:url-port]/auth-realm | |
| 590 // | |
| 591 // Be careful when changing this function, since you could make existing | |
| 592 // saved logins un-retrievable. | |
| 593 std::string GetSignonRealm(const GURL& url, | |
| 594 const net::AuthChallengeInfo& auth_info) { | |
| 595 std::string signon_realm; | |
| 596 if (auth_info.is_proxy) { | |
| 597 signon_realm = auth_info.challenger.ToString(); | |
| 598 signon_realm.append("/"); | |
| 599 } else { | |
| 600 // Take scheme, host, and port from the url. | |
| 601 signon_realm = url.GetOrigin().spec(); | |
| 602 // This ends with a "/". | |
| 603 } | |
| 604 signon_realm.append(auth_info.realm); | |
| 605 return signon_realm; | |
| 606 } | |
| OLD | NEW |