jwt_credentials.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <inttypes.h>
24 #include <stdlib.h>
25 
26 #include <map>
27 #include <string>
28 #include <utility>
29 
30 #include "absl/status/status.h"
31 #include "absl/strings/str_cat.h"
32 
33 #include <grpc/support/alloc.h>
34 #include <grpc/support/log.h>
36 #include <grpc/support/sync.h>
37 
42 #include "src/core/lib/json/json.h"
49 
50 using grpc_core::Json;
51 
56 }
57 
60  grpc_core::ClientMetadataHandle initial_metadata,
62  gpr_timespec refresh_threshold = gpr_time_from_seconds(
64 
65  // Remove service name from service_url to follow the audience format
66  // dictated in https://google.aip.dev/auth/4111.
68  grpc_core::MakeJwtServiceUrl(initial_metadata, args));
69  if (!uri.ok()) {
70  return grpc_core::Immediate(uri.status());
71  }
72  // See if we can return a cached jwt.
74  {
76  if (cached_.has_value() && cached_->service_url == *uri &&
77  (gpr_time_cmp(
79  refresh_threshold) > 0)) {
80  jwt_value = cached_->jwt_value.Ref();
81  }
83  }
84 
85  if (!jwt_value.has_value()) {
86  char* jwt = nullptr;
87  // Generate a new jwt.
89  cached_.reset();
90  jwt = grpc_jwt_encode_and_sign(&key_, uri->c_str(), jwt_lifetime_, nullptr);
91  if (jwt != nullptr) {
92  std::string md_value = absl::StrCat("Bearer ", jwt);
93  gpr_free(jwt);
94  jwt_value = grpc_core::Slice::FromCopiedString(md_value);
95  cached_ = {jwt_value->Ref(), std::move(*uri),
97  }
99  }
100 
101  if (!jwt_value.has_value()) {
102  return grpc_core::Immediate(
103  absl::UnauthenticatedError("Could not generate JWT."));
104  }
105 
106  initial_metadata->Append(
108  [](absl::string_view, const grpc_core::Slice&) { abort(); });
109  return grpc_core::Immediate(std::move(initial_metadata));
110 }
111 
114  gpr_timespec token_lifetime)
115  : key_(key) {
116  gpr_timespec max_token_lifetime = grpc_max_auth_token_lifetime();
117  if (gpr_time_cmp(token_lifetime, max_token_lifetime) > 0) {
119  "Cropping token lifetime to maximum allowed value (%d secs).",
120  static_cast<int>(max_token_lifetime.tv_sec));
121  token_lifetime = grpc_max_auth_token_lifetime();
122  }
123  jwt_lifetime_ = token_lifetime;
125 }
126 
128  static grpc_core::UniqueTypeName::Factory kFactory("Jwt");
129  return kFactory.Create();
130 }
131 
134  grpc_auth_json_key key, gpr_timespec token_lifetime) {
136  gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
137  return nullptr;
138  }
139  return grpc_core::MakeRefCounted<grpc_service_account_jwt_access_credentials>(
140  key, token_lifetime);
141 }
142 
143 static char* redact_private_key(const char* json_key) {
145  Json json = Json::Parse(json_key, &error);
146  if (!GRPC_ERROR_IS_NONE(error) || json.type() != Json::Type::OBJECT) {
148  return gpr_strdup("<Json failed to parse.>");
149  }
150  (*json.mutable_object())["private_key"] = "<redacted>";
151  return gpr_strdup(json.Dump(/*indent=*/2).c_str());
152 }
153 
155  const char* json_key, gpr_timespec token_lifetime, void* reserved) {
157  char* clean_json = redact_private_key(json_key);
159  "grpc_service_account_jwt_access_credentials_create("
160  "json_key=%s, "
161  "token_lifetime="
162  "gpr_timespec { tv_sec: %" PRId64
163  ", tv_nsec: %d, clock_type: %d }, "
164  "reserved=%p)",
165  clean_json, token_lifetime.tv_sec, token_lifetime.tv_nsec,
166  static_cast<int>(token_lifetime.clock_type), reserved);
167  gpr_free(clean_json);
168  }
169  GPR_ASSERT(reserved == nullptr);
170  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
173  grpc_auth_json_key_create_from_string(json_key), token_lifetime)
174  .release();
175 }
176 
177 namespace grpc_core {
178 
180  auto parsed = URI::Parse(uri);
181  if (!parsed.ok()) {
182  return parsed.status();
183  }
184  return absl::StrFormat("%s://%s/", parsed->scheme(), parsed->authority());
185 }
186 
187 } // namespace grpc_core
trace.h
gpr_timespec::tv_nsec
int32_t tv_nsec
Definition: gpr_types.h:52
GPR_TIMESPAN
@ GPR_TIMESPAN
Definition: gpr_types.h:45
gpr_timespec::tv_sec
int64_t tv_sec
Definition: gpr_types.h:51
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
cleanup.Json
Json
Definition: cleanup.py:49
grpc_core::UniqueTypeName::Factory::Create
UniqueTypeName Create()
Definition: unique_type_name.h:67
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
grpc_call_credentials::GetRequestMetadataArgs
Definition: src/core/lib/security/credentials/credentials.h:196
grpc_core::Slice::Ref
Slice Ref() const
Definition: src/core/lib/slice/slice.h:368
log.h
metadata_batch.h
grpc_core::MetadataMap::Append
void Append(absl::string_view key, Slice value, MetadataParseErrorFn on_error)
Definition: metadata_batch.h:1156
grpc_core::Json::type
Type type() const
Definition: src/core/lib/json/json.h:174
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
grpc_service_account_jwt_access_credentials::Type
static grpc_core::UniqueTypeName Type()
Definition: jwt_credentials.cc:127
grpc_service_account_jwt_access_credentials::grpc_service_account_jwt_access_credentials
grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, gpr_timespec token_lifetime)
Definition: jwt_credentials.cc:113
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::Slice
Definition: src/core/lib/slice/slice.h:282
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
grpc_jwt_encode_and_sign
char * grpc_jwt_encode_and_sign(const grpc_auth_json_key *json_key, const char *audience, gpr_timespec token_lifetime, const char *scope)
Definition: json_token.cc:266
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
grpc_call_credentials
Definition: src/core/lib/security/credentials/credentials.h:189
grpc_core::ApplicationCallbackExecCtx
Definition: exec_ctx.h:283
grpc_core::RefCountedPtr::release
T * release()
Definition: ref_counted_ptr.h:140
grpc_core::Json::mutable_object
Object * mutable_object()
Definition: src/core/lib/json/json.h:178
grpc_auth_json_key_destruct
void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key)
Definition: json_token.cc:134
grpc_core::URI::Parse
static absl::StatusOr< URI > Parse(absl::string_view uri_text)
Definition: uri_parser.cc:209
grpc_service_account_jwt_access_credentials_create
grpc_call_credentials * grpc_service_account_jwt_access_credentials_create(const char *json_key, gpr_timespec token_lifetime, void *reserved)
Definition: jwt_credentials.cc:154
GRPC_TRACE_FLAG_ENABLED
#define GRPC_TRACE_FLAG_ENABLED(f)
Definition: debug/trace.h:114
grpc_auth_json_key_create_from_string
grpc_auth_json_key grpc_auth_json_key_create_from_string(const char *json_string)
Definition: json_token.cc:126
absl::UnauthenticatedError
Status UnauthenticatedError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:371
gpr_mu_destroy
GPRAPI void gpr_mu_destroy(gpr_mu *mu)
string_util.h
grpc_core::slice_detail::CopyConstructors< Slice >::FromCopiedString
static Slice FromCopiedString(const char *s)
Definition: src/core/lib/slice/slice.h:173
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
grpc_core::RefCountedPtr< grpc_call_credentials >
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc_auth_json_key_is_valid
int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key)
Definition: json_token.cc:66
gpr_time_cmp
GPRAPI int gpr_time_cmp(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:30
absl::optional::has_value
constexpr bool has_value() const noexcept
Definition: abseil-cpp/absl/types/optional.h:461
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS
#define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS
Definition: src/core/lib/security/credentials/credentials.h:60
gpr_time_sub
GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:168
grpc_max_auth_token_lifetime
GRPCAPI gpr_timespec grpc_max_auth_token_lifetime(void)
Definition: json_token.cc:48
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
grpc_service_account_jwt_access_credentials::key_
grpc_auth_json_key key_
Definition: jwt_credentials.h:90
grpc_service_account_jwt_access_credentials::GetRequestMetadata
grpc_core::ArenaPromise< absl::StatusOr< grpc_core::ClientMetadataHandle > > GetRequestMetadata(grpc_core::ClientMetadataHandle initial_metadata, const GetRequestMetadataArgs *args) override
Definition: jwt_credentials.cc:59
grpc_core::RemoveServiceNameFromJwtUri
absl::StatusOr< std::string > RemoveServiceNameFromJwtUri(absl::string_view uri)
Definition: jwt_credentials.cc:179
grpc_service_account_jwt_access_credentials::~grpc_service_account_jwt_access_credentials
~grpc_service_account_jwt_access_credentials() override
Definition: jwt_credentials.cc:53
GRPC_AUTHORIZATION_METADATA_KEY
#define GRPC_AUTHORIZATION_METADATA_KEY
Definition: src/core/lib/security/credentials/credentials.h:55
grpc_service_account_jwt_access_credentials_create_from_auth_json_key
grpc_core::RefCountedPtr< grpc_call_credentials > grpc_service_account_jwt_access_credentials_create_from_auth_json_key(grpc_auth_json_key key, gpr_timespec token_lifetime)
Definition: jwt_credentials.cc:133
absl::optional< grpc_core::Slice >
grpc_service_account_jwt_access_credentials::cache_mu_
gpr_mu cache_mu_
Definition: jwt_credentials.h:82
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
absl::flags_internal::Parse
bool Parse(FlagOpFn op, absl::string_view text, void *dst, std::string *error)
Definition: abseil-cpp/absl/flags/internal/flag.h:125
error.h
key_
RlsLb::RequestKey key_
Definition: rls.cc:659
redact_private_key
static char * redact_private_key(const char *json_key)
Definition: jwt_credentials.cc:143
json.h
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
grpc_core::ExecCtx
Definition: exec_ctx.h:97
promise.h
grpc_core::MetadataHandle< ClientMetadata >
grpc_service_account_jwt_access_credentials::cached_
absl::optional< Cache > cached_
Definition: jwt_credentials.h:88
gpr_timespec::clock_type
gpr_clock_type clock_type
Definition: gpr_types.h:55
grpc_core::MakeJwtServiceUrl
std::string MakeJwtServiceUrl(const ClientMetadataHandle &initial_metadata, const grpc_call_credentials::GetRequestMetadataArgs *args)
Definition: call_creds_util.cc:77
grpc_service_account_jwt_access_credentials::jwt_lifetime_
gpr_timespec jwt_lifetime_
Definition: jwt_credentials.h:91
absl::StatusOr::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: abseil-cpp/absl/status/statusor.h:491
grpc_api_trace
grpc_core::TraceFlag grpc_api_trace(false, "api")
key
const char * key
Definition: hpack_parser_table.cc:164
grpc_core::UniqueTypeName
Definition: unique_type_name.h:56
gpr_time_add
GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:135
grpc_core::ArenaPromise
Definition: arena_promise.h:152
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
poll.h
alloc.h
exec_ctx.h
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
ref_counted_ptr.h
api_trace.h
gpr_strdup
GPRAPI char * gpr_strdup(const char *src)
Definition: string.cc:39
grpc_core::Immediate
promise_detail::Immediate< T > Immediate(T value)
Definition: promise/promise.h:73
call_creds_util.h
absl::StatusOr< std::string >
uri_parser.h
gpr_timespec
Definition: gpr_types.h:50
grpc_error
Definition: error_internal.h:42
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
sync.h
grpc_core::UniqueTypeName::Factory
Definition: unique_type_name.h:60
grpc_core::Json::Dump
std::string Dump(int indent=0) const
Definition: json_writer.cc:336
absl::StatusOr::status
const Status & status() const &
Definition: abseil-cpp/absl/status/statusor.h:678
gpr_time_from_seconds
GPRAPI gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:123
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
jwt_credentials.h
port_platform.h
grpc_auth_json_key
Definition: json_token.h:36


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:14