|
|
|
@ -31,6 +31,8 @@ |
|
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
|
#include "src/core/lib/slice/slice_internal.h" |
|
|
|
|
#include "src/core/lib/surface/api_trace.h" |
|
|
|
|
#include "src/core/lib/transport/error_utils.h" |
|
|
|
|
#include "src/core/lib/uri/uri_parser.h" |
|
|
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
@ -42,10 +44,7 @@ using grpc_core::Json; |
|
|
|
|
void grpc_service_account_jwt_access_credentials::reset_cache() { |
|
|
|
|
GRPC_MDELEM_UNREF(cached_.jwt_md); |
|
|
|
|
cached_.jwt_md = GRPC_MDNULL; |
|
|
|
|
if (cached_.service_url != nullptr) { |
|
|
|
|
gpr_free(cached_.service_url); |
|
|
|
|
cached_.service_url = nullptr; |
|
|
|
|
} |
|
|
|
|
cached_.service_url.clear(); |
|
|
|
|
cached_.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -63,12 +62,19 @@ bool grpc_service_account_jwt_access_credentials::get_request_metadata( |
|
|
|
|
gpr_timespec refresh_threshold = gpr_time_from_seconds( |
|
|
|
|
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); |
|
|
|
|
|
|
|
|
|
// Remove service name from service_url to follow the audience format
|
|
|
|
|
// dictated in https://google.aip.dev/auth/4111.
|
|
|
|
|
absl::StatusOr<std::string> uri = |
|
|
|
|
grpc_core::RemoveServiceNameFromJwtUri(context.service_url); |
|
|
|
|
if (!uri.ok()) { |
|
|
|
|
*error = absl_status_to_grpc_error(uri.status()); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
/* See if we can return a cached jwt. */ |
|
|
|
|
grpc_mdelem jwt_md = GRPC_MDNULL; |
|
|
|
|
{ |
|
|
|
|
gpr_mu_lock(&cache_mu_); |
|
|
|
|
if (cached_.service_url != nullptr && |
|
|
|
|
strcmp(cached_.service_url, context.service_url) == 0 && |
|
|
|
|
if (!cached_.service_url.empty() && cached_.service_url == *uri && |
|
|
|
|
!GRPC_MDISNULL(cached_.jwt_md) && |
|
|
|
|
(gpr_time_cmp( |
|
|
|
|
gpr_time_sub(cached_.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), |
|
|
|
@ -83,14 +89,13 @@ bool grpc_service_account_jwt_access_credentials::get_request_metadata( |
|
|
|
|
/* Generate a new jwt. */ |
|
|
|
|
gpr_mu_lock(&cache_mu_); |
|
|
|
|
reset_cache(); |
|
|
|
|
jwt = grpc_jwt_encode_and_sign(&key_, context.service_url, jwt_lifetime_, |
|
|
|
|
nullptr); |
|
|
|
|
jwt = grpc_jwt_encode_and_sign(&key_, uri->c_str(), jwt_lifetime_, nullptr); |
|
|
|
|
if (jwt != nullptr) { |
|
|
|
|
std::string md_value = absl::StrCat("Bearer ", jwt); |
|
|
|
|
gpr_free(jwt); |
|
|
|
|
cached_.jwt_expiration = |
|
|
|
|
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), jwt_lifetime_); |
|
|
|
|
cached_.service_url = gpr_strdup(context.service_url); |
|
|
|
|
cached_.service_url = std::move(*uri); |
|
|
|
|
cached_.jwt_md = grpc_mdelem_from_slices( |
|
|
|
|
grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), |
|
|
|
|
grpc_slice_from_cpp_string(std::move(md_value))); |
|
|
|
@ -173,3 +178,15 @@ grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( |
|
|
|
|
grpc_auth_json_key_create_from_string(json_key), token_lifetime) |
|
|
|
|
.release(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
|
absl::StatusOr<std::string> RemoveServiceNameFromJwtUri(absl::string_view uri) { |
|
|
|
|
auto parsed = grpc_core::URI::Parse(uri); |
|
|
|
|
if (!parsed.ok()) { |
|
|
|
|
return parsed.status(); |
|
|
|
|
} |
|
|
|
|
return absl::StrFormat("%s://%s/", parsed->scheme(), parsed->authority()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace grpc_core
|
|
|
|
|