diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h index 56827c0f21b7132d5a5b19f702045bf137378a36..ad3572c00378e3b44126286efaa59f8fac2369ef 100644 --- a/include/grpc++/security/credentials.h +++ b/include/grpc++/security/credentials.h @@ -38,6 +38,7 @@ #include <memory> #include <grpc++/impl/grpc_library.h> +#include <grpc++/security/auth_context.h> #include <grpc++/support/config.h> #include <grpc++/support/status.h> #include <grpc++/support/string_ref.h> @@ -207,9 +208,18 @@ class MetadataCredentialsPlugin { // a different thread from the one processing the call. virtual bool IsBlocking() const { return true; } + // Type of credentials this plugin is implementing. + virtual const char* GetType() const { return ""; } + // Gets the auth metatada produced by this plugin. + // The fully qualified method name is: + // service_url + "/" + method_name. + // The channel_auth_context contains (among other things), the identity of + // the server. virtual Status GetMetadata( grpc::string_ref service_url, + grpc::string_ref method_name, + const AuthContext& channel_auth_context, std::multimap<grpc::string, grpc::string>* metadata) = 0; }; diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index bd68228460296f3eeabe81570e37a765ff4f1305..640932326237384971cc8f07f25cf60e278b14a7 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -37,6 +37,7 @@ #include <grpc++/support/channel_arguments.h> #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/client/secure_credentials.h" +#include "src/cpp/common/secure_auth_context.h" namespace grpc { @@ -171,18 +172,25 @@ void MetadataCredentialsPluginWrapper::GetMetadata( } if (w->plugin_->IsBlocking()) { w->thread_pool_->Add( - std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, - context.service_url, cb, user_data)); + std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, context, + cb, user_data)); } else { - w->InvokePlugin(context.service_url, cb, user_data); + w->InvokePlugin(context, cb, user_data); } } void MetadataCredentialsPluginWrapper::InvokePlugin( - const char* service_url, grpc_credentials_plugin_metadata_cb cb, + grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data) { std::multimap<grpc::string, grpc::string> metadata; - Status status = plugin_->GetMetadata(service_url, &metadata); + + // const_cast is safe since the SecureAuthContext does not take owndership and + // the object is passed as a const ref to plugin_->GetMetadata. + SecureAuthContext cpp_channel_auth_context( + const_cast<grpc_auth_context*>(context.channel_auth_context), false); + + Status status = plugin_->GetMetadata(context.service_url, context.method_name, + cpp_channel_auth_context, &metadata); std::vector<grpc_metadata> md; for (auto it = metadata.begin(); it != metadata.end(); ++it) { grpc_metadata md_entry; @@ -204,11 +212,12 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin( std::unique_ptr<MetadataCredentialsPlugin> plugin) { GrpcLibrary init; // To call grpc_init(). + const char* type = plugin->GetType(); MetadataCredentialsPluginWrapper* wrapper = new MetadataCredentialsPluginWrapper(std::move(plugin)); grpc_metadata_credentials_plugin c_plugin = { MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper, ""}; + MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; return WrapCallCredentials( grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); } diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index b8fe075dc7d2ad0683184cfc6b2311452be7eb2b..8e3c713a503683cb232e8b20f8d3cf36205debb8 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -88,7 +88,7 @@ class MetadataCredentialsPluginWrapper GRPC_FINAL { std::unique_ptr<MetadataCredentialsPlugin> plugin); private: - void InvokePlugin(const char* service_url, + void InvokePlugin(grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data); std::unique_ptr<ThreadPoolInterface> thread_pool_; std::unique_ptr<MetadataCredentialsPlugin> plugin_; diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 2bd886334e13d9bb4066ac75df8d3d97de89be33..df37e6349957a53305fad1d157ad55b5d4f2120d 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -119,10 +119,13 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; } - Status GetMetadata(grpc::string_ref service_url, + Status GetMetadata(grpc::string_ref service_url, grpc::string_ref method_name, + const grpc::AuthContext& channel_auth_context, std::multimap<grpc::string, grpc::string>* metadata) GRPC_OVERRIDE { EXPECT_GT(service_url.length(), 0UL); + EXPECT_GT(method_name.length(), 0UL); + EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated()); EXPECT_TRUE(metadata != nullptr); if (is_successful_) { metadata->insert(std::make_pair(kMetadataKey, metadata_value_));