1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_HTTP_HTTP_AUTH_CONTROLLER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/non_thread_safe.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/completion_callback.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_auth.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AuthChallengeInfo; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpAuthHandler; 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass HttpAuthHandlerFactory; 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass HttpAuthCache; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpRequestHeaders; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct HttpRequestInfo; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass HttpAuthController : public base::RefCounted<HttpAuthController>, 323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen public base::NonThreadSafe { 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The arguments are self explanatory except possibly for |auth_url|, which 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should be both the auth target and auth path in a single url argument. 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthController(HttpAuth::Target target, 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GURL& auth_url, 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthCache* http_auth_cache, 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthHandlerFactory* http_auth_handler_factory); 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Generate an authentication token for |target| if necessary. The return 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // value is a net error code. |OK| will be returned both in the case that 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a token is correctly generated synchronously, as well as when no tokens 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // were necessary. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int MaybeGenerateAuthToken(const HttpRequestInfo* request, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Adds either the proxy auth header, or the origin server auth header, 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // as specified by |target_|. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void AddAuthorizationHeader( 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestHeaders* authorization_headers); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Checks for and handles HTTP status code 401 or 407. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |HandleAuthChallenge()| returns OK on success, or a network error code 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // otherwise. It may also populate |auth_info_|. 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers, 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool do_not_send_server_auth, 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool establishing_tunnel, 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Store the supplied credentials and prepare to restart the auth. 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void ResetAuth(const string16& username, 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& password); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual bool HaveAuthHandler() const; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual bool HaveAuth() const; 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual scoped_refptr<AuthChallengeInfo> auth_info(); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const; 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void DisableAuthScheme(HttpAuth::Scheme scheme); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Actions for InvalidateCurrentHandler() 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen enum InvalidateHandlerAction { 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen INVALIDATE_HANDLER 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen }; 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // So that we can mock this object. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class base::RefCounted<HttpAuthController>; 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~HttpAuthController(); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Searches the auth cache for an entry that encompasses the request's path. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If such an entry is found, updates |identity_| and |handler_| with the 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // cache entry's data and returns true. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool SelectPreemptiveAuth(const BoundNetLog& net_log); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Invalidates the current handler. If |action| is 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // the cached credentials used by the handler. 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void InvalidateCurrentHandler(InvalidateHandlerAction action); 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Invalidates any auth cache entries after authentication has failed. 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The identity that was rejected is |identity_|. 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void InvalidateRejectedAuthFromCache(); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sets |identity_| to the next identity that the transaction should try. It 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // chooses candidates by searching the auth cache and the URL for a 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // username:password. Returns true if an identity was found. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool SelectNextAuthIdentityToTry(); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Populates auth_info_ with the challenge information, so that 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URLRequestHttpJob can prompt for a username/password. 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void PopulateAuthChallenge(); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If |result| indicates a permanent failure, disables the current 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // auth scheme for this controller and returns true. Returns false 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // otherwise. 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool DisableOnAuthHandlerResult(int result); 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnIOComplete(int result); 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Indicates if this handler is for Proxy auth or Server auth. 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuth::Target target_; 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Holds the {scheme, host, path, port} for the authentication target. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL auth_url_; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Holds the {scheme, host, port} for the authentication target. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL auth_origin_; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The absolute path of the resource needing authentication. 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For proxy authentication the path is empty. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string auth_path_; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |handler_| encapsulates the logic for the particular auth-scheme. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This includes the challenge's parameters. If NULL, then there is no 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // associated auth handler. 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpAuthHandler> handler_; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |identity_| holds the (username/password) that should be used by 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the handler_ to generate credentials. This identity can come from 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a number of places (url, cache, prompt). 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuth::Identity identity_; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |auth_token_| contains the opaque string to pass to the proxy or 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // server to authenticate the client. 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string auth_token_; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Contains information about the auth challenge. 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<AuthChallengeInfo> auth_info_; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // True if we've used the username/password embedded in the URL. This 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // makes sure we use the embedded identity only once for the transaction, 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // preventing an infinite auth restart loop. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool embedded_identity_used_; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // True if default credentials have already been tried for this transaction 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in response to an HTTP authentication challenge. 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool default_credentials_used_; 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // These two are owned by the HttpNetworkSession/IOThread, which own the 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // objects which reference |this|. Therefore, these raw pointers are valid 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // for the lifetime of this object. 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthCache* const http_auth_cache_; 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthHandlerFactory* const http_auth_handler_factory_; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::set<HttpAuth::Scheme> disabled_schemes_; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallbackImpl<HttpAuthController> io_callback_; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* user_callback_; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // NET_HTTP_HTTP_AUTH_CONTROLLER_H_ 171