Have the authenticating_url_loader cache token per-origin.
R=blundell@chromium.org
Review URL: https://codereview.chromium.org/1161603003
diff --git a/services/authenticating_url_loader/BUILD.gn b/services/authenticating_url_loader/BUILD.gn
index 730270e..5dd07b7 100644
--- a/services/authenticating_url_loader/BUILD.gn
+++ b/services/authenticating_url_loader/BUILD.gn
@@ -25,5 +25,6 @@
"//mojo/services/authenticating_url_loader/public/interfaces",
"//mojo/services/authentication/public/interfaces",
"//mojo/services/network/public/interfaces",
+ "//url",
]
}
diff --git a/services/authenticating_url_loader/authenticating_url_loader_factory_impl.cc b/services/authenticating_url_loader/authenticating_url_loader_factory_impl.cc
index f3e2bbf..5ed1a7d 100644
--- a/services/authenticating_url_loader/authenticating_url_loader_factory_impl.cc
+++ b/services/authenticating_url_loader/authenticating_url_loader_factory_impl.cc
@@ -39,7 +39,7 @@
url_loaders_.push_back(std::unique_ptr<AuthenticatingURLLoaderImpl>(
new AuthenticatingURLLoaderImpl(
loader_request.Pass(), authentication_service_.get(),
- network_service_.get(),
+ network_service_.get(), &cached_tokens_,
base::Bind(&AuthenticatingURLLoaderFactoryImpl::DeleteURLLoader,
base::Unretained(this)))));
}
diff --git a/services/authenticating_url_loader/authenticating_url_loader_factory_impl.h b/services/authenticating_url_loader/authenticating_url_loader_factory_impl.h
index 03f9307..f120cd3 100644
--- a/services/authenticating_url_loader/authenticating_url_loader_factory_impl.h
+++ b/services/authenticating_url_loader/authenticating_url_loader_factory_impl.h
@@ -13,6 +13,7 @@
#include "mojo/services/authenticating_url_loader/public/interfaces/authenticating_url_loader_factory.mojom.h"
#include "mojo/services/authentication/public/interfaces/authentication.mojom.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
+#include "url/gurl.h"
namespace mojo {
@@ -46,6 +47,7 @@
authentication::AuthenticationServicePtr authentication_service_;
NetworkServicePtr network_service_;
std::vector<std::unique_ptr<AuthenticatingURLLoaderImpl>> url_loaders_;
+ std::map<GURL, std::string> cached_tokens_;
};
} // namespace mojo
diff --git a/services/authenticating_url_loader/authenticating_url_loader_impl.cc b/services/authenticating_url_loader/authenticating_url_loader_impl.cc
index 53b0324..df1919a 100644
--- a/services/authenticating_url_loader/authenticating_url_loader_impl.cc
+++ b/services/authenticating_url_loader/authenticating_url_loader_impl.cc
@@ -14,13 +14,15 @@
InterfaceRequest<AuthenticatingURLLoader> request,
authentication::AuthenticationService* authentication_service,
NetworkService* network_service,
+ std::map<GURL, std::string>* cached_tokens,
const Callback<void(AuthenticatingURLLoaderImpl*)>&
connection_error_callback)
: binding_(this, request.Pass()),
authentication_service_(authentication_service),
network_service_(network_service),
connection_error_callback_(connection_error_callback),
- request_authorization_state_(REQUEST_NOT_AUTHORIZED) {
+ request_authorization_state_(REQUEST_INITIAL),
+ cached_tokens_(cached_tokens) {
binding_.set_error_handler(this);
}
@@ -38,11 +40,15 @@
callback.Run(nullptr);
return;
}
- url_ = request->url;
+ url_ = GURL(request->url);
auto_follow_redirects_ = request->auto_follow_redirects;
bypass_cache_ = request->bypass_cache;
headers_ = request->headers.Clone();
pending_request_callback_ = callback;
+ if (cached_tokens_->find(url_.GetOrigin()) != cached_tokens_->end()) {
+ request->headers.push_back("Authorization: Bearer " +
+ (*cached_tokens_)[url_.GetOrigin()]);
+ }
StartNetworkRequest(request.Pass());
}
@@ -50,7 +56,7 @@
const Callback<void(URLResponsePtr)>& callback) {
mojo::String error;
- if (!url_ || !url_loader_) {
+ if (!url_.is_valid() || !url_loader_) {
error = "No redirect to follow";
}
@@ -60,7 +66,7 @@
"called when auto_follow_redirects has been set";
}
- if (username_ || (request_authorization_state_ != REQUEST_NOT_AUTHORIZED)) {
+ if (username_ || (request_authorization_state_ != REQUEST_INITIAL)) {
error = "Not in the right state to follow a redirect";
}
@@ -88,9 +94,9 @@
void AuthenticatingURLLoaderImpl::OnLoadComplete(URLResponsePtr response) {
if (response->redirect_url) {
- url_ = response->redirect_url;
+ url_ = GURL(response->redirect_url);
username_ = nullptr;
- request_authorization_state_ = REQUEST_NOT_AUTHORIZED;
+ request_authorization_state_ = REQUEST_INITIAL;
if (auto_follow_redirects_) {
FollowRedirectInternal();
@@ -105,38 +111,39 @@
url_loader_.reset();
if (response->status_code != 401 || !authentication_service_ ||
- request_authorization_state_ == REQUEST_AUTHORIZED_WITH_FRESH_TOKEN) {
+ request_authorization_state_ == REQUEST_USED_FRESH_AUTH_SERVICE_TOKEN) {
pending_request_callback_.Run(response.Pass());
return;
}
pending_response_ = response.Pass();
- if (request_authorization_state_ == REQUEST_NOT_AUTHORIZED) {
+ if (request_authorization_state_ == REQUEST_INITIAL) {
DCHECK(!username_);
- request_authorization_state_ = REQUEST_AUTHORIZED_WITH_CACHED_TOKEN;
+ request_authorization_state_ = REQUEST_USED_CURRENT_AUTH_SERVICE_TOKEN;
authentication_service_->SelectAccount(
base::Bind(&AuthenticatingURLLoaderImpl::OnAccountSelected,
base::Unretained(this)));
return;
}
- DCHECK(request_authorization_state_ == REQUEST_AUTHORIZED_WITH_CACHED_TOKEN);
+ DCHECK(request_authorization_state_ ==
+ REQUEST_USED_CURRENT_AUTH_SERVICE_TOKEN);
// Clear the cached token in case the failure was due to that token being
// stale and try again. If a fresh token doesn't work, we'll have to give up.
DCHECK(authentication_service_);
DCHECK(username_);
authentication_service_->ClearOAuth2Token(token_);
token_ = String();
- request_authorization_state_ = REQUEST_AUTHORIZED_WITH_FRESH_TOKEN;
+ request_authorization_state_ = REQUEST_USED_FRESH_AUTH_SERVICE_TOKEN;
OnAccountSelected(username_, String());
}
void AuthenticatingURLLoaderImpl::FollowRedirectInternal() {
- DCHECK(url_);
+ DCHECK(url_.is_valid());
DCHECK(url_loader_);
DCHECK(!username_);
- DCHECK(request_authorization_state_ == REQUEST_NOT_AUTHORIZED);
+ DCHECK(request_authorization_state_ == REQUEST_INITIAL);
url_loader_->FollowRedirect(base::Bind(
&AuthenticatingURLLoaderImpl::OnLoadComplete, base::Unretained(this)));
@@ -171,6 +178,7 @@
}
DCHECK(token);
+ (*cached_tokens_)[url_.GetOrigin()] = token;
token_ = token;
mojo::Array<mojo::String> headers(0);
if (headers_)
@@ -178,7 +186,7 @@
headers.push_back("Authorization: Bearer " + token.get());
URLRequestPtr request(mojo::URLRequest::New());
- request->url = url_;
+ request->url = url_.spec();
request->auto_follow_redirects = false;
request->bypass_cache = bypass_cache_;
request->headers = headers.Pass();
diff --git a/services/authenticating_url_loader/authenticating_url_loader_impl.h b/services/authenticating_url_loader/authenticating_url_loader_impl.h
index a3ef28f..f2ee787 100644
--- a/services/authenticating_url_loader/authenticating_url_loader_impl.h
+++ b/services/authenticating_url_loader/authenticating_url_loader_impl.h
@@ -10,15 +10,16 @@
#include "mojo/services/authenticating_url_loader/public/interfaces/authenticating_url_loader.mojom.h"
#include "mojo/services/authentication/public/interfaces/authentication.mojom.h"
#include "mojo/services/network/public/interfaces/url_loader.mojom.h"
+#include "url/gurl.h"
namespace mojo {
class NetworkService;
enum RequestAuthorizationState {
- REQUEST_NOT_AUTHORIZED,
- REQUEST_AUTHORIZED_WITH_CACHED_TOKEN,
- REQUEST_AUTHORIZED_WITH_FRESH_TOKEN,
+ REQUEST_INITIAL,
+ REQUEST_USED_CURRENT_AUTH_SERVICE_TOKEN,
+ REQUEST_USED_FRESH_AUTH_SERVICE_TOKEN,
};
class AuthenticatingURLLoaderImpl : public AuthenticatingURLLoader,
@@ -28,6 +29,7 @@
InterfaceRequest<AuthenticatingURLLoader> request,
authentication::AuthenticationService* authentication_service,
NetworkService* network_service,
+ std::map<GURL, std::string>* cached_tokens,
const Callback<void(AuthenticatingURLLoaderImpl*)>&
connection_error_callback);
~AuthenticatingURLLoaderImpl() override;
@@ -61,13 +63,14 @@
URLLoaderPtr url_loader_;
URLResponsePtr pending_response_;
RequestAuthorizationState request_authorization_state_;
- String url_;
+ GURL url_;
bool auto_follow_redirects_;
bool bypass_cache_;
Array<String> headers_;
String username_;
String token_;
Callback<void(URLResponsePtr)> pending_request_callback_;
+ std::map<GURL, std::string>* cached_tokens_;
};
} // namespace mojo