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