asanka | 5ffd5d7 | 2016-03-23 16:20:49 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| 6 | #define NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| 7 | |
danakj | 1fd259a0 | 2016-04-16 03:17:09 | [diff] [blame] | 8 | #include <memory> |
[email protected] | cee6312 | 2010-07-20 04:43:31 | [diff] [blame] | 9 | #include <set> |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 10 | #include <string> |
| 11 | |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 12 | #include "base/memory/ref_counted.h" |
Emily Stark | f2c9bbd | 2019-04-09 17:08:58 | [diff] [blame] | 13 | #include "base/optional.h" |
gab | 47aa7da | 2017-06-02 16:09:43 | [diff] [blame] | 14 | #include "base/threading/thread_checker.h" |
Bence Béky | 7236fb7 | 2018-08-01 14:35:09 | [diff] [blame] | 15 | #include "net/base/completion_once_callback.h" |
[email protected] | 172da1b | 2011-08-12 15:52:26 | [diff] [blame] | 16 | #include "net/base/net_export.h" |
Matt Menke | be09042 | 2019-10-18 20:25:26 | [diff] [blame] | 17 | #include "net/base/network_isolation_key.h" |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 18 | #include "net/http/http_auth.h" |
Kevin DiClemente | f0711908 | 2019-08-12 13:31:34 | [diff] [blame] | 19 | #include "net/http/http_auth_preferences.h" |
Asanka Herath | 20e8909 | 2019-05-10 04:33:20 | [diff] [blame] | 20 | #include "net/log/net_log_with_source.h" |
[email protected] | f89276a7 | 2013-07-12 06:41:54 | [diff] [blame] | 21 | #include "url/gurl.h" |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 22 | |
| 23 | namespace net { |
| 24 | |
| 25 | class AuthChallengeInfo; |
[email protected] | f3cf980 | 2011-10-28 18:44:58 | [diff] [blame] | 26 | class AuthCredentials; |
[email protected] | 560c043 | 2010-07-13 20:45:31 | [diff] [blame] | 27 | class HttpAuthHandler; |
[email protected] | 3598c602 | 2010-09-17 23:13:09 | [diff] [blame] | 28 | class HttpAuthHandlerFactory; |
| 29 | class HttpAuthCache; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 30 | class HttpRequestHeaders; |
Eric Orth | be2efac | 2019-03-06 01:11:11 | [diff] [blame] | 31 | class HostResolver; |
mikecirone | f22f981 | 2016-10-04 03:40:19 | [diff] [blame] | 32 | class NetLogWithSource; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 33 | struct HttpRequestInfo; |
asanka | 5ffd5d7 | 2016-03-23 16:20:49 | [diff] [blame] | 34 | class SSLInfo; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 35 | |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 36 | // HttpAuthController is the main entry point for external callers into the HTTP |
| 37 | // authentication stack. A single instance of an HttpAuthController can be used |
| 38 | // to handle authentication to a single "target", where "target" is a HTTP |
| 39 | // server or a proxy. During its lifetime, the HttpAuthController can make use |
| 40 | // of multiple authentication handlers (implemented as HttpAuthHandler |
| 41 | // subclasses), and respond to multiple challenges. |
Matt Menke | 84586d8 | 2017-09-28 19:39:28 | [diff] [blame] | 42 | // |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 43 | // Individual HTTP authentication schemes can have additional requirements other |
| 44 | // than what's prescribed in RFC 7235. See HandleAuthChallenge() for details. |
[email protected] | 172da1b | 2011-08-12 15:52:26 | [diff] [blame] | 45 | class NET_EXPORT_PRIVATE HttpAuthController |
gab | 47aa7da | 2017-06-02 16:09:43 | [diff] [blame] | 46 | : public base::RefCounted<HttpAuthController> { |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 47 | public: |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 48 | // Construct a new HttpAuthController. |
| 49 | // |
| 50 | // * |target| is either PROXY or SERVER and determines the authentication |
| 51 | // headers to use ("WWW-Authenticate"/"Authorization" vs. |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 52 | // "Proxy-Authenticate"/"Proxy-Authorization") and how ambient |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 53 | // credentials are used. |
| 54 | // |
| 55 | // * |auth_url| specifies the target URL. The origin of the URL identifies the |
| 56 | // target host. The path (hierarchical part defined in RFC 3986 section |
| 57 | // 3.3) of the URL is used by HTTP basic authentication to determine |
| 58 | // cached credentials can be used to preemptively send an authorization |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 59 | // header. See RFC 7617 section 2.2 (Reusing Credentials) for details. |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 60 | // If |target| is PROXY, then |auth_url| should have no hierarchical |
| 61 | // part since that is meaningless. |
| 62 | // |
Matt Menke | be09042 | 2019-10-18 20:25:26 | [diff] [blame] | 63 | // * |network_isolation_key| specifies the NetworkIsolationKey associated with |
| 64 | // the resource load. Depending on settings, credentials may be scoped |
| 65 | // to a single NetworkIsolationKey. |
| 66 | // |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 67 | // * |http_auth_cache| specifies the credentials cache to use. During |
| 68 | // authentication if explicit (user-provided) credentials are used and |
| 69 | // they can be cached to respond to authentication challenges in the |
| 70 | // future, they are stored in the cache. In addition, the HTTP Digest |
| 71 | // authentication is stateful across requests. So the |http_auth_cache| |
| 72 | // is also used to maintain state for this authentication scheme. |
| 73 | // |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 74 | // * |http_auth_handler_factory| is used to construct instances of |
| 75 | // HttpAuthHandler subclasses to handle scheme-specific authentication |
Asanka Herath | d856bd01 | 2019-05-08 03:17:58 | [diff] [blame] | 76 | // logic. The |http_auth_handler_factory| is also responsible for |
| 77 | // determining whether the authentication stack should use a specific |
| 78 | // authentication scheme or not. |
| 79 | // |
| 80 | // * |host_resolver| is used for determining the canonical hostname given a |
| 81 | // possibly non-canonical host name. Name canonicalization is used for |
| 82 | // NTLM and Negotiate HTTP authentication schemes. |
Kevin DiClemente | f0711908 | 2019-08-12 13:31:34 | [diff] [blame] | 83 | // |
| 84 | // * |allow_default_credentials| is used for determining if the current |
| 85 | // context allows ambient authentication using default credentials. |
Rohit Agarwal | 2653f47 | 2019-11-12 19:39:27 | [diff] [blame] | 86 | HttpAuthController(HttpAuth::Target target, |
| 87 | const GURL& auth_url, |
| 88 | const NetworkIsolationKey& network_isolation_key, |
| 89 | HttpAuthCache* http_auth_cache, |
| 90 | HttpAuthHandlerFactory* http_auth_handler_factory, |
| 91 | HostResolver* host_resolver); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 92 | |
| 93 | // Generate an authentication token for |target| if necessary. The return |
| 94 | // value is a net error code. |OK| will be returned both in the case that |
| 95 | // a token is correctly generated synchronously, as well as when no tokens |
| 96 | // were necessary. |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 97 | int MaybeGenerateAuthToken(const HttpRequestInfo* request, |
Bence Béky | 7236fb7 | 2018-08-01 14:35:09 | [diff] [blame] | 98 | CompletionOnceCallback callback, |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 99 | const NetLogWithSource& net_log); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 100 | |
| 101 | // Adds either the proxy auth header, or the origin server auth header, |
| 102 | // as specified by |target_|. |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 103 | void AddAuthorizationHeader(HttpRequestHeaders* authorization_headers); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 104 | |
| 105 | // Checks for and handles HTTP status code 401 or 407. |
[email protected] | 65d3438 | 2010-07-01 18:12:26 | [diff] [blame] | 106 | // |HandleAuthChallenge()| returns OK on success, or a network error code |
| 107 | // otherwise. It may also populate |auth_info_|. |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 108 | int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers, |
| 109 | const SSLInfo& ssl_info, |
| 110 | bool do_not_send_server_auth, |
| 111 | bool establishing_tunnel, |
| 112 | const NetLogWithSource& net_log); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 113 | |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 114 | // Store the supplied credentials and prepare to restart the auth. |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 115 | void ResetAuth(const AuthCredentials& credentials); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 116 | |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 117 | bool HaveAuthHandler() const; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 118 | |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 119 | bool HaveAuth() const; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 120 | |
Bence Béky | 3238f2e1 | 2017-09-22 22:44:49 | [diff] [blame] | 121 | // Return whether the authentication scheme is incompatible with HTTP/2 |
| 122 | // and thus the server would presumably reject a request on HTTP/2 anyway. |
| 123 | bool NeedsHTTP11() const; |
| 124 | |
Emily Stark | f2c9bbd | 2019-04-09 17:08:58 | [diff] [blame] | 125 | // Swaps the authentication challenge info into |other|. |
| 126 | void TakeAuthInfo(base::Optional<AuthChallengeInfo>* other); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 127 | |
asanka | 5e8286c3 | 2017-02-23 16:13:42 | [diff] [blame] | 128 | bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const; |
| 129 | void DisableAuthScheme(HttpAuth::Scheme scheme); |
| 130 | void DisableEmbeddedIdentity(); |
[email protected] | cee6312 | 2010-07-20 04:43:31 | [diff] [blame] | 131 | |
davidben | 8c7089a | 2017-04-17 20:38:22 | [diff] [blame] | 132 | // Called when the connection has been closed, so the current handler (which |
| 133 | // contains state bound to the connection) should be dropped. If retrying on a |
| 134 | // new connection, the next call to MaybeGenerateAuthToken will retry the |
| 135 | // current auth scheme. |
| 136 | void OnConnectionClosed(); |
| 137 | |
[email protected] | 3598c602 | 2010-09-17 23:13:09 | [diff] [blame] | 138 | private: |
[email protected] | 463f835 | 2011-02-18 14:26:55 | [diff] [blame] | 139 | // Actions for InvalidateCurrentHandler() |
| 140 | enum InvalidateHandlerAction { |
| 141 | INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, |
[email protected] | 26d84b0 | 2011-08-31 14:07:08 | [diff] [blame] | 142 | INVALIDATE_HANDLER_AND_DISABLE_SCHEME, |
[email protected] | 463f835 | 2011-02-18 14:26:55 | [diff] [blame] | 143 | INVALIDATE_HANDLER |
| 144 | }; |
| 145 | |
[email protected] | 3598c602 | 2010-09-17 23:13:09 | [diff] [blame] | 146 | // So that we can mock this object. |
[email protected] | e772db3f | 2010-07-12 18:11:13 | [diff] [blame] | 147 | friend class base::RefCounted<HttpAuthController>; |
[email protected] | 3598c602 | 2010-09-17 23:13:09 | [diff] [blame] | 148 | |
David Benjamin | 5af27d4 | 2018-08-24 17:07:36 | [diff] [blame] | 149 | ~HttpAuthController(); |
[email protected] | e772db3f | 2010-07-12 18:11:13 | [diff] [blame] | 150 | |
Asanka Herath | 20e8909 | 2019-05-10 04:33:20 | [diff] [blame] | 151 | // If this controller's NetLog hasn't been created yet, creates it and |
| 152 | // associates it with |caller_net_log|. Does nothing after the first |
| 153 | // invocation. |
| 154 | void BindToCallingNetLog(const NetLogWithSource& caller_net_log); |
| 155 | |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 156 | // Searches the auth cache for an entry that encompasses the request's path. |
| 157 | // If such an entry is found, updates |identity_| and |handler_| with the |
| 158 | // cache entry's data and returns true. |
Asanka Herath | 20e8909 | 2019-05-10 04:33:20 | [diff] [blame] | 159 | bool SelectPreemptiveAuth(const NetLogWithSource& caller_net_log); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 160 | |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 161 | // Invalidates the current handler. If |action| is |
[email protected] | cd0efd2 | 2011-02-24 15:25:55 | [diff] [blame] | 162 | // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate |
| 163 | // the cached credentials used by the handler. |
[email protected] | 463f835 | 2011-02-18 14:26:55 | [diff] [blame] | 164 | void InvalidateCurrentHandler(InvalidateHandlerAction action); |
[email protected] | eca50e12 | 2010-09-11 14:03:30 | [diff] [blame] | 165 | |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 166 | // Invalidates any auth cache entries after authentication has failed. |
| 167 | // The identity that was rejected is |identity_|. |
| 168 | void InvalidateRejectedAuthFromCache(); |
| 169 | |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 170 | // Allows reusing last used identity source. If the authentication handshake |
Asanka Herath | bc3f8f6 | 2018-11-16 23:08:30 | [diff] [blame] | 171 | // breaks down halfway, then the controller needs to restart it from the |
| 172 | // beginning and resue the same identity. |
| 173 | void PrepareIdentityForReuse(); |
| 174 | |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 175 | // Sets |identity_| to the next identity that the transaction should try. It |
| 176 | // chooses candidates by searching the auth cache and the URL for a |
| 177 | // username:password. Returns true if an identity was found. |
| 178 | bool SelectNextAuthIdentityToTry(); |
| 179 | |
| 180 | // Populates auth_info_ with the challenge information, so that |
[email protected] | f3cf980 | 2011-10-28 18:44:58 | [diff] [blame] | 181 | // URLRequestHttpJob can prompt for credentials. |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 182 | void PopulateAuthChallenge(); |
| 183 | |
asanka | e2257db | 2016-10-11 22:03:16 | [diff] [blame] | 184 | // Handle the result of calling GenerateAuthToken on an HttpAuthHandler. The |
| 185 | // return value of this function should be used as the return value of the |
| 186 | // GenerateAuthToken operation. |
| 187 | int HandleGenerateTokenResult(int result); |
[email protected] | 76b0f68 | 2011-03-30 16:54:54 | [diff] [blame] | 188 | |
asanka | 463ca426 | 2016-11-16 02:34:31 | [diff] [blame] | 189 | void OnGenerateAuthTokenDone(int result); |
[email protected] | cee6312 | 2010-07-20 04:43:31 | [diff] [blame] | 190 | |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 191 | // Indicates if this handler is for Proxy auth or Server auth. |
| 192 | HttpAuth::Target target_; |
| 193 | |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 194 | // Holds the {scheme, host, port, path} for the authentication target. |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 195 | const GURL auth_url_; |
| 196 | |
| 197 | // Holds the {scheme, host, port} for the authentication target. |
| 198 | const GURL auth_origin_; |
| 199 | |
| 200 | // The absolute path of the resource needing authentication. |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 201 | // For proxy authentication, the path is empty. |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 202 | const std::string auth_path_; |
| 203 | |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 204 | // NetworkIsolationKey associated with the request. |
Matt Menke | be09042 | 2019-10-18 20:25:26 | [diff] [blame] | 205 | const NetworkIsolationKey network_isolation_key_; |
| 206 | |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 207 | // |handler_| encapsulates the logic for the particular auth-scheme. |
Asanka Herath | 26b1de8 | 2019-05-23 04:03:04 | [diff] [blame] | 208 | // This includes the challenge's parameters. If nullptr, then there is no |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 209 | // associated auth handler. |
danakj | 1fd259a0 | 2016-04-16 03:17:09 | [diff] [blame] | 210 | std::unique_ptr<HttpAuthHandler> handler_; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 211 | |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 212 | // |identity_| holds the credentials that should be used by the handler_ to |
| 213 | // generate challenge responses. This identity can come from a number of |
| 214 | // places (url, cache, prompt). |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 215 | HttpAuth::Identity identity_; |
| 216 | |
| 217 | // |auth_token_| contains the opaque string to pass to the proxy or |
| 218 | // server to authenticate the client. |
| 219 | std::string auth_token_; |
| 220 | |
| 221 | // Contains information about the auth challenge. |
Emily Stark | f2c9bbd | 2019-04-09 17:08:58 | [diff] [blame] | 222 | base::Optional<AuthChallengeInfo> auth_info_; |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 223 | |
[email protected] | f3cf980 | 2011-10-28 18:44:58 | [diff] [blame] | 224 | // True if we've used the username:password embedded in the URL. This |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 225 | // makes sure we use the embedded identity only once for the transaction, |
| 226 | // preventing an infinite auth restart loop. |
| 227 | bool embedded_identity_used_; |
| 228 | |
| 229 | // True if default credentials have already been tried for this transaction |
| 230 | // in response to an HTTP authentication challenge. |
| 231 | bool default_credentials_used_; |
| 232 | |
[email protected] | 3598c602 | 2010-09-17 23:13:09 | [diff] [blame] | 233 | // These two are owned by the HttpNetworkSession/IOThread, which own the |
Eric Lawrence [MSFT] | 855f0969e | 2020-11-11 07:03:43 | [diff] [blame] | 234 | // objects which reference |this|. Therefore, these raw pointers are valid |
[email protected] | 3598c602 | 2010-09-17 23:13:09 | [diff] [blame] | 235 | // for the lifetime of this object. |
| 236 | HttpAuthCache* const http_auth_cache_; |
| 237 | HttpAuthHandlerFactory* const http_auth_handler_factory_; |
Eric Orth | be2efac | 2019-03-06 01:11:11 | [diff] [blame] | 238 | HostResolver* const host_resolver_; |
[email protected] | cee6312 | 2010-07-20 04:43:31 | [diff] [blame] | 239 | |
[email protected] | 547fc79 | 2011-01-13 13:31:17 | [diff] [blame] | 240 | std::set<HttpAuth::Scheme> disabled_schemes_; |
[email protected] | cee6312 | 2010-07-20 04:43:31 | [diff] [blame] | 241 | |
Bence Béky | 7236fb7 | 2018-08-01 14:35:09 | [diff] [blame] | 242 | CompletionOnceCallback callback_; |
gab | 47aa7da | 2017-06-02 16:09:43 | [diff] [blame] | 243 | |
Asanka Herath | 20e8909 | 2019-05-10 04:33:20 | [diff] [blame] | 244 | // NetLog to be used for logging in this controller. |
| 245 | NetLogWithSource net_log_; |
| 246 | |
gab | 47aa7da | 2017-06-02 16:09:43 | [diff] [blame] | 247 | THREAD_CHECKER(thread_checker_); |
[email protected] | 228404f | 2010-06-24 04:31:41 | [diff] [blame] | 248 | }; |
| 249 | |
| 250 | } // namespace net |
| 251 | |
| 252 | #endif // NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |