You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2017/03/15 18:36:15 UTC

[2/3] mesos git commit: Enabled loading multiple HTTP authenticators in Mesos.

Enabled loading multiple HTTP authenticators in Mesos.

This patch updates the Mesos code to allow master and agent
to load multiple HTTP authenticator modules.

Review: https://reviews.apache.org/r/56476/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/af5af3f9
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/af5af3f9
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/af5af3f9

Branch: refs/heads/master
Commit: af5af3f9f8e2d736f3aaa244a4e254230a8467f0
Parents: 0804be3
Author: Greg Mann <gr...@mesosphere.io>
Authored: Wed Mar 15 19:35:55 2017 +0100
Committer: Vinod Kone <vi...@gmail.com>
Committed: Wed Mar 15 19:35:55 2017 +0100

----------------------------------------------------------------------
 src/common/http.cpp | 127 +++++++++++++++++++++++++++++++----------------
 1 file changed, 83 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/af5af3f9/src/common/http.cpp
----------------------------------------------------------------------
diff --git a/src/common/http.cpp b/src/common/http.cpp
index 0848f70..ce32ff3 100644
--- a/src/common/http.cpp
+++ b/src/common/http.cpp
@@ -26,6 +26,7 @@
 #include <mesos/resources.hpp>
 
 #include <mesos/authentication/http/basic_authenticator_factory.hpp>
+#include <mesos/authentication/http/combined_authenticator.hpp>
 #include <mesos/authorizer/authorizer.hpp>
 #include <mesos/module/http_authenticator.hpp>
 
@@ -63,6 +64,7 @@ using process::http::authentication::Principal;
 using process::http::authorization::AuthorizationCallbacks;
 
 using mesos::http::authentication::BasicAuthenticatorFactory;
+using mesos::http::authentication::CombinedAuthenticator;
 
 namespace mesos {
 
@@ -938,72 +940,109 @@ bool approveViewRole(
   return approved.get();
 }
 
+namespace {
 
-Try<Nothing> initializeHttpAuthenticators(
+Result<Authenticator*> createBasicAuthenticator(
     const string& realm,
-    const vector<string>& httpAuthenticatorNames,
+    const string& authenticatorName,
     const Option<Credentials>& credentials)
 {
-  if (httpAuthenticatorNames.empty()) {
-    return Error("No HTTP authenticator specified for realm '" + realm + "'");
+  if (credentials.isNone()) {
+    return Error(
+        "No credentials provided for the default '" +
+        string(internal::DEFAULT_HTTP_AUTHENTICATOR) +
+        "' HTTP authenticator for realm '" + realm + "'");
   }
 
-  if (httpAuthenticatorNames.size() > 1) {
-    return Error("Multiple HTTP authenticators not supported");
+  LOG(INFO) << "Creating default '" << internal::DEFAULT_HTTP_AUTHENTICATOR
+            << "' HTTP authenticator for realm '" << realm << "'";
+
+  return BasicAuthenticatorFactory::create(realm, credentials.get());
+}
+
+
+Result<Authenticator*> createCustomAuthenticator(
+    const string& realm,
+    const string& authenticatorName)
+{
+  if (!modules::ModuleManager::contains<Authenticator>(authenticatorName)) {
+    return Error(
+        "HTTP authenticator '" + authenticatorName + "' not found. "
+        "Check the spelling (compare to '" +
+        string(internal::DEFAULT_HTTP_AUTHENTICATOR) +
+        "') or verify that the authenticator was loaded "
+        "successfully (see --modules)");
   }
 
-  Option<Authenticator*> httpAuthenticator;
-  if (httpAuthenticatorNames[0] == internal::DEFAULT_HTTP_AUTHENTICATOR) {
-    if (credentials.isNone()) {
-      return Error(
-          "No credentials provided for the default '" +
-          string(internal::DEFAULT_HTTP_AUTHENTICATOR) +
-          "' HTTP authenticator for realm '" + realm + "'");
-    }
+  LOG(INFO) << "Creating '" << authenticatorName << "' HTTP authenticator "
+            << "for realm '" << realm << "'";
 
-    LOG(INFO) << "Using default '" << internal::DEFAULT_HTTP_AUTHENTICATOR
-              << "' HTTP authenticator for realm '" << realm << "'";
+  return modules::ModuleManager::create<Authenticator>(authenticatorName);
+}
 
-    Try<Authenticator*> authenticator =
-      BasicAuthenticatorFactory::create(realm, credentials.get());
-    if (authenticator.isError()) {
-      return Error(
-          "Could not create HTTP authenticator module '" +
-          httpAuthenticatorNames[0] + "': " + authenticator.error());
+} // namespace {
+
+Try<Nothing> initializeHttpAuthenticators(
+    const string& realm,
+    const vector<string>& authenticatorNames,
+    const Option<Credentials>& credentials)
+{
+  if (authenticatorNames.empty()) {
+    return Error(
+        "No HTTP authenticators specified for realm '" + realm + "'");
+  }
+
+  Option<Authenticator*> authenticator;
+
+  if (authenticatorNames.size() == 1) {
+    Result<Authenticator*> authenticator_ = None();
+    if (authenticatorNames[0] == internal::DEFAULT_HTTP_AUTHENTICATOR) {
+      authenticator_ =
+        createBasicAuthenticator(realm, authenticatorNames[0], credentials);
+    } else {
+      authenticator_ = createCustomAuthenticator(realm, authenticatorNames[0]);
     }
 
-    httpAuthenticator = authenticator.get();
-  } else {
-    if (!modules::ModuleManager::contains<Authenticator>(
-          httpAuthenticatorNames[0])) {
+    if (authenticator_.isError()) {
       return Error(
-          "HTTP authenticator '" + httpAuthenticatorNames[0] +
-          "' not found. Check the spelling (compare to '" +
-          string(internal::DEFAULT_HTTP_AUTHENTICATOR) +
-          "') or verify that the authenticator was loaded "
-          "successfully (see --modules)");
+          "Failed to create HTTP authenticator module '" +
+          authenticatorNames[0] + "': " + authenticator_.error());
     }
 
-    Try<Authenticator*> module =
-      modules::ModuleManager::create<Authenticator>(httpAuthenticatorNames[0]);
-    if (module.isError()) {
-      return Error(
-          "Could not create HTTP authenticator module '" +
-          httpAuthenticatorNames[0] + "': " + module.error());
+    CHECK_SOME(authenticator_);
+    authenticator = authenticator_.get();
+  } else {
+    // There are multiple authenticators loaded for this realm,
+    // so construct a `CombinedAuthenticator` to handle them.
+    vector<Owned<Authenticator>> authenticators;
+    foreach (const string& name, authenticatorNames) {
+      Result<Authenticator*> authenticator_ = None();
+      if (name == internal::DEFAULT_HTTP_AUTHENTICATOR) {
+        authenticator_ = createBasicAuthenticator(realm, name, credentials);
+      } else {
+        authenticator_ = createCustomAuthenticator(realm, name);
+      }
+
+      if (authenticator_.isError()) {
+        return Error(
+            "Failed to create HTTP authenticator module '" +
+            name + "': " + authenticator_.error());
+      }
+
+      CHECK_SOME(authenticator_);
+      authenticators.push_back(Owned<Authenticator>(authenticator_.get()));
     }
-    LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
-              << "' HTTP authenticator for realm '" << realm << "'";
-    httpAuthenticator = module.get();
+
+    authenticator = new CombinedAuthenticator(realm, std::move(authenticators));
   }
 
-  CHECK(httpAuthenticator.isSome());
+  CHECK(authenticator.isSome());
 
-  // Ownership of the `httpAuthenticator` is passed to libprocess.
+  // Ownership of the authenticator is passed to libprocess.
   process::http::authentication::setAuthenticator(
-    realm, Owned<Authenticator>(httpAuthenticator.get()));
+      realm, Owned<Authenticator>(authenticator.get()));
 
   return Nothing();
 }
 
-
 }  // namespace mesos {