forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttp_auth_handler.h
249 lines (210 loc) · 9.49 KB
/
http_auth_handler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
// Copyright 2011 The Chromium Authors
// 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_HANDLER_H_
#define NET_HTTP_HTTP_AUTH_HANDLER_H_
#include <string>
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/http/http_auth.h"
#include "net/log/net_log_with_source.h"
#include "url/scheme_host_port.h"
namespace net {
class NetworkAnonymizationKey;
class HttpAuthChallengeTokenizer;
struct HttpRequestInfo;
class SSLInfo;
// HttpAuthHandler is the interface for the authentication schemes
// (basic, digest, NTLM, Negotiate).
// HttpAuthHandler objects are typically created by an HttpAuthHandlerFactory.
//
// HttpAuthHandlers and generally created and managed by an HttpAuthController,
// which is the interaction point between the rest of net and the HTTP auth
// code.
//
// For connection-based authentication, an HttpAuthHandler handles all rounds
// related to using a single identity. If the identity is rejected, a new
// HttpAuthHandler must be created.
class NET_EXPORT_PRIVATE HttpAuthHandler {
public:
HttpAuthHandler();
HttpAuthHandler(const HttpAuthHandler&) = delete;
HttpAuthHandler& operator=(const HttpAuthHandler&) = delete;
virtual ~HttpAuthHandler();
// Initializes the handler using a challenge issued by a server.
//
// |challenge| must be non-nullptr and have already tokenized the
// authentication scheme, but none of the tokens occurring after the
// authentication scheme.
// |target| and |scheme_host_port| are both stored for later use, and are not
// part of the initial challenge.
// |ssl_info| must be valid if the underlying connection used a certificate.
// |network_anonymization_key| the NetworkAnonymizationKey associated with the
// challenge. Used for host resolutions, if any are needed.
// |net_log| to be used for logging.
bool InitFromChallenge(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key,
const url::SchemeHostPort& scheme_host_port,
const NetLogWithSource& net_log);
// Determines how the previous authorization attempt was received.
//
// This is called when the server/proxy responds with a 401/407 after an
// earlier authorization attempt. Although this normally means that the
// previous attempt was rejected, in multi-round schemes such as
// NTLM+Negotiate it may indicate that another round of challenge+response
// is required. For Digest authentication it may also mean that the previous
// attempt used a stale nonce (and nonce-count) and that a new attempt should
// be made with a different nonce provided in the challenge.
//
// |challenge| must be non-nullptr and have already tokenized the
// authentication scheme, but none of the tokens occurring after the
// authentication scheme.
HttpAuth::AuthorizationResult HandleAnotherChallenge(
HttpAuthChallengeTokenizer* challenge);
// Generates an authentication token, potentially asynchronously.
//
// When |credentials| is nullptr, the default credentials for the currently
// logged in user are used. |AllowsDefaultCredentials()| MUST be true in this
// case.
//
// |request|, |callback|, and |auth_token| must be non-nullptr.
//
// The return value is a net error code.
//
// If |OK| is returned, |*auth_token| is filled in with an authentication
// token which can be inserted in the HTTP request.
//
// If |ERR_IO_PENDING| is returned, |*auth_token| will be filled in
// asynchronously and |callback| will be invoked. The lifetime of
// |request|, |callback|, and |auth_token| must last until |callback| is
// invoked, but |credentials| is only used during the initial call.
//
// All other return codes indicate that there was a problem generating a
// token, and the value of |*auth_token| is unspecified.
int GenerateAuthToken(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
std::string* auth_token);
// The authentication scheme as an enumerated value.
HttpAuth::Scheme auth_scheme() const {
return auth_scheme_;
}
// The realm, encoded as UTF-8. This may be empty.
const std::string& realm() const {
return realm_;
}
// The challenge which was issued when creating the handler.
const std::string& challenge() const { return auth_challenge_; }
// Numeric rank based on the challenge's security level. Higher
// numbers are better. Used by HttpAuth::ChooseBestChallenge().
int score() const {
return score_;
}
HttpAuth::Target target() const {
return target_;
}
// Returns the proxy or server which issued the authentication challenge
// that this HttpAuthHandler is handling.
const url::SchemeHostPort& scheme_host_port() const {
return scheme_host_port_;
}
// Returns true if the authentication scheme does not send the username and
// password in the clear.
bool encrypts_identity() const {
return (properties_ & ENCRYPTS_IDENTITY) != 0;
}
// Returns true if the authentication scheme is connection-based, for
// example, NTLM. A connection-based authentication scheme does not support
// preemptive authentication, and must use the same handler object
// throughout the life of an HTTP transaction.
bool is_connection_based() const {
return (properties_ & IS_CONNECTION_BASED) != 0;
}
// This HttpAuthHandler's bound NetLog.
const NetLogWithSource& net_log() const { return net_log_; }
// If NeedsIdentity() returns true, then a subsequent call to
// GenerateAuthToken() must indicate which identity to use. This can be done
// either by passing in a non-empty set of credentials, or an empty set to
// force the handler to use the default credentials. The latter is only an
// option if AllowsDefaultCredentials() returns true.
//
// If NeedsIdentity() returns false, then the handler is already bound to an
// identity and GenerateAuthToken() will ignore any credentials that are
// passed in.
//
// TODO(wtc): Find a better way to handle a multi-round challenge-response
// sequence used by a connection-based authentication scheme.
virtual bool NeedsIdentity();
// Returns whether the default credentials may be used for the |origin| passed
// into |InitFromChallenge|. If true, the user does not need to be prompted
// for username and password to establish credentials.
// NOTE: SSO is a potential security risk.
// TODO(cbentzel): Add a pointer to Firefox documentation about risk.
virtual bool AllowsDefaultCredentials();
// Returns whether explicit credentials can be used with this handler. If
// true the user may be prompted for credentials if an implicit identity
// cannot be determined.
virtual bool AllowsExplicitCredentials();
protected:
enum Property {
ENCRYPTS_IDENTITY = 1 << 0,
IS_CONNECTION_BASED = 1 << 1,
};
// Initializes the handler using a challenge issued by a server.
// |challenge| must be non-nullptr and have already tokenized the
// authentication scheme, but none of the tokens occurring after the
// authentication scheme.
//
// If the request was sent over an encrypted connection, |ssl_info| is valid
// and describes the connection.
//
// NetworkAnonymizationKey is the NetworkAnonymizationKey associated with the
// request.
//
// Implementations are expected to initialize the following members:
// scheme_, realm_, score_, properties_
virtual bool Init(
HttpAuthChallengeTokenizer* challenge,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key) = 0;
// |GenerateAuthTokenImpl()} is the auth-scheme specific implementation
// of generating the next auth token. Callers should use |GenerateAuthToken()|
// which will in turn call |GenerateAuthTokenImpl()|
virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
std::string* auth_token) = 0;
// See HandleAnotherChallenge() above. HandleAuthChallengeImpl is the
// scheme-specific implementation. Callers should use HandleAnotherChallenge()
// instead.
virtual HttpAuth::AuthorizationResult HandleAnotherChallengeImpl(
HttpAuthChallengeTokenizer* challenge) = 0;
// The auth-scheme as an enumerated value.
HttpAuth::Scheme auth_scheme_ = HttpAuth::AUTH_SCHEME_MAX;
// The realm, encoded as UTF-8. Used by "basic" and "digest".
std::string realm_;
// The auth challenge.
std::string auth_challenge_;
// The {scheme, host, port} for the authentication target. Used by "ntlm"
// and "negotiate" to construct the service principal name.
url::SchemeHostPort scheme_host_port_;
// The score for this challenge. Higher numbers are better.
int score_ = -1;
// Whether this authentication request is for a proxy server, or an
// origin server.
HttpAuth::Target target_ = HttpAuth::AUTH_NONE;
// A bitmask of the properties of the authentication scheme.
int properties_ = -1;
private:
void OnGenerateAuthTokenComplete(int rv);
void FinishGenerateAuthToken(int rv);
// NetLog that should be used for logging events generated by this
// HttpAuthHandler.
NetLogWithSource net_log_;
CompletionOnceCallback callback_;
};
} // namespace net
#endif // NET_HTTP_HTTP_AUTH_HANDLER_H_