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

Unified Diff: remoting/host/token_validator_factory_impl.cc

Issue 12313085: Host-side third party token validation (Closed) Base URL: http://git.chromium.org/chromium/src.git@third_party_auth_protocol
Patch Set: Add TODO comment Created 7 years, 8 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 | « remoting/host/token_validator_factory_impl.h ('k') | remoting/protocol/it2me_host_authenticator_factory.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/token_validator_factory_impl.cc
diff --git a/remoting/host/token_validator_factory_impl.cc b/remoting/host/token_validator_factory_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a61bfaabd6d233a7827d9456e7b96eaac7532fc4
--- /dev/null
+++ b/remoting/host/token_validator_factory_impl.cc
@@ -0,0 +1,184 @@
+// Copyright 2013 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 "remoting/host/token_validator_factory_impl.h"
+
+#include <set>
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/json/json_reader.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "base/values.h"
+#include "crypto/random.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/escape.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request_status.h"
+#include "remoting/base/rsa_key_pair.h"
+
+namespace {
+
+// Length in bytes of the cryptographic nonce used to salt the token scope.
+const size_t kNonceLength = 16; // 128 bits.
+
+}
+
+namespace remoting {
+
+class TokenValidatorImpl
+ : public net::URLFetcherDelegate,
+ public protocol::ThirdPartyHostAuthenticator::TokenValidator {
+ public:
+ TokenValidatorImpl(
+ const GURL& token_url,
+ const GURL& token_validation_url,
+ scoped_refptr<RsaKeyPair> key_pair,
+ const std::string& local_jid,
+ const std::string& remote_jid,
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter)
+ : token_url_(token_url),
+ token_validation_url_(token_validation_url),
+ key_pair_(key_pair),
+ request_context_getter_(request_context_getter) {
+ DCHECK(token_url_.is_valid());
+ DCHECK(token_validation_url_.is_valid());
+ DCHECK(key_pair_);
+ token_scope_ = CreateScope(local_jid, remote_jid);
+ }
+
+ virtual ~TokenValidatorImpl() {
+ }
+
+ // TokenValidator interface.
+ virtual void ValidateThirdPartyToken(
+ const std::string& token,
+ const base::Callback<void(
+ const std::string& shared_secret)>& on_token_validated) OVERRIDE {
+ DCHECK(!request_);
+ DCHECK(!on_token_validated.is_null());
+
+ on_token_validated_ = on_token_validated;
+
+ std::string post_body =
+ "code=" + net::EscapeUrlEncodedData(token, true) +
+ "&client_id=" + net::EscapeUrlEncodedData(
+ key_pair_->GetPublicKey(), true) +
+ "&client_secret=" + net::EscapeUrlEncodedData(
+ key_pair_->SignMessage(token), true) +
+ "&grant_type=authorization_code";
+ request_.reset(net::URLFetcher::Create(
+ token_validation_url_, net::URLFetcher::POST, this));
+ request_->SetUploadData("application/x-www-form-urlencoded", post_body);
+ request_->SetRequestContext(request_context_getter_);
+ request_->Start();
+ }
+
+ virtual const GURL& token_url() const OVERRIDE {
+ return token_url_;
+ }
+
+ virtual const std::string& token_scope() const OVERRIDE {
+ return token_scope_;
+ }
+
+ // URLFetcherDelegate interface.
+ virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
+ DCHECK_EQ(request_.get(), source);
+ std::string shared_token = ProcessResponse();
+ on_token_validated_.Run(shared_token);
+ request_.reset();
+ }
+
+ private:
+ bool IsValidScope(const std::string& token_scope) {
+ // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc.
+ return token_scope == token_scope_;
+ }
+
+ static std::string CreateScope(const std::string& local_jid,
+ const std::string& remote_jid) {
+ char nonce_bytes[kNonceLength];
+ crypto::RandBytes(nonce_bytes, kNonceLength);
+ std::string nonce;
+ bool success = base::Base64Encode(nonce_bytes, &nonce);
+ DCHECK(success);
+ return "client:" + remote_jid + " host:" + local_jid + " nonce:" + nonce;
+ }
+
+ std::string ProcessResponse() {
+ // Verify that we got a successful response.
+ int response = request_->GetResponseCode();
+ net::URLRequestStatus status = request_->GetStatus();
+ std::string data;
+ if (!status.is_success() || response != 200) {
+ LOG(ERROR)
+ << "Error " << response << " validating token: '" << data << "'";
+ return std::string();
+ }
+
+ // Decode the JSON data from the response.
+ request_->GetResponseAsString(&data);
+ scoped_ptr<base::Value> value(base::JSONReader::Read(data));
+ DictionaryValue* dict;
+ if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY ||
+ !value->GetAsDictionary(&dict)) {
+ LOG(ERROR) << "Invalid token validation response: '" << data << "'";
+ return std::string();
+ }
+
+ std::string token_scope;
+ dict->GetStringWithoutPathExpansion("scope", &token_scope);
+ if (!IsValidScope(token_scope)) {
+ LOG(ERROR) << "Invalid scope: '" << token_scope
+ << "', expected: '" << token_scope_ <<"'.";
+ return std::string();
+ }
+
+ std::string shared_secret;
+ // Everything is valid, so return the shared secret to the caller.
+ dict->GetStringWithoutPathExpansion("access_token", &shared_secret);
+ return shared_secret;
+ }
+
+ scoped_ptr<net::URLFetcher> request_;
+ GURL token_url_;
+ GURL token_validation_url_;
+ scoped_refptr<RsaKeyPair> key_pair_;
+ std::string token_scope_;
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+ base::Callback<void(const std::string& shared_secret)> on_token_validated_;
+
+ DISALLOW_COPY_AND_ASSIGN(TokenValidatorImpl);
+};
+
+TokenValidatorFactoryImpl::TokenValidatorFactoryImpl(
+ const GURL& token_url,
+ const GURL& token_validation_url,
+ scoped_refptr<RsaKeyPair> key_pair,
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter)
+ : token_url_(token_url),
+ token_validation_url_(token_validation_url),
+ key_pair_(key_pair),
+ request_context_getter_(request_context_getter) {
+}
+
+TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() {
+}
+
+scoped_ptr<protocol::ThirdPartyHostAuthenticator::TokenValidator>
+TokenValidatorFactoryImpl::CreateTokenValidator(
+ const std::string& local_jid,
+ const std::string& remote_jid) {
+ return scoped_ptr<protocol::ThirdPartyHostAuthenticator::TokenValidator>(
+ new TokenValidatorImpl(token_url_, token_validation_url_, key_pair_,
+ local_jid, remote_jid,
+ request_context_getter_));
+}
+
+} // namespace remoting
« no previous file with comments | « remoting/host/token_validator_factory_impl.h ('k') | remoting/protocol/it2me_host_authenticator_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698