| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_ | 5 #ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| 6 #define NET_HTTP_HTTP_AUTH_CONTROLLER_H_ | 6 #define NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| 7 | 7 |
| 8 #include <queue> |
| 8 #include <set> | 9 #include <set> |
| 9 #include <string> | 10 #include <string> |
| 10 | 11 |
| 11 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 13 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/memory/weak_ptr.h" |
| 14 #include "base/threading/non_thread_safe.h" | 16 #include "base/threading/non_thread_safe.h" |
| 15 #include "net/base/completion_callback.h" | 17 #include "net/base/completion_callback.h" |
| 16 #include "net/base/net_export.h" | 18 #include "net/base/net_export.h" |
| 17 #include "net/http/http_auth.h" | 19 #include "net/http/http_auth.h" |
| 18 #include "net/http/http_auth_scheme_set.h" | 20 #include "net/http/http_auth_scheme_set.h" |
| 19 #include "net/log/net_log.h" | 21 #include "net/log/net_log.h" |
| 20 #include "url/gurl.h" | 22 #include "url/gurl.h" |
| 21 | 23 |
| 22 namespace net { | 24 namespace net { |
| 23 | 25 |
| 24 class AuthChallengeInfo; | 26 class AuthChallengeInfo; |
| 25 class AuthCredentials; | 27 class AuthCredentials; |
| 26 class HttpAuthHandler; | 28 class HttpAuthHandler; |
| 27 class HttpAuthHandlerFactory; | 29 class HttpAuthHandlerFactory; |
| 28 class HttpAuthCache; | 30 class HttpAuthCache; |
| 29 class HttpRequestHeaders; | 31 class HttpRequestHeaders; |
| 30 struct HttpRequestInfo; | 32 struct HttpRequestInfo; |
| 33 class HttpResponseInfo; |
| 31 | 34 |
| 35 // HttpAuthController handles HTTP authentication for a single authentication |
| 36 // target during a network transaction. An authentication target is a single |
| 37 // proxy server or a single protection space for an HTTP server as defined in |
| 38 // http://tools.ietf.org/html/rfc7235#section-2.2. |
| 32 class NET_EXPORT_PRIVATE HttpAuthController | 39 class NET_EXPORT_PRIVATE HttpAuthController |
| 33 : public base::RefCounted<HttpAuthController>, | 40 : public base::RefCounted<HttpAuthController>, |
| 34 NON_EXPORTED_BASE(public base::NonThreadSafe) { | 41 NON_EXPORTED_BASE(public base::NonThreadSafe) { |
| 35 public: | 42 public: |
| 36 // The arguments are self explanatory except possibly for |auth_url|, which | 43 // |http_auth_cache| and |http_auth_handler_factory| should remain valid for |
| 37 // should be both the auth target and auth path in a single url argument. | 44 // the lifetime of the HttpAuthController. |
| 38 HttpAuthController(HttpAuth::Target target, | 45 HttpAuthController(HttpAuth::Target target, |
| 39 const GURL& auth_url, | 46 const GURL& auth_url, |
| 40 HttpAuthCache* http_auth_cache, | 47 HttpAuthCache* http_auth_cache, |
| 41 HttpAuthHandlerFactory* http_auth_handler_factory); | 48 HttpAuthHandlerFactory* http_auth_handler_factory); |
| 42 | 49 |
| 43 // Generate an authentication token for |target| if necessary. The return | 50 // Generate an authentication token for |target| if necessary. The return |
| 44 // value is a net error code. |OK| will be returned both in the case that | 51 // value is a net error code. |OK| will be returned both in the case that |
| 45 // a token is correctly generated synchronously, as well as when no tokens | 52 // a token is correctly generated synchronously, as well as when no tokens |
| 46 // were necessary. | 53 // were necessary. |
| 47 virtual int MaybeGenerateAuthToken(const HttpRequestInfo* request, | 54 // TODO(asanka): Move towards model of generating tokens during |
| 48 const CompletionCallback& callback, | 55 // HandleAuthChallenge() and after ResetAuth() rather than just before sending |
| 49 const BoundNetLog& net_log); | 56 // a new request. |
| 57 int MaybeGenerateAuthToken(const HttpRequestInfo* request, |
| 58 const CompletionCallback& callback, |
| 59 const BoundNetLog& net_log); |
| 60 |
| 61 // Checks for and handles HTTP authentication challenge headers appropriate |
| 62 // for |target_|. Returns OK on success. If the operation will be blocking, |
| 63 // returns ERR_IO_PENDING and invokes |callback| with the result. Returns a |
| 64 // network error code on failure (either synchronously, or via |callback|). |
| 65 // |
| 66 // The initial invocation of HandleAuthChallenge() must specify a |response| |
| 67 // containing an authentication challenge appropriate for the authentication |
| 68 // target (i.e. a 401 for AUTH_SERVER and 407 for AUTH_PROXY). Subsequent |
| 69 // calls to HandleAuthChallenge() must specify in |response| the server |
| 70 // response obtained after sending the request generated by |
| 71 // MaybeGenerateAuthToken() and AddAuthorizationHeader(). |
| 72 // |
| 73 // After a successful call: |
| 74 // * HaveAuthHandler() => |
| 75 // A suitable handler was found that can respond to the challenge. |
| 76 // |
| 77 // If HaveAuthHandler() is false, then HttpAuthController can't respond |
| 78 // to the challenge. |
| 79 // |
| 80 // * HaveAuth() => |
| 81 // A suitable handler was found and a suitable identity is available to |
| 82 // proceed with responding to the authentication challenge. |
| 83 // MaybeGenerateAuthToken() is likely to successfully generate a token. |
| 84 // |
| 85 // If HaveAuth() is false, then auth_info() will return an |
| 86 // AuthChallengeInfo that can be used to inform the acquisition of |
| 87 // credentials from an external source (e.g. by prompting the user). |
| 88 // Once credentials are available, call ResetAuth(). |
| 89 int HandleAuthChallenge(const HttpResponseInfo& response, |
| 90 const CompletionCallback& callback, |
| 91 const BoundNetLog& net_log); |
| 50 | 92 |
| 51 // Adds either the proxy auth header, or the origin server auth header, | 93 // Adds either the proxy auth header, or the origin server auth header, |
| 52 // as specified by |target_|. | 94 // as specified by |target_|. |
| 53 virtual void AddAuthorizationHeader( | 95 void AddAuthorizationHeader(HttpRequestHeaders* authorization_headers); |
| 54 HttpRequestHeaders* authorization_headers); | |
| 55 | 96 |
| 56 // Checks for and handles HTTP status code 401 or 407. | 97 // Store the supplied |credentials| for use with the next invocation of |
| 57 // |HandleAuthChallenge()| returns OK on success, or a network error code | 98 // MaybeGenerateAuthToken(). In addition, the credentials will also be stored |
| 58 // otherwise. It may also populate |auth_info_|. | 99 // in the |http_auth_cache| that was passed into the constructor, potentially |
| 59 virtual int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers, | 100 // making it available for other HttpAuthControllers. |
| 60 bool do_not_send_server_auth, | 101 // TODO(asanka): Rename to SetCredentials(). |
| 61 bool establishing_tunnel, | 102 void ResetAuth(const AuthCredentials& credentials); |
| 62 const BoundNetLog& net_log); | |
| 63 | 103 |
| 64 // Store the supplied credentials and prepare to restart the auth. | 104 // Returns whether this HttpAuthController has an active HttpAuthHandler. |
| 65 virtual void ResetAuth(const AuthCredentials& credentials); | 105 bool HaveAuthHandler() const; |
| 66 | 106 |
| 67 virtual bool HaveAuthHandler() const; | 107 // Returns |true| if the HttpAuthController is ready to generate an |
| 108 // authentication token. |
| 109 // TODO(asanka): Rename this to avoid confusion with HaveAuthHandler(). |
| 110 bool HaveAuth() const; |
| 68 | 111 |
| 69 virtual bool HaveAuth() const; | 112 // TODO(asanka): Rename to auth_challenge_info(). |
| 113 scoped_refptr<AuthChallengeInfo> auth_info(); |
| 70 | 114 |
| 71 virtual scoped_refptr<AuthChallengeInfo> auth_info(); | 115 // TODO(asanka): This method is only used by tests. Make it private once tests |
| 116 // are updated. |
| 117 bool IsAuthSchemeDisabled(const std::string& scheme) const; |
| 72 | 118 |
| 73 virtual bool IsAuthSchemeDisabled(const std::string& scheme) const; | 119 // Disallow using URL embedded identities to respond to authentication |
| 74 virtual void DisableAuthScheme(const std::string& scheme); | 120 // challenges. |
| 75 virtual void DisableEmbeddedIdentity(); | 121 void DisableEmbeddedIdentity(); |
| 76 | 122 |
| 77 private: | 123 private: |
| 124 struct CandidateChallenge { |
| 125 std::string scheme; |
| 126 std::string challenge; |
| 127 int priority; |
| 128 |
| 129 friend bool operator<(const CandidateChallenge& left, |
| 130 const CandidateChallenge& right) { |
| 131 return left.priority < right.priority; |
| 132 } |
| 133 }; |
| 134 |
| 78 // Actions for InvalidateCurrentHandler() | 135 // Actions for InvalidateCurrentHandler() |
| 79 enum InvalidateHandlerAction { | 136 enum InvalidateHandlerAction { |
| 80 INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, | 137 INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, |
| 81 INVALIDATE_HANDLER_AND_DISABLE_SCHEME, | 138 INVALIDATE_HANDLER_AND_DISABLE_SCHEME, |
| 82 INVALIDATE_HANDLER | 139 INVALIDATE_HANDLER |
| 83 }; | 140 }; |
| 84 | 141 |
| 85 // So that we can mock this object. | 142 enum State { |
| 143 STATE_NONE, |
| 144 STATE_CHOOSE_CHALLENGE, |
| 145 STATE_TRY_NEXT_CHALLENGE, |
| 146 STATE_TRY_NEXT_CHALLENGE_COMPLETE, |
| 147 STATE_CHOOSE_IDENTITY, |
| 148 STATE_HANDLE_ANOTHER_CHALLENGE, |
| 149 STATE_HANDLE_ANOTHER_CHALLENGE_COMPLETE, |
| 150 STATE_GENERATE_TOKEN, |
| 151 STATE_GENERATE_TOKEN_COMPLETE, |
| 152 }; |
| 153 |
| 154 int DoLoop(int result); |
| 155 int DoChooseChallenge(); |
| 156 int DoTryNextChallenge(); |
| 157 int DoTryNextChallengeComplete(int result); |
| 158 int DoChooseIdentity(); |
| 159 int DoHandleAnotherChallenge(); |
| 160 int DoHandleAnotherChallengeComplete(int result); |
| 161 int DoGenerateToken(); |
| 162 int DoGenerateTokenComplete(int result); |
| 163 |
| 86 friend class base::RefCounted<HttpAuthController>; | 164 friend class base::RefCounted<HttpAuthController>; |
| 87 | 165 |
| 88 virtual ~HttpAuthController(); | 166 virtual ~HttpAuthController(); |
| 89 | 167 |
| 90 // Searches the auth cache for an entry that encompasses the request's path. | 168 // Searches the auth cache for an entry that encompasses the path for the |
| 91 // If such an entry is found, updates |identity_| and |handler_| with the | 169 // request. If such an entry is found, updates |identity_| and |handler_| |
| 92 // cache entry's data and returns true. | 170 // with the cache entry's data and returns true. |
| 93 bool SelectPreemptiveAuth(const BoundNetLog& net_log); | 171 bool SelectPreemptiveAuth(const BoundNetLog& net_log); |
| 94 | 172 |
| 95 // Invalidates the current handler. If |action| is | 173 // Invalidates the current handler. If |action| is |
| 96 // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate | 174 // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate |
| 97 // the cached credentials used by the handler. | 175 // the cached credentials used by the handler. |
| 98 void InvalidateCurrentHandler(InvalidateHandlerAction action); | 176 void InvalidateCurrentHandler(InvalidateHandlerAction action); |
| 99 | 177 |
| 100 // Invalidates any auth cache entries after authentication has failed. | 178 // Invalidates any auth cache entries after authentication has failed. |
| 101 // The identity that was rejected is |identity_|. | 179 // The identity that was rejected is |identity_|. |
| 102 void InvalidateRejectedAuthFromCache(); | 180 void InvalidateRejectedAuthFromCache(); |
| 103 | 181 |
| 104 // Sets |identity_| to the next identity that the transaction should try. It | 182 // Sets |identity_| to the next identity that the transaction should try. It |
| 105 // chooses candidates by searching the auth cache and the URL for a | 183 // chooses candidates by searching the auth cache and the URL for a |
| 106 // username:password. Returns true if an identity was found. | 184 // username:password. Returns true if an identity was found. |
| 107 bool SelectNextAuthIdentityToTry(); | 185 bool SelectNextAuthIdentityToTry(); |
| 108 | 186 |
| 109 // Populates auth_info_ with the challenge information, so that | 187 // Populates auth_info_ with the challenge information, so that |
| 110 // URLRequestHttpJob can prompt for credentials. | 188 // URLRequestHttpJob can prompt for credentials. |
| 111 void PopulateAuthChallenge(); | 189 void PopulateAuthChallenge(); |
| 112 | 190 |
| 113 // If |result| indicates a permanent failure, disables the current | 191 // If |result| indicates a permanent failure, disables the current |
| 114 // auth scheme for this controller and returns true. Returns false | 192 // auth scheme for this controller and returns true. Returns false |
| 115 // otherwise. | 193 // otherwise. |
| 116 bool DisableOnAuthHandlerResult(int result); | 194 bool DisableOnAuthHandlerResult(int result); |
| 117 | 195 |
| 196 // Disables |scheme| from being considered for handling authentication |
| 197 // challenges in the future. |
| 198 void DisableAuthScheme(const std::string& scheme); |
| 199 |
| 118 void OnIOComplete(int result); | 200 void OnIOComplete(int result); |
| 119 | 201 |
| 120 // Indicates if this handler is for Proxy auth or Server auth. | 202 // Indicates if this handler is for Proxy auth or Server auth. |
| 121 HttpAuth::Target target_; | 203 HttpAuth::Target target_; |
| 122 | 204 |
| 123 // Holds the {scheme, host, path, port} for the authentication target. | 205 // Holds the {scheme, host, path, port} for the authentication target. |
| 124 const GURL auth_url_; | 206 const GURL auth_url_; |
| 125 | 207 |
| 126 // Holds the {scheme, host, port} for the authentication target. | 208 // Holds the {scheme, host, port} for the authentication target. |
| 127 const GURL auth_origin_; | 209 const GURL auth_origin_; |
| 128 | 210 |
| 129 // The absolute path of the resource needing authentication. | 211 // The absolute path of the resource needing authentication. |
| 130 // For proxy authentication the path is empty. | 212 // For proxy authentication the path is empty. |
| 131 const std::string auth_path_; | 213 const std::string auth_path_; |
| 132 | 214 |
| 133 // |handler_| encapsulates the logic for the particular auth-scheme. | 215 // |handler_| encapsulates the logic for the particular auth-scheme. |
| 134 // This includes the challenge's parameters. If NULL, then there is no | 216 // This includes the challenge parameters. If NULL, then there is no |
| 135 // associated auth handler. | 217 // associated auth handler. |
| 136 scoped_ptr<HttpAuthHandler> handler_; | 218 scoped_ptr<HttpAuthHandler> handler_; |
| 137 | 219 |
| 138 // |identity_| holds the credentials that should be used by | 220 // |identity_| holds the credentials that should be used by |
| 139 // the handler_ to generate challenge responses. This identity can come from | 221 // the handler_ to generate challenge responses. This identity can come from |
| 140 // a number of places (url, cache, prompt). | 222 // a number of places (URL, cache, prompt). |
| 141 HttpAuth::Identity identity_; | 223 HttpAuth::Identity identity_; |
| 142 | 224 |
| 143 // |auth_token_| contains the opaque string to pass to the proxy or | 225 // |auth_token_| contains the opaque string to pass to the proxy or |
| 144 // server to authenticate the client. | 226 // server to authenticate the client. |
| 145 std::string auth_token_; | 227 std::string auth_token_; |
| 146 | 228 |
| 147 // Contains information about the auth challenge. | 229 // Contains information about the auth challenge. |
| 148 scoped_refptr<AuthChallengeInfo> auth_info_; | 230 scoped_refptr<AuthChallengeInfo> auth_info_; |
| 149 | 231 |
| 150 // True if we've used the username:password embedded in the URL. This | 232 // True if we've used the username:password embedded in the URL. This |
| 151 // makes sure we use the embedded identity only once for the transaction, | 233 // makes sure we use the embedded identity only once for the transaction, |
| 152 // preventing an infinite auth restart loop. | 234 // preventing an infinite auth restart loop. |
| 153 bool embedded_identity_used_; | 235 bool embedded_identity_used_; |
| 154 | 236 |
| 155 // True if default credentials have already been tried for this transaction | 237 // True if default credentials have already been tried for this transaction |
| 156 // in response to an HTTP authentication challenge. | 238 // in response to an HTTP authentication challenge. |
| 157 bool default_credentials_used_; | 239 bool default_credentials_used_; |
| 158 | 240 |
| 159 // These two are owned by the HttpNetworkSession/IOThread, which own the | 241 // These two are owned by the HttpNetworkSession/IOThread, which own the |
| 160 // objects which reference |this|. Therefore, these raw pointers are valid | 242 // objects which reference |this|. Therefore, these raw pointers are valid |
| 161 // for the lifetime of this object. | 243 // for the lifetime of this object. |
| 162 HttpAuthCache* const http_auth_cache_; | 244 HttpAuthCache* const http_auth_cache_; |
| 163 HttpAuthHandlerFactory* const http_auth_handler_factory_; | 245 HttpAuthHandlerFactory* const http_auth_handler_factory_; |
| 164 | 246 |
| 165 HttpAuthSchemeSet disabled_schemes_; | 247 HttpAuthSchemeSet disabled_schemes_; |
| 166 | 248 |
| 167 CompletionCallback callback_; | 249 CompletionCallback callback_; |
| 250 |
| 251 State next_state_ = STATE_NONE; |
| 252 CompletionCallback io_callback_; |
| 253 HttpResponseInfo const* response_info_ = nullptr; |
| 254 HttpRequestInfo const* request_info_ = nullptr; |
| 255 std::string selected_auth_challenge_; |
| 256 BoundNetLog net_log_; |
| 257 std::priority_queue<CandidateChallenge> candidate_challenges_; |
| 258 |
| 259 base::WeakPtrFactory<HttpAuthController> weak_ptr_factory_; |
| 168 }; | 260 }; |
| 169 | 261 |
| 170 } // namespace net | 262 } // namespace net |
| 171 | 263 |
| 172 #endif // NET_HTTP_HTTP_AUTH_CONTROLLER_H_ | 264 #endif // NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| OLD | NEW |