Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(592)

Unified Diff: net/http/http_auth_controller_unittest.cc

Issue 1391053002: [net/http auth] Make HttpAuthHandler challenge handling asynchronous. Base URL: https://chromium.googlesource.com/chromium/src.git@auth-handler-init-split
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/http_auth_controller.cc ('k') | net/http/http_auth_gssapi_posix.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_auth_controller_unittest.cc
diff --git a/net/http/http_auth_controller_unittest.cc b/net/http/http_auth_controller_unittest.cc
index 1235156a38a5bd52b87aa88944aeed666900cb07..e90e578e67b27f22a570b04174512d50bf19e3e5 100644
--- a/net/http/http_auth_controller_unittest.cc
+++ b/net/http/http_auth_controller_unittest.cc
@@ -4,18 +4,30 @@
#include "net/http/http_auth_controller.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/http/http_auth.h"
#include "net/http/http_auth_cache.h"
#include "net/http/http_auth_challenge_tokenizer.h"
+#include "net/http/http_auth_filter.h"
+#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_handler_mock.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
#include "net/http/http_util.h"
+#include "net/http/mock_allow_url_security_manager.h"
#include "net/log/net_log.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::ValuesIn;
+
namespace net {
namespace {
@@ -49,6 +61,10 @@ void RunSingleRoundAuthTest(HandlerRunMode run_mode,
int handler_rv,
int expected_controller_rv,
SchemeState scheme_state) {
+ SCOPED_TRACE(::testing::Message()
+ << "run_mode:" << run_mode << " handler_rv:" << handler_rv
+ << " expected_controller_rv:" << expected_controller_rv
+ << " scheme_state:" << scheme_state);
BoundNetLog dummy_log;
HttpAuthCache dummy_auth_cache;
@@ -56,10 +72,11 @@ void RunSingleRoundAuthTest(HandlerRunMode run_mode,
request.method = "GET";
request.url = GURL("http://example.com");
- scoped_refptr<HttpResponseHeaders> headers(HeadersFromString(
+ HttpResponseInfo response;
+ response.headers = HeadersFromString(
"HTTP/1.1 407\r\n"
"Proxy-Authenticate: MOCK foo\r\n"
- "\r\n"));
+ "\r\n");
HttpAuthHandlerMock::Factory auth_handler_factory;
scoped_ptr<HttpAuthHandlerMock> auth_handler(new HttpAuthHandlerMock());
@@ -72,20 +89,22 @@ void RunSingleRoundAuthTest(HandlerRunMode run_mode,
new HttpAuthController(HttpAuth::AUTH_PROXY,
GURL("http://example.com"),
&dummy_auth_cache, &auth_handler_factory));
- ASSERT_EQ(OK,
- controller->HandleAuthChallenge(headers, false, false, dummy_log));
+ TestCompletionCallback completion_callback;
+ int result = controller->HandleAuthChallenge(
+ response, completion_callback.callback(), dummy_log);
+ ASSERT_EQ(OK, completion_callback.GetResult(result));
ASSERT_TRUE(controller->HaveAuthHandler());
+ EXPECT_FALSE(controller->HaveAuth());
controller->ResetAuth(
AuthCredentials(base::ASCIIToUTF16("a"), base::ASCIIToUTF16("b")));
EXPECT_TRUE(controller->HaveAuth());
TestCompletionCallback callback;
- EXPECT_EQ((run_mode == RUN_HANDLER_ASYNC)? ERR_IO_PENDING:
- expected_controller_rv,
- controller->MaybeGenerateAuthToken(&request, callback.callback(),
- dummy_log));
+ result = controller->MaybeGenerateAuthToken(&request, callback.callback(),
+ dummy_log);
if (run_mode == RUN_HANDLER_ASYNC)
- EXPECT_EQ(expected_controller_rv, callback.WaitForResult());
+ ASSERT_EQ(ERR_IO_PENDING, result);
+ EXPECT_EQ(expected_controller_rv, callback.GetResult(result));
EXPECT_EQ((scheme_state == SCHEME_IS_DISABLED),
controller->IsAuthSchemeDisabled("mock"));
}
@@ -95,24 +114,30 @@ void RunSingleRoundAuthTest(HandlerRunMode run_mode,
// If an HttpAuthHandler returns an error code that indicates a
// permanent error, the HttpAuthController should disable the scheme
// used and retry the request.
-TEST(HttpAuthControllerTest, PermanentErrors) {
-
- // Run a synchronous handler that returns
- // ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS. We expect a return value
- // of OK from the controller so we can retry the request.
+TEST(HttpAuthControllerTest, PermanentErrors_Sync) {
RunSingleRoundAuthTest(RUN_HANDLER_SYNC,
ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS,
OK, SCHEME_IS_DISABLED);
+}
- // Now try an async handler that returns
- // ERR_MISSING_AUTH_CREDENTIALS. Async and sync handlers invoke
- // different code paths in HttpAuthController when generating
- // tokens.
+// Similar to the above test. Now try an async handler that returns
+// ERR_MISSING_AUTH_CREDENTIALS. Async and sync handlers invoke different code
+// paths in HttpAuthController when generating tokens.
+TEST(HttpAuthControllerTest, PermanentErrors_Async) {
RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_MISSING_AUTH_CREDENTIALS, OK,
SCHEME_IS_DISABLED);
+}
- // If a non-permanent error is returned by the handler, then the
- // controller should report it unchanged.
+// If a non-permanent error is returned by the handler, then the controller
+// should leave the scheme enabled.
+TEST(HttpAuthControllerTest, NonPermanentErrors_Sync) {
+ RunSingleRoundAuthTest(RUN_HANDLER_SYNC, ERR_INVALID_AUTH_CREDENTIALS,
+ ERR_INVALID_AUTH_CREDENTIALS, SCHEME_IS_ENABLED);
+}
+
+// If a non-permanent error is returned by the handler, then the controller
+// should leave the scheme enabled.
+TEST(HttpAuthControllerTest, NonPermanentErrors_Async) {
RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_INVALID_AUTH_CREDENTIALS,
ERR_INVALID_AUTH_CREDENTIALS, SCHEME_IS_ENABLED);
}
@@ -127,11 +152,12 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) {
request.url = GURL("http://example.com");
HttpRequestHeaders request_headers;
- scoped_refptr<HttpResponseHeaders> headers(
- HeadersFromString("HTTP/1.1 401\r\n"
- "WWW-Authenticate: Ernie\r\n"
- "WWW-Authenticate: Bert\r\n"
- "\r\n"));
+ HttpResponseInfo response;
+ response.headers = HeadersFromString(
+ "HTTP/1.1 401\r\n"
+ "WWW-Authenticate: Ernie\r\n"
+ "WWW-Authenticate: Bert\r\n"
+ "\r\n");
HttpAuthHandlerMock::Factory auth_handler_factory;
@@ -148,16 +174,17 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) {
new HttpAuthController(HttpAuth::AUTH_SERVER,
GURL("http://example.com"),
&dummy_auth_cache, &auth_handler_factory));
- ASSERT_EQ(OK,
- controller->HandleAuthChallenge(headers, false, false, dummy_log));
+ TestCompletionCallback completion_calback;
+ int rv = controller->HandleAuthChallenge(
+ response, completion_calback.callback(), dummy_log);
+ ASSERT_EQ(OK, completion_calback.GetResult(rv));
ASSERT_TRUE(controller->HaveAuthHandler());
- controller->ResetAuth(AuthCredentials());
EXPECT_TRUE(controller->HaveAuth());
EXPECT_FALSE(auth_handler_factory.HaveAuthHandlers());
// Should only succeed if we are using the "Ernie" MockHandler.
- EXPECT_EQ(OK, controller->MaybeGenerateAuthToken(
- &request, CompletionCallback(), dummy_log));
+ ASSERT_EQ(OK, controller->MaybeGenerateAuthToken(
+ &request, completion_calback.callback(), dummy_log));
controller->AddAuthorizationHeader(&request_headers);
// Handlers for the second attempt. Neither should be used to generate a
@@ -182,9 +209,12 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) {
// Once a token is generated, simulate the receipt of a server response
// indicating that the authentication attempt was rejected.
- ASSERT_EQ(OK,
- controller->HandleAuthChallenge(headers, false, false, dummy_log));
+ TestCompletionCallback completion_calback_rejected;
+ rv = controller->HandleAuthChallenge(
+ response, completion_calback_rejected.callback(), dummy_log);
+ ASSERT_EQ(OK, completion_calback_rejected.GetResult(rv));
ASSERT_TRUE(controller->HaveAuthHandler());
+ EXPECT_FALSE(controller->HaveAuth());
controller->ResetAuth(AuthCredentials(base::ASCIIToUTF16("Hello"),
base::string16()));
EXPECT_TRUE(controller->HaveAuth());
@@ -193,7 +223,445 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) {
// Should only succeed if we are using the "Bert" MockHandler.
EXPECT_EQ(OK, controller->MaybeGenerateAuthToken(
- &request, CompletionCallback(), dummy_log));
+ &request, completion_calback.callback(), dummy_log));
}
+namespace {
+
+struct ChallengeResponse {
+ const char* const response_headers = nullptr;
+ const char* const authorization_header = nullptr;
+
+ ChallengeResponse(const char* const response_headers,
+ const char* const authorization_header)
+ : response_headers(response_headers),
+ authorization_header(authorization_header) {}
+};
+
+struct MockAuthHandler {
+ std::string scheme;
+ int init_rv = OK;
+ int generate_rv = OK;
+
+ MockAuthHandler(const std::string& scheme, int int_rv, int generate_rv)
+ : scheme(scheme), init_rv(int_rv), generate_rv(generate_rv) {}
+};
+
+struct ChallengeResponseTestCase {
+ std::vector<ChallengeResponse> rounds;
+ std::vector<MockAuthHandler> handlers;
+ bool run_handler_async = false;
+
+ ChallengeResponseTestCase& WithChallengeResponse(
+ const char* response_headers,
+ const char* authorization_header) {
+ rounds.push_back(ChallengeResponse(response_headers, authorization_header));
+ return *this;
+ }
+
+ ChallengeResponseTestCase& WithHandler(const base::StringPiece& scheme,
+ int init_rv,
+ int generate_rv) {
+ handlers.push_back(
+ MockAuthHandler(scheme.as_string(), init_rv, generate_rv));
+ return *this;
+ }
+};
+
+std::vector<ChallengeResponseTestCase> SyncAndAsync(
+ const ChallengeResponseTestCase& test_case) {
+ std::vector<ChallengeResponseTestCase> test_cases;
+ ChallengeResponseTestCase test_case_copy = test_case;
+
+ test_case_copy.run_handler_async = false;
+ test_cases.push_back(test_case_copy);
+
+ test_case_copy.run_handler_async = true;
+ test_cases.push_back(test_case_copy);
+ return test_cases;
+}
+
+class HttpAuthControllerTest
+ : public ::testing::TestWithParam<ChallengeResponseTestCase> {};
+
+} // namespace
+
+TEST_P(HttpAuthControllerTest, Run) {
+ const ChallengeResponseTestCase& params = GetParam();
+ BoundNetLog dummy_log;
+ HttpAuthCache dummy_auth_cache;
+ GURL url("http://example.com");
+ HttpAuthHandlerMock::Factory auth_factory;
+
+ for (const auto& handler : params.handlers) {
+ scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock);
+ mock_handler->set_expected_auth_scheme(handler.scheme);
+ mock_handler->set_expect_multiple_challenges(handler.scheme == "ntlm" ||
+ handler.scheme == "negotiate");
+ mock_handler->SetInitExpectation(params.run_handler_async, handler.init_rv);
+ mock_handler->SetGenerateExpectation(params.run_handler_async,
+ handler.generate_rv);
+ auth_factory.AddMockHandler(mock_handler.Pass(),
+ HttpAuthHandlerCreateReason::CHALLENGE);
+ }
+
+ HttpRequestInfo request_info;
+
+ scoped_refptr<HttpAuthController> auth_controller(new HttpAuthController(
+ HttpAuth::AUTH_SERVER, url, &dummy_auth_cache, &auth_factory));
+ for (const auto& round : params.rounds) {
+ if (!round.response_headers)
+ break;
+ HttpResponseInfo response_info;
+ response_info.headers = HeadersFromString(round.response_headers);
+ TestCompletionCallback callback;
+
+ int result = auth_controller->HandleAuthChallenge(
+ response_info, callback.callback(), dummy_log);
+ EXPECT_EQ(OK, callback.GetResult(result));
+
+ if (!auth_controller->HaveAuthHandler()) {
+ EXPECT_STREQ("", round.authorization_header);
+ continue;
+ }
+
+ if (!auth_controller->HaveAuth()) {
+ auth_controller->ResetAuth(
+ AuthCredentials(base::ASCIIToUTF16("a"), base::ASCIIToUTF16("b")));
+ }
+
+ result = auth_controller->MaybeGenerateAuthToken(
+ &request_info, callback.callback(), dummy_log);
+ EXPECT_EQ(OK, callback.GetResult(result));
+ HttpRequestHeaders headers;
+ auth_controller->AddAuthorizationHeader(&headers);
+ std::string authorization_header;
+ headers.GetHeader(
+ HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_SERVER),
+ &authorization_header);
+ EXPECT_STREQ(round.authorization_header, authorization_header.c_str());
+ }
+
+ EXPECT_FALSE(auth_factory.HaveAuthHandlers());
+}
+
+// Picks Basic because that's the only supported scheme.
+INSTANTIATE_TEST_CASE_P(
+ PickSupportedScheme,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse(
+ "HTTP/1.1 401\n"
+ "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n"
+ "www-authenticate: Basic realm=\"BasicRealm\"\n",
+ "basic auth_token,realm=\"BasicRealm\"")
+ .WithHandler("basic", OK, OK))));
+
+// No supported schemes.
+INSTANTIATE_TEST_CASE_P(
+ NoSupportedSchemes,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(ChallengeResponseTestCase().WithChallengeResponse(
+ "HTTP/1.1 401\n"
+ "Y: Digest realm=\"FooBar\", nonce=\"aaaaaaaaaa\"\n"
+ "www-authenticate: Fake realm=\"FooBar\"\n",
+ ""))));
+
+// Pick Digest over Basic.
+INSTANTIATE_TEST_CASE_P(
+ DigestOverBasic,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse(
+ "HTTP/1.1 401\n"
+ "www-authenticate: Basic realm=\"FooBar\"\n"
+ "www-authenticate: Fake realm=\"FooBar\"\n"
+ "www-authenticate: nonce=\"aaaaaaaaaa\"\n"
+ "www-authenticate: Digest realm=\"DigestRealm\", "
+ "nonce=\"aaaaaaaaaa\"\n",
+ "digest auth_token,realm=\"DigestRealm\", nonce=\"aaaaaaaaaa\"")
+ .WithHandler("digest", OK, OK))));
+
+// Handle an empty header correctly.
+INSTANTIATE_TEST_CASE_P(
+ EmptyHeader,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(ChallengeResponseTestCase().WithChallengeResponse(
+ "HTTP/1.1 401\n"
+ "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n"
+ "www-authenticate:\n",
+ ""))));
+
+// NTLM appears earlier in the list, Negotiate is preferred.
+INSTANTIATE_TEST_CASE_P(
+ NegotiateOverNTLM,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: NTLM\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK))));
+
+// Two rounds. Basic isn't connection oriented and will use up a new handler
+// for the second challenge.
+INSTANTIATE_TEST_CASE_P(
+ SecondChallengeForBasic,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic first_round\n",
+ "basic auth_token,first_round")
+ .WithHandler("basic", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic second_round\n",
+ "basic auth_token,second_round")
+ .WithHandler("basic", OK, OK))));
+
+// Correctly deal with a missing challenge for the second round.
+INSTANTIATE_TEST_CASE_P(
+ SecondChallengeIsMissing,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic first_round\n",
+ "basic auth_token,first_round")
+ .WithHandler("basic", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n", ""))));
+
+// Correctly deal with an empty challenge for the second round.
+INSTANTIATE_TEST_CASE_P(
+ SecondChallengeIsEmpty,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic first_round\n",
+ "basic auth_token,first_round")
+ .WithHandler("basic", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate:\n",
+ ""))));
+
+// The second round introduces a preferred scheme.
+INSTANTIATE_TEST_CASE_P(
+ SecondChallengeHasPreferredScheme,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic first_round\n",
+ "basic auth_token,first_round")
+ .WithHandler("basic", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic second_round\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK))));
+
+// If there are two challenges, then the auth controller should pick the first
+// one.
+INSTANTIATE_TEST_CASE_P(
+ MultipleChallengesForSameScheme,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic first_round\n",
+ "basic auth_token,first_round")
+ .WithHandler("basic", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic second_round_1\n"
+ "WWW-Authenticate: Basic second_round_2\n",
+ "basic auth_token,second_round_1")
+ .WithHandler("basic", OK, OK))));
+
+// As above, but the handler will reject the first challenge of the second
+// round. The auth controller should use the second challenge instead.
+INSTANTIATE_TEST_CASE_P(
+ RejectChallengeForTheSameSchemeInSingleResponse,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic first_round\n",
+ "basic auth_token,first_round")
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic second_round_1\n"
+ "WWW-Authenticate: Basic second_round_2\n",
+ "basic auth_token,second_round_2")
+ .WithHandler("basic", OK, OK)
+ .WithHandler("basic", ERR_INVALID_AUTH_CREDENTIALS, OK)
+ .WithHandler("basic", OK, OK))));
+
+// Connection based schemes will treat new auth challenges for the same scheme
+// as acceptance and continuance of the current handshake if there's a
+// parameter.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_Continuations,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate foo\n",
+ "negotiate continuation,foo"))));
+
+// As above, but picks the first challenge for the second round.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_ContinuationsWithMultipleChallenges,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate foo\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate continuation,foo"))));
+
+// As above. The first challenge in the second round counts as a rejection, so
+// the controller should create a new handler and restart the handshake.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_ContinuationsWithMultipleChallengesAndRejection,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n"
+ "WWW-Authenticate: Negotiate continuation\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK))));
+
+// Multiround authentication with rejection. The rejection comes in the form of
+// an empty challenge for the same scheme.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_RejectionViaEmptyChallenge,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK))));
+
+// Multiround authentication with rejection. The rejection comes in the form of
+// a response with no challenge for the original scheme.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_RejectionViaSchemeChange,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic foo\n",
+ "basic auth_token,foo")
+ .WithHandler("basic", OK, OK))));
+
+// Dealing with empty and missing second round challenges for connection
+// oriented schemes.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_EmptySecondChallenge,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate:\n",
+ ""))));
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_MissingSecondChallenge,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n", ""))));
+
+// Should pick matching challenge even if other challenges are present.
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_PicksCorrectChallenge,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n",
+ "negotiate auth_token")
+ .WithHandler("negotiate", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic foo\n"
+ "WWW-Authenticate: Negotiate bar\n",
+ "negotiate continuation,bar"))));
+INSTANTIATE_TEST_CASE_P(
+ MultiRoundAuth_PicksCorrectChallengeWithPreferredChallenge,
+ HttpAuthControllerTest,
+ ValuesIn(
+ SyncAndAsync(ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: NTLM\n",
+ "ntlm auth_token")
+ .WithHandler("ntlm", OK, OK)
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Negotiate\n"
+ "WWW-Authenticate: NTLM bar\n",
+ "ntlm continuation,bar"))));
+
+// If an auth handler fails to initialize, the controller should try the next
+// suitable challenge.
+INSTANTIATE_TEST_CASE_P(
+ FallThroughInvalidHeaders,
+ HttpAuthControllerTest,
+ ValuesIn(SyncAndAsync(
+ ChallengeResponseTestCase()
+ .WithChallengeResponse("HTTP/1.1 401\n"
+ "WWW-Authenticate: Basic abc;\n"
+ "WWW-Authenticate: Digest abc;\n"
+ "WWW-Authenticate: Basic valid",
+ "basic auth_token,valid")
+ // The first challenge chosen is Digest. But the handler fails.
+ .WithHandler("digest", ERR_INVALID_AUTH_CREDENTIALS, OK)
+ // Next the controller tries the first Basic challenge, which also
+ // fails.
+ .WithHandler("basic", ERR_INVALID_AUTH_CREDENTIALS, OK)
+ // Finally, the second Basic challenge succeeds.
+ .WithHandler("basic", OK, OK))));
+
+// Identities are used in the correct order.
+TEST(HttpAuthControllerTest, IdentityPriorityOrder) {}
+
+// Identities from abstract sources should be available to a new handler if the
+// server changes authentication scheme or if all identity sources were
+// exhausted for a handler.
+TEST(HttpAuthControllerTest, IdentityReuseAcrossHandlers) {}
+
} // namespace net
« no previous file with comments | « net/http/http_auth_controller.cc ('k') | net/http/http_auth_gssapi_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698