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 |