diff options
-rw-r--r-- | include/grpc++/credentials.h | 8 | ||||
-rw-r--r-- | src/cpp/client/secure_credentials.cc | 22 | ||||
-rw-r--r-- | test/cpp/interop/client.cc | 31 |
3 files changed, 57 insertions, 4 deletions
diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h index c677cc3e0a..59ad638f47 100644 --- a/include/grpc++/credentials.h +++ b/include/grpc++/credentials.h @@ -105,6 +105,14 @@ std::unique_ptr<Credentials> ServiceAccountCredentials( const grpc::string& json_key, const grpc::string& scope, std::chrono::seconds token_lifetime); +// Builds JWT credentials. +// json_key is the JSON key string containing the client's private key. +// token_lifetime is the lifetime of each Json Web Token (JWT) created with +// this credentials. It should not exceed grpc_max_auth_token_lifetime or +// will be cropped to this value. +std::unique_ptr<Credentials> JWTCredentials( + const grpc::string& json_key, std::chrono::seconds token_lifetime); + // Builds IAM credentials. std::unique_ptr<Credentials> IAMCredentials( const grpc::string& authorization_token, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 6ca702eead..a2f6a69858 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -98,12 +98,30 @@ std::unique_ptr<Credentials> ComputeEngineCredentials() { std::unique_ptr<Credentials> ServiceAccountCredentials( const grpc::string& json_key, const grpc::string& scope, std::chrono::seconds token_lifetime) { - gpr_timespec lifetime = gpr_time_from_seconds( - token_lifetime.count() > 0 ? token_lifetime.count() : 0); + if (token_lifetime.count() <= 0) { + gpr_log(GPR_ERROR, + "Trying to create ServiceAccountCredentials " + "with non-positive lifetime"); + return WrapCredentials(nullptr); + } + gpr_timespec lifetime = gpr_time_from_seconds(token_lifetime.count()); return WrapCredentials(grpc_service_account_credentials_create( json_key.c_str(), scope.c_str(), lifetime)); } +// Builds JWT credentials. +std::unique_ptr<Credentials> JWTCredentials( + const grpc::string &json_key, std::chrono::seconds token_lifetime) { + if (token_lifetime.count() <= 0) { + gpr_log(GPR_ERROR, + "Trying to create JWTCredentials with non-positive lifetime"); + return WrapCredentials(nullptr); + } + gpr_timespec lifetime = gpr_time_from_seconds(token_lifetime.count()); + return WrapCredentials( + grpc_jwt_credentials_create(json_key.c_str(), lifetime)); +} + // Builds IAM credentials. std::unique_ptr<Credentials> IAMCredentials( const grpc::string& authorization_token, diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index ae68f7a556..e5645e568e 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -73,6 +73,7 @@ DEFINE_string(test_case, "large_unary", "ping_pong : full-duplex streaming; " "service_account_creds : large_unary with service_account auth; " "compute_engine_creds: large_unary with compute engine auth; " + "jwt_token_creds: large_unary with JWT token auth; " "all : all of above."); DEFINE_string(default_service_account, "", "Email of GCE default service account"); @@ -85,6 +86,7 @@ using grpc::ClientContext; using grpc::ComputeEngineCredentials; using grpc::CreateTestChannel; using grpc::Credentials; +using grpc::JWTCredentials; using grpc::ServiceAccountCredentials; using grpc::testing::ResponseParameters; using grpc::testing::SimpleRequest; @@ -146,6 +148,13 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase( creds = ComputeEngineCredentials(); return CreateTestChannel(host_port, FLAGS_server_host_override, FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); + } else if (test_case == "jwt_token_creds") { + std::unique_ptr<Credentials> creds; + GPR_ASSERT(FLAGS_enable_ssl); + grpc::string json_key = GetServiceAccountJsonKey(); + creds = JWTCredentials(json_key, std::chrono::hours(1)); + return CreateTestChannel(host_port, FLAGS_server_host_override, + FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); } else { return CreateTestChannel(host_port, FLAGS_server_host_override, FLAGS_enable_ssl, FLAGS_use_prod_roots); @@ -227,6 +236,21 @@ void DoServiceAccountCreds() { gpr_log(GPR_INFO, "Large unary with service account creds done."); } +void DoJwtTokenCreds() { + gpr_log(GPR_INFO, + "Sending a large unary rpc with JWT token credentials ..."); + std::shared_ptr<ChannelInterface> channel = + CreateChannelForTestCase("jwt_token_creds"); + SimpleRequest request; + SimpleResponse response; + request.set_fill_username(true); + PerformLargeUnary(channel, &request, &response); + GPR_ASSERT(!response.username().empty()); + grpc::string json_key = GetServiceAccountJsonKey(); + GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos); + gpr_log(GPR_INFO, "Large unary with JWT token creds done."); +} + void DoLargeUnary() { gpr_log(GPR_INFO, "Sending a large unary rpc..."); std::shared_ptr<ChannelInterface> channel = @@ -415,6 +439,8 @@ int main(int argc, char** argv) { DoServiceAccountCreds(); } else if (FLAGS_test_case == "compute_engine_creds") { DoComputeEngineCreds(); + } else if (FLAGS_test_case == "jwt_token_creds") { + DoJwtTokenCreds(); } else if (FLAGS_test_case == "all") { DoEmpty(); DoLargeUnary(); @@ -422,9 +448,10 @@ int main(int argc, char** argv) { DoResponseStreaming(); DoHalfDuplex(); DoPingPong(); - // service_account_creds can only run with ssl. + // service_account_creds and jwt_token_creds can only run with ssl. if (FLAGS_enable_ssl) { DoServiceAccountCreds(); + DoJwtTokenCreds(); } // compute_engine_creds only runs in GCE. } else { @@ -432,7 +459,7 @@ int main(int argc, char** argv) { GPR_ERROR, "Unsupported test case %s. Valid options are all|empty_unary|" "large_unary|client_streaming|server_streaming|half_duplex|ping_pong|" - "service_account_creds|compute_engine_creds", + "service_account_creds|compute_engine_creds|jwt_token_creds", FLAGS_test_case.c_str()); } |