Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(636)

Side by Side Diff: net/http/http_auth_controller.cc

Issue 2518633002: [Merge M55] [net/auth] Deal better with ERR_INVALID_AUTH_CREDENTIALS error. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_auth_controller.h ('k') | net/http/http_auth_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "net/http/http_auth_controller.h" 5 #include "net/http/http_auth_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 bool needs_auth = HaveAuth() || SelectPreemptiveAuth(net_log); 149 bool needs_auth = HaveAuth() || SelectPreemptiveAuth(net_log);
150 if (!needs_auth) 150 if (!needs_auth)
151 return OK; 151 return OK;
152 const AuthCredentials* credentials = NULL; 152 const AuthCredentials* credentials = NULL;
153 if (identity_.source != HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS) 153 if (identity_.source != HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS)
154 credentials = &identity_.credentials; 154 credentials = &identity_.credentials;
155 DCHECK(auth_token_.empty()); 155 DCHECK(auth_token_.empty());
156 DCHECK(callback_.is_null()); 156 DCHECK(callback_.is_null());
157 int rv = handler_->GenerateAuthToken( 157 int rv = handler_->GenerateAuthToken(
158 credentials, request, 158 credentials, request,
159 base::Bind(&HttpAuthController::OnIOComplete, base::Unretained(this)), 159 base::Bind(&HttpAuthController::OnGenerateAuthTokenDone,
160 base::Unretained(this)),
160 &auth_token_); 161 &auth_token_);
161 if (DisableOnAuthHandlerResult(rv)) 162
162 rv = OK; 163 if (rv == ERR_IO_PENDING) {
163 if (rv == ERR_IO_PENDING)
164 callback_ = callback; 164 callback_ = callback;
165 else 165 return rv;
166 OnIOComplete(rv); 166 }
167 return rv; 167
168 return HandleGenerateTokenResult(rv);
168 } 169 }
169 170
170 bool HttpAuthController::SelectPreemptiveAuth(const NetLogWithSource& net_log) { 171 bool HttpAuthController::SelectPreemptiveAuth(const NetLogWithSource& net_log) {
171 DCHECK(CalledOnValidThread()); 172 DCHECK(CalledOnValidThread());
172 DCHECK(!HaveAuth()); 173 DCHECK(!HaveAuth());
173 DCHECK(identity_.invalid); 174 DCHECK(identity_.invalid);
174 175
175 // Don't do preemptive authorization if the URL contains a username:password, 176 // Don't do preemptive authorization if the URL contains a username:password,
176 // since we must first be challenged in order to use the URL's identity. 177 // since we must first be challenged in order to use the URL's identity.
177 if (auth_url_.has_username()) 178 if (auth_url_.has_username())
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 // Populates response_.auth_challenge with the authentication challenge info. 465 // Populates response_.auth_challenge with the authentication challenge info.
465 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo(). 466 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo().
466 467
467 auth_info_ = new AuthChallengeInfo; 468 auth_info_ = new AuthChallengeInfo;
468 auth_info_->is_proxy = (target_ == HttpAuth::AUTH_PROXY); 469 auth_info_->is_proxy = (target_ == HttpAuth::AUTH_PROXY);
469 auth_info_->challenger = url::Origin(auth_origin_); 470 auth_info_->challenger = url::Origin(auth_origin_);
470 auth_info_->scheme = HttpAuth::SchemeToString(handler_->auth_scheme()); 471 auth_info_->scheme = HttpAuth::SchemeToString(handler_->auth_scheme());
471 auth_info_->realm = handler_->realm(); 472 auth_info_->realm = handler_->realm();
472 } 473 }
473 474
474 bool HttpAuthController::DisableOnAuthHandlerResult(int result) { 475 int HttpAuthController::HandleGenerateTokenResult(int result) {
475 DCHECK(CalledOnValidThread()); 476 DCHECK(CalledOnValidThread());
477 switch (result) {
478 // Occurs if the credential handle is found to be invalid at the point it is
479 // exercised (i.e. GenerateAuthToken stage). We are going to consider this
480 // to be an error that invalidates the identity but not necessarily the
481 // scheme. Doing so allows a different identity to be used with the same
482 // scheme. See https://crbug.com/648366.
483 case ERR_INVALID_HANDLE:
476 484
477 switch (result) { 485 // If the GenerateAuthToken call fails with this error, this means that the
486 // handler can no longer be used. However, the authentication scheme is
487 // considered still usable. This allows a scheme that attempted and failed
488 // to use default credentials to recover and use explicit credentials.
489 //
490 // The current handler may be tied to external state that is no longer
491 // valid, hence should be discarded. Since the scheme is still valid, a new
492 // handler can be created for the current scheme.
493 case ERR_INVALID_AUTH_CREDENTIALS:
494 InvalidateCurrentHandler(INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS);
495 auth_token_.clear();
496 return OK;
497
478 // Occurs with GSSAPI, if the user has not already logged in. 498 // Occurs with GSSAPI, if the user has not already logged in.
479 case ERR_MISSING_AUTH_CREDENTIALS: 499 case ERR_MISSING_AUTH_CREDENTIALS:
480 500
481 // Can occur with GSSAPI or SSPI if the underlying library reports 501 // Can occur with GSSAPI or SSPI if the underlying library reports
482 // a permanent error. 502 // a permanent error.
483 case ERR_UNSUPPORTED_AUTH_SCHEME: 503 case ERR_UNSUPPORTED_AUTH_SCHEME:
484 504
485 // These two error codes represent failures we aren't handling. 505 // These two error codes represent failures we aren't handling.
486 case ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS: 506 case ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS:
487 case ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS: 507 case ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS:
488 508
489 // Can be returned by SSPI if the authenticating authority or 509 // Can be returned by SSPI if the authenticating authority or
490 // target is not known. 510 // target is not known.
491 case ERR_MISCONFIGURED_AUTH_ENVIRONMENT: 511 case ERR_MISCONFIGURED_AUTH_ENVIRONMENT:
492 512
493 // In these cases, disable the current scheme as it cannot 513 // In these cases, disable the current scheme as it cannot
494 // succeed. 514 // succeed.
495 DisableAuthScheme(handler_->auth_scheme()); 515 InvalidateCurrentHandler(INVALIDATE_HANDLER_AND_DISABLE_SCHEME);
496 auth_token_.clear(); 516 auth_token_.clear();
497 return true; 517 return OK;
498 518
499 default: 519 default:
500 return false; 520 return result;
501 } 521 }
502 } 522 }
503 523
504 void HttpAuthController::OnIOComplete(int result) { 524 void HttpAuthController::OnGenerateAuthTokenDone(int result) {
505 DCHECK(CalledOnValidThread()); 525 DCHECK(CalledOnValidThread());
506 if (DisableOnAuthHandlerResult(result)) 526 result = HandleGenerateTokenResult(result);
507 result = OK;
508 if (!callback_.is_null()) { 527 if (!callback_.is_null()) {
509 CompletionCallback c = callback_; 528 CompletionCallback c = callback_;
510 callback_.Reset(); 529 callback_.Reset();
511 c.Run(result); 530 c.Run(result);
512 } 531 }
513 } 532 }
514 533
515 scoped_refptr<AuthChallengeInfo> HttpAuthController::auth_info() { 534 scoped_refptr<AuthChallengeInfo> HttpAuthController::auth_info() {
516 DCHECK(CalledOnValidThread()); 535 DCHECK(CalledOnValidThread());
517 return auth_info_; 536 return auth_info_;
518 } 537 }
519 538
520 bool HttpAuthController::IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const { 539 bool HttpAuthController::IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const {
521 DCHECK(CalledOnValidThread()); 540 DCHECK(CalledOnValidThread());
522 return disabled_schemes_.find(scheme) != disabled_schemes_.end(); 541 return disabled_schemes_.find(scheme) != disabled_schemes_.end();
523 } 542 }
524 543
525 void HttpAuthController::DisableAuthScheme(HttpAuth::Scheme scheme) { 544 void HttpAuthController::DisableAuthScheme(HttpAuth::Scheme scheme) {
526 DCHECK(CalledOnValidThread()); 545 DCHECK(CalledOnValidThread());
527 disabled_schemes_.insert(scheme); 546 disabled_schemes_.insert(scheme);
528 } 547 }
529 548
530 void HttpAuthController::DisableEmbeddedIdentity() { 549 void HttpAuthController::DisableEmbeddedIdentity() {
531 DCHECK(CalledOnValidThread()); 550 DCHECK(CalledOnValidThread());
532 embedded_identity_used_ = true; 551 embedded_identity_used_ = true;
533 } 552 }
534 553
535 } // namespace net 554 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_controller.h ('k') | net/http/http_auth_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698