| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| #define NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| |
| #include "base/memory/ref_counted.h" |
| #include "base/threading/thread_checker.h" |
| #include "net/base/completion_once_callback.h" |
| #include "net/base/net_export.h" |
| #include "net/http/http_auth.h" |
| #include "url/gurl.h" |
| |
| namespace net { |
| |
| class AuthChallengeInfo; |
| class AuthCredentials; |
| class HttpAuthHandler; |
| class HttpAuthHandlerFactory; |
| class HttpAuthCache; |
| class HttpRequestHeaders; |
| class NetLogWithSource; |
| struct HttpRequestInfo; |
| class SSLInfo; |
| |
| // HttpAuthController is interface between other classes and HttpAuthHandlers. |
| // It handles all challenges when attempting to make a single request to a |
| // server, both in the case of trying multiple sets of credentials (Possibly on |
| // different sockets), and when going through multiple rounds of auth with |
| // connection-based auth, creating new HttpAuthHandlers as necessary. |
| // |
| // It is unaware of when a round of auth uses a new socket, which can lead to |
| // problems for connection-based auth. |
| class NET_EXPORT_PRIVATE HttpAuthController |
| : public base::RefCounted<HttpAuthController> { |
| public: |
| // The arguments are self explanatory except possibly for |auth_url|, which |
| // should be both the auth target and auth path in a single url argument. |
| // |target| indicates whether this is for authenticating with a proxy or |
| // destination server. |
| HttpAuthController(HttpAuth::Target target, |
| const GURL& auth_url, |
| HttpAuthCache* http_auth_cache, |
| HttpAuthHandlerFactory* http_auth_handler_factory); |
| |
| // Generate an authentication token for |target| if necessary. The return |
| // value is a net error code. |OK| will be returned both in the case that |
| // a token is correctly generated synchronously, as well as when no tokens |
| // were necessary. |
| int MaybeGenerateAuthToken(const HttpRequestInfo* request, |
| CompletionOnceCallback callback, |
| const NetLogWithSource& net_log); |
| |
| // Adds either the proxy auth header, or the origin server auth header, |
| // as specified by |target_|. |
| void AddAuthorizationHeader(HttpRequestHeaders* authorization_headers); |
| |
| // Checks for and handles HTTP status code 401 or 407. |
| // |HandleAuthChallenge()| returns OK on success, or a network error code |
| // otherwise. It may also populate |auth_info_|. |
| int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers, |
| const SSLInfo& ssl_info, |
| bool do_not_send_server_auth, |
| bool establishing_tunnel, |
| const NetLogWithSource& net_log); |
| |
| // Store the supplied credentials and prepare to restart the auth. |
| void ResetAuth(const AuthCredentials& credentials); |
| |
| bool HaveAuthHandler() const; |
| |
| bool HaveAuth() const; |
| |
| // Return whether the authentication scheme is incompatible with HTTP/2 |
| // and thus the server would presumably reject a request on HTTP/2 anyway. |
| bool NeedsHTTP11() const; |
| |
| scoped_refptr<AuthChallengeInfo> auth_info(); |
| |
| bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const; |
| void DisableAuthScheme(HttpAuth::Scheme scheme); |
| void DisableEmbeddedIdentity(); |
| |
| // Called when the connection has been closed, so the current handler (which |
| // contains state bound to the connection) should be dropped. If retrying on a |
| // new connection, the next call to MaybeGenerateAuthToken will retry the |
| // current auth scheme. |
| void OnConnectionClosed(); |
| |
| private: |
| // Actions for InvalidateCurrentHandler() |
| enum InvalidateHandlerAction { |
| INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, |
| INVALIDATE_HANDLER_AND_DISABLE_SCHEME, |
| INVALIDATE_HANDLER |
| }; |
| |
| // So that we can mock this object. |
| friend class base::RefCounted<HttpAuthController>; |
| |
| ~HttpAuthController(); |
| |
| // Searches the auth cache for an entry that encompasses the request's path. |
| // If such an entry is found, updates |identity_| and |handler_| with the |
| // cache entry's data and returns true. |
| bool SelectPreemptiveAuth(const NetLogWithSource& net_log); |
| |
| // Invalidates the current handler. If |action| is |
| // INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, then also invalidate |
| // the cached credentials used by the handler. |
| void InvalidateCurrentHandler(InvalidateHandlerAction action); |
| |
| // Invalidates any auth cache entries after authentication has failed. |
| // The identity that was rejected is |identity_|. |
| void InvalidateRejectedAuthFromCache(); |
| |
| // Sets |identity_| to the next identity that the transaction should try. It |
| // chooses candidates by searching the auth cache and the URL for a |
| // username:password. Returns true if an identity was found. |
| bool SelectNextAuthIdentityToTry(); |
| |
| // Populates auth_info_ with the challenge information, so that |
| // URLRequestHttpJob can prompt for credentials. |
| void PopulateAuthChallenge(); |
| |
| // Handle the result of calling GenerateAuthToken on an HttpAuthHandler. The |
| // return value of this function should be used as the return value of the |
| // GenerateAuthToken operation. |
| int HandleGenerateTokenResult(int result); |
| |
| void OnGenerateAuthTokenDone(int result); |
| |
| // Indicates if this handler is for Proxy auth or Server auth. |
| HttpAuth::Target target_; |
| |
| // Holds the {scheme, host, path, port} for the authentication target. |
| const GURL auth_url_; |
| |
| // Holds the {scheme, host, port} for the authentication target. |
| const GURL auth_origin_; |
| |
| // The absolute path of the resource needing authentication. |
| // For proxy authentication the path is empty. |
| const std::string auth_path_; |
| |
| // |handler_| encapsulates the logic for the particular auth-scheme. |
| // This includes the challenge's parameters. If NULL, then there is no |
| // associated auth handler. |
| std::unique_ptr<HttpAuthHandler> handler_; |
| |
| // |identity_| holds the credentials that should be used by |
| // the handler_ to generate challenge responses. This identity can come from |
| // a number of places (url, cache, prompt). |
| HttpAuth::Identity identity_; |
| |
| // |auth_token_| contains the opaque string to pass to the proxy or |
| // server to authenticate the client. |
| std::string auth_token_; |
| |
| // Contains information about the auth challenge. |
| scoped_refptr<AuthChallengeInfo> auth_info_; |
| |
| // True if we've used the username:password embedded in the URL. This |
| // makes sure we use the embedded identity only once for the transaction, |
| // preventing an infinite auth restart loop. |
| bool embedded_identity_used_; |
| |
| // True if default credentials have already been tried for this transaction |
| // in response to an HTTP authentication challenge. |
| bool default_credentials_used_; |
| |
| // These two are owned by the HttpNetworkSession/IOThread, which own the |
| // objects which reference |this|. Therefore, these raw pointers are valid |
| // for the lifetime of this object. |
| HttpAuthCache* const http_auth_cache_; |
| HttpAuthHandlerFactory* const http_auth_handler_factory_; |
| |
| std::set<HttpAuth::Scheme> disabled_schemes_; |
| |
| CompletionOnceCallback callback_; |
| |
| THREAD_CHECKER(thread_checker_); |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |