Skip to content

Commit

Permalink
Add Single Sign On support to HTTP Authentication handlers.
Browse files Browse the repository at this point in the history
Currently this is implemented on Windows for the NTLM and Negotiate schemes.

This CL does not introduce the hooks to actually use Single Sign On in response to a 401/407 request - that will come in a later CL.

This behavior is disabled for now as well.

BUG=29862
TEST=Ran unittests, and Chrome against a server with authentication challenges.

Review URL: http://codereview.chromium.org/555174

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38227 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
cbentzel@chromium.org committed Feb 5, 2010
1 parent 5502208 commit ac3fa8e
Show file tree
Hide file tree
Showing 21 changed files with 457 additions and 185 deletions.
9 changes: 8 additions & 1 deletion net/base/net_error_list.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

Expand Down Expand Up @@ -305,6 +305,13 @@ NET_ERROR(NO_SUPPORTED_PROXIES, -336)
// There is a FLIP protocol framing error.
NET_ERROR(FLIP_PROTOCOL_ERROR, -337)

// Credentials could not be estalished during HTTP Authentication.
NET_ERROR(INVALID_AUTH_CREDENTIALS, -338)

// An HTTP Authentication scheme was tried which is not supported on this
// machine.
NET_ERROR(UNSUPPORTED_AUTH_SCHEME, -339)

// The cache does not have the requested entry.
NET_ERROR(CACHE_MISS, -400)

Expand Down
29 changes: 20 additions & 9 deletions net/http/http_auth_cache_unittest.cc
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

#include "base/string_util.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth_cache.h"

#include "testing/gtest/include/gtest/gtest.h"
Expand All @@ -23,11 +24,20 @@ class MockAuthHandler : public HttpAuthHandler {
properties_ = 0;
}

virtual std::string GenerateCredentials(const std::wstring&,
const std::wstring&,
const HttpRequestInfo*,
const ProxyInfo*) {
return "mock-credentials"; // Unused.
virtual int GenerateAuthToken(const std::wstring&,
const std::wstring&,
const HttpRequestInfo*,
const ProxyInfo*,
std::string* auth_token) {
*auth_token = "mock-credentials";
return OK;
}

virtual int GenerateDefaultAuthToken(const HttpRequestInfo*,
const ProxyInfo*,
std::string* auth_token) {
*auth_token = "mock-credentials";
return OK;
}

protected:
Expand All @@ -52,12 +62,12 @@ TEST(HttpAuthCacheTest, Basic) {
scoped_refptr<HttpAuthHandler> realm1_handler =
new MockAuthHandler("basic", "Realm1", HttpAuth::AUTH_SERVER);
cache.Add(origin, realm1_handler, L"realm1-user", L"realm1-password",
"/foo/bar/index.html");
"/foo/bar/index.html");

scoped_refptr<HttpAuthHandler> realm2_handler =
new MockAuthHandler("basic", "Realm2", HttpAuth::AUTH_SERVER);
cache.Add(origin, realm2_handler, L"realm2-user", L"realm2-password",
"/foo2/index.html");
"/foo2/index.html");

scoped_refptr<HttpAuthHandler> realm3_handler =
new MockAuthHandler("basic", "Realm3", HttpAuth::AUTH_PROXY);
Expand Down Expand Up @@ -227,7 +237,8 @@ class HttpAuthCacheEvictionTest : public testing::Test {
}

void AddPathToRealm(int realm_i, int path_i) {
scoped_refptr<HttpAuthHandler> handler = new MockAuthHandler("basic",
scoped_refptr<HttpAuthHandler> handler = new MockAuthHandler(
"basic",
GenerateRealm(realm_i), HttpAuth::AUTH_SERVER);
std::string path = GeneratePath(realm_i, path_i);
cache_.Add(origin_, handler, L"username", L"password", path);
Expand Down
6 changes: 4 additions & 2 deletions net/http/http_auth_handler.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

#include "base/logging.h"
#include "net/http/http_auth_handler.h"

#include "base/logging.h"
#include "net/base/net_errors.h"

namespace net {

bool HttpAuthHandler::InitFromChallenge(std::string::const_iterator begin,
Expand Down
33 changes: 27 additions & 6 deletions net/http/http_auth_handler.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

Expand Down Expand Up @@ -72,11 +72,32 @@ class HttpAuthHandler : public base::RefCounted<HttpAuthHandler> {
// single-round schemes.
virtual bool IsFinalRound() { return true; }

// Generate the Authorization header value.
virtual std::string GenerateCredentials(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy) = 0;
// 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.
virtual bool AllowDefaultCredentials() { return false; }

// TODO(cbentzel): Separate providing credentials from generating the
// authentication token in the API.

// Generates an authentication token.
// The return value is an error code. If the code is not |OK|, the value of
// |*auth_token| is unspecified.
// |auth_token| is a return value and must be non-NULL.
virtual int GenerateAuthToken(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token) = 0;

// Generates an authentication token using default credentials.
// The return value is an error code. If the code is not |OK|, the value of
// |*auth_token| is unspecified.
// |auth_token| is a return value and must be non-NULL.
// This should only be called after |AllowDefaultCredentials| returns true.
virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token) = 0;

protected:
enum Property {
Expand Down
27 changes: 21 additions & 6 deletions net/http/http_auth_handler_basic.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

Expand All @@ -8,6 +8,7 @@

#include "base/base64.h"
#include "base/string_util.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth.h"

namespace net {
Expand Down Expand Up @@ -41,17 +42,31 @@ bool HttpAuthHandlerBasic::Init(std::string::const_iterator challenge_begin,
return challenge_tok.valid();
}

std::string HttpAuthHandlerBasic::GenerateCredentials(
int HttpAuthHandlerBasic::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo*,
const ProxyInfo*) {
const ProxyInfo*,
std::string* auth_token) {
// TODO(eroman): is this the right encoding of username/password?
std::string base64_username_password;
if (!base::Base64Encode(WideToUTF8(username) + ":" + WideToUTF8(password),
&base64_username_password))
return std::string(); // FAIL
return std::string("Basic ") + base64_username_password;
&base64_username_password)) {
LOG(ERROR) << "Unexpected problem Base64 encoding.";
return ERR_UNEXPECTED;
}
*auth_token = "Basic " + base64_username_password;
return OK;
}

int HttpAuthHandlerBasic::GenerateDefaultAuthToken(
const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token) {
NOTREACHED();
LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
return ERR_NOT_IMPLEMENTED;
}


} // namespace net
17 changes: 12 additions & 5 deletions net/http/http_auth_handler_basic.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

Expand All @@ -12,10 +12,17 @@ namespace net {
// Code for handling http basic authentication.
class HttpAuthHandlerBasic : public HttpAuthHandler {
public:
virtual std::string GenerateCredentials(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo*,
const ProxyInfo*);
virtual int GenerateAuthToken(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo*,
const ProxyInfo*,
std::string* auth_token);

virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token);


protected:
virtual bool Init(std::string::const_iterator challenge_begin,
std::string::const_iterator challenge_end);
Expand Down
15 changes: 10 additions & 5 deletions net/http/http_auth_handler_basic_unittest.cc
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

#include "testing/gtest/include/gtest/gtest.h"

#include "base/basictypes.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth_handler_basic.h"

namespace net {

TEST(HttpAuthHandlerBasicTest, GenerateCredentials) {
TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) {
static const struct {
const wchar_t* username;
const wchar_t* password;
Expand All @@ -30,9 +31,13 @@ TEST(HttpAuthHandlerBasicTest, GenerateCredentials) {
bool ok = basic->InitFromChallenge(challenge.begin(), challenge.end(),
HttpAuth::AUTH_SERVER, origin);
EXPECT_TRUE(ok);
std::string credentials = basic->GenerateCredentials(tests[i].username,
tests[i].password,
NULL, NULL);
std::string credentials;
int rv = basic->GenerateAuthToken(tests[i].username,
tests[i].password,
NULL,
NULL,
&credentials);
EXPECT_EQ(OK, rv);
EXPECT_STREQ(tests[i].expected_credentials, credentials.c_str());
}
}
Expand Down
28 changes: 20 additions & 8 deletions net/http/http_auth_handler_digest.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

Expand All @@ -7,6 +7,7 @@
#include "base/md5.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_info.h"
Expand Down Expand Up @@ -77,11 +78,12 @@ std::string HttpAuthHandlerDigest::AlgorithmToString(int algorithm) {
}
}

std::string HttpAuthHandlerDigest::GenerateCredentials(
int HttpAuthHandlerDigest::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy) {
const ProxyInfo* proxy,
std::string* auth_token) {
// Generate a random client nonce.
std::string cnonce = GenerateNonce();

Expand All @@ -97,11 +99,21 @@ std::string HttpAuthHandlerDigest::GenerateCredentials(
std::string path;
GetRequestMethodAndPath(request, proxy, &method, &path);

return AssembleCredentials(method, path,
// TODO(eroman): is this the right encoding?
WideToUTF8(username),
WideToUTF8(password),
cnonce, nonce_count);
*auth_token = AssembleCredentials(method, path,
// TODO(eroman): is this the right encoding?
WideToUTF8(username),
WideToUTF8(password),
cnonce, nonce_count);
return OK;
}

int HttpAuthHandlerDigest::GenerateDefaultAuthToken(
const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token) {
NOTREACHED();
LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
return ERR_NOT_IMPLEMENTED;
}

void HttpAuthHandlerDigest::GetRequestMethodAndPath(
Expand Down
15 changes: 10 additions & 5 deletions net/http/http_auth_handler_digest.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2010 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.

Expand All @@ -15,10 +15,15 @@ namespace net {
// Code for handling http digest authentication.
class HttpAuthHandlerDigest : public HttpAuthHandler {
public:
virtual std::string GenerateCredentials(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy);
virtual int GenerateAuthToken(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token);

virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token);

protected:
virtual bool Init(std::string::const_iterator challenge_begin,
Expand Down
14 changes: 10 additions & 4 deletions net/http/http_auth_handler_negotiate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler {

virtual bool IsFinalRound();

virtual std::string GenerateCredentials(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy);
virtual bool AllowDefaultCredentials();

virtual int GenerateAuthToken(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token);

virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
const ProxyInfo* proxy,
std::string* auth_token);

protected:
virtual bool Init(std::string::const_iterator challenge_begin,
Expand Down
Loading

0 comments on commit ac3fa8e

Please sign in to comment.