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

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

Issue 3360017: Fix multi-round authentication.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: SocketStream fix Created 10 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_auth_controller.h ('k') | net/http/http_auth_gssapi_posix.h » ('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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/string_util.h"
7 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
8 #include "net/base/auth.h" 9 #include "net/base/auth.h"
9 #include "net/base/host_resolver.h" 10 #include "net/base/host_resolver.h"
10 #include "net/base/net_util.h" 11 #include "net/base/net_util.h"
11 #include "net/http/http_auth_handler.h" 12 #include "net/http/http_auth_handler.h"
12 #include "net/http/http_auth_handler_factory.h" 13 #include "net/http/http_auth_handler_factory.h"
13 #include "net/http/http_network_session.h" 14 #include "net/http/http_network_session.h"
14 #include "net/http/http_request_headers.h" 15 #include "net/http/http_request_headers.h"
15 #include "net/http/http_request_info.h" 16 #include "net/http/http_request_info.h"
16 #include "net/http/http_response_headers.h" 17 #include "net/http/http_response_headers.h"
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 auth_token_.clear(); 145 auth_token_.clear();
145 } 146 }
146 147
147 int HttpAuthController::HandleAuthChallenge( 148 int HttpAuthController::HandleAuthChallenge(
148 scoped_refptr<HttpResponseHeaders> headers, 149 scoped_refptr<HttpResponseHeaders> headers,
149 bool do_not_send_server_auth, 150 bool do_not_send_server_auth,
150 bool establishing_tunnel, 151 bool establishing_tunnel,
151 const BoundNetLog& net_log) { 152 const BoundNetLog& net_log) {
152 DCHECK(headers); 153 DCHECK(headers);
153 DCHECK(auth_origin_.is_valid()); 154 DCHECK(auth_origin_.is_valid());
154
155 LOG(INFO) << "The " << HttpAuth::GetAuthTargetString(target_) << " " 155 LOG(INFO) << "The " << HttpAuth::GetAuthTargetString(target_) << " "
156 << auth_origin_ << " requested auth" 156 << auth_origin_ << " requested auth"
157 << AuthChallengeLogMessage(headers.get()); 157 << AuthChallengeLogMessage(headers.get());
158 158
159 // The auth we tried just failed, hence it can't be valid. Remove it from 159 // Give the existing auth handler first try at the authentication headers.
160 // the cache so it won't be used again. 160 // This will also evict the entry in the HttpAuthCache if the previous
161 // TODO(wtc): IsFinalRound is not the right condition. In a multi-round 161 // challenge appeared to be rejected, or is using a stale nonce in the Digest
162 // auth sequence, the server may fail the auth in round 1 if our first 162 // case.
163 // authorization header is broken. We should inspect response_.headers to 163 if (HaveAuth()) {
164 // determine if the server already failed the auth or wants us to continue. 164 HttpAuth::AuthorizationResult result = HttpAuth::HandleChallengeResponse(
165 // See http://crbug.com/21015. 165 handler_.get(), headers, target_, disabled_schemes_);
166 if (HaveAuth() && handler_->IsFinalRound()) { 166 switch (result) {
167 InvalidateRejectedAuthFromCache(); 167 case HttpAuth::AUTHORIZATION_RESULT_ACCEPT:
168 handler_.reset(); 168 break;
169 identity_ = HttpAuth::Identity(); 169 case HttpAuth::AUTHORIZATION_RESULT_INVALID:
170 case HttpAuth::AUTHORIZATION_RESULT_REJECT:
171 InvalidateCurrentHandler();
172 break;
173 case HttpAuth::AUTHORIZATION_RESULT_STALE:
174 // TODO(cbentzel): Support "stale" invalidation in HttpAuthCache.
175 // Right now this does the same invalidation as before.
176 InvalidateCurrentHandler();
177 break;
178 default:
179 NOTREACHED();
180 break;
181 }
170 } 182 }
171 183
172 identity_.invalid = true; 184 identity_.invalid = true;
173 185
174 if (target_ != HttpAuth::AUTH_SERVER || !do_not_send_server_auth) { 186 bool can_send_auth = (target_ != HttpAuth::AUTH_SERVER ||
187 !do_not_send_server_auth);
188 if (!handler_.get() && can_send_auth) {
175 // Find the best authentication challenge that we support. 189 // Find the best authentication challenge that we support.
176 HttpAuth::ChooseBestChallenge(session_->http_auth_handler_factory(), 190 HttpAuth::ChooseBestChallenge(session_->http_auth_handler_factory(),
177 headers, target_, auth_origin_, 191 headers, target_, auth_origin_,
178 disabled_schemes_, net_log, 192 disabled_schemes_, net_log,
179 &handler_); 193 &handler_);
180 } 194 }
181 195
182 if (!handler_.get()) { 196 if (!handler_.get()) {
183 if (establishing_tunnel) { 197 if (establishing_tunnel) {
184 LOG(ERROR) << "Can't perform auth to the " 198 LOG(ERROR) << "Can't perform auth to the "
(...skipping 11 matching lines...) Expand all
196 // so we end up displaying the error page. 210 // so we end up displaying the error page.
197 return OK; 211 return OK;
198 } 212 }
199 213
200 if (handler_->NeedsIdentity()) { 214 if (handler_->NeedsIdentity()) {
201 // Pick a new auth identity to try, by looking to the URL and auth cache. 215 // Pick a new auth identity to try, by looking to the URL and auth cache.
202 // If an identity to try is found, it is saved to identity_. 216 // If an identity to try is found, it is saved to identity_.
203 SelectNextAuthIdentityToTry(); 217 SelectNextAuthIdentityToTry();
204 } else { 218 } else {
205 // Proceed with the existing identity or a null identity. 219 // Proceed with the existing identity or a null identity.
206 //
207 // TODO(wtc): Add a safeguard against infinite transaction restarts, if
208 // the server keeps returning "NTLM".
209 identity_.invalid = false; 220 identity_.invalid = false;
210 } 221 }
211 222
212 // From this point on, we are restartable. 223 // From this point on, we are restartable.
213 224
214 if (identity_.invalid) { 225 if (identity_.invalid) {
215 // We have exhausted all identity possibilities, all we can do now is 226 // We have exhausted all identity possibilities, all we can do now is
216 // pass the challenge information back to the client. 227 // pass the challenge information back to the client.
217 PopulateAuthChallenge(); 228 PopulateAuthChallenge();
218 } else { 229 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 break; 267 break;
257 default: 268 default:
258 session_->auth_cache()->Add(auth_origin_, handler_->realm(), 269 session_->auth_cache()->Add(auth_origin_, handler_->realm(),
259 handler_->scheme(), handler_->challenge(), 270 handler_->scheme(), handler_->challenge(),
260 identity_.username, identity_.password, 271 identity_.username, identity_.password,
261 auth_path_); 272 auth_path_);
262 break; 273 break;
263 } 274 }
264 } 275 }
265 276
277 void HttpAuthController::InvalidateCurrentHandler() {
278 InvalidateRejectedAuthFromCache();
279 handler_.reset();
280 identity_ = HttpAuth::Identity();
281 }
282
266 void HttpAuthController::InvalidateRejectedAuthFromCache() { 283 void HttpAuthController::InvalidateRejectedAuthFromCache() {
267 DCHECK(HaveAuth()); 284 DCHECK(HaveAuth());
268 285
269 // TODO(eroman): this short-circuit can be relaxed. If the realm of 286 // TODO(eroman): this short-circuit can be relaxed. If the realm of
270 // the preemptively used auth entry matches the realm of the subsequent 287 // the preemptively used auth entry matches the realm of the subsequent
271 // challenge, then we can invalidate the preemptively used entry. 288 // challenge, then we can invalidate the preemptively used entry.
272 // Otherwise as-is we may send the failed credentials one extra time. 289 // Otherwise as-is we may send the failed credentials one extra time.
273 if (identity_.source == HttpAuth::IDENT_SRC_PATH_LOOKUP) 290 if (identity_.source == HttpAuth::IDENT_SRC_PATH_LOOKUP)
274 return; 291 return;
275 292
(...skipping 19 matching lines...) Expand all
295 &identity_.username, 312 &identity_.username,
296 &identity_.password); 313 &identity_.password);
297 embedded_identity_used_ = true; 314 embedded_identity_used_ = true;
298 // TODO(eroman): If the password is blank, should we also try combining 315 // TODO(eroman): If the password is blank, should we also try combining
299 // with a password from the cache? 316 // with a password from the cache?
300 return true; 317 return true;
301 } 318 }
302 319
303 // Check the auth cache for a realm entry. 320 // Check the auth cache for a realm entry.
304 HttpAuthCache::Entry* entry = 321 HttpAuthCache::Entry* entry =
305 session_->auth_cache()->Lookup(auth_origin_, handler_->realm(), 322 session_->auth_cache()->Lookup(auth_origin_, handler_->realm(),
306 handler_->scheme()); 323 handler_->scheme());
307 324
308 if (entry) { 325 if (entry) {
309 identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP; 326 identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP;
310 identity_.invalid = false; 327 identity_.invalid = false;
311 identity_.username = entry->username(); 328 identity_.username = entry->username();
312 identity_.password = entry->password(); 329 identity_.password = entry->password();
313 return true; 330 return true;
314 } 331 }
315 332
316 // Use default credentials (single sign on) if this is the first attempt 333 // Use default credentials (single sign on) if this is the first attempt
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 378
362 bool HttpAuthController::IsAuthSchemeDisabled(const std::string& scheme) const { 379 bool HttpAuthController::IsAuthSchemeDisabled(const std::string& scheme) const {
363 return disabled_schemes_.find(scheme) != disabled_schemes_.end(); 380 return disabled_schemes_.find(scheme) != disabled_schemes_.end();
364 } 381 }
365 382
366 void HttpAuthController::DisableAuthScheme(const std::string& scheme) { 383 void HttpAuthController::DisableAuthScheme(const std::string& scheme) {
367 disabled_schemes_.insert(scheme); 384 disabled_schemes_.insert(scheme);
368 } 385 }
369 386
370 } // namespace net 387 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_controller.h ('k') | net/http/http_auth_gssapi_posix.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698