15#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_SERVICE_ACCOUNT_CREDENTIALS_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OAUTH2_SERVICE_ACCOUNT_CREDENTIALS_H
18#include "google/cloud/storage/internal/curl_request_builder.h"
19#include "google/cloud/storage/internal/openssl_util.h"
20#include "google/cloud/storage/oauth2/credential_constants.h"
21#include "google/cloud/storage/oauth2/credentials.h"
22#include "google/cloud/storage/oauth2/refreshing_credentials_wrapper.h"
23#include "google/cloud/storage/version.h"
24#include "google/cloud/internal/getenv.h"
25#include "google/cloud/internal/oauth2_service_account_credentials.h"
26#include "google/cloud/internal/sha256_hash.h"
27#include "google/cloud/optional.h"
28#include "google/cloud/status_or.h"
29#include "absl/types/optional.h"
31#include <condition_variable>
42GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
46
47
48
49
56 absl::optional<std::set<std::string>>
scopes;
58 absl::optional<std::string>
subject;
62
63
64
65
68 std::string
const& content, std::string
const& source,
72
73
74
75
76
77
78
79
80
81
83 std::string
const& source,
87
88
89
90
91
94 storage::internal::HttpResponse
const& response,
95 std::chrono::system_clock::time_point now);
98
99
100
101
102
103
104
105
106
107
110 std::chrono::system_clock::time_point now);
113
114
115
116
117
118
120 std::string
const& payload,
121 std::string
const& pem_contents);
124
125
126
127
128
129
130
131
134 std::chrono::system_clock::time_point now);
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
164 std::chrono::system_clock::time_point tp);
167
168
169
170
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200template <
typename HttpRequestBuilderType =
201 storage::internal::CurlRequestBuilder,
202 typename ClockType = std::chrono::system_clock>
203class ServiceAccountCredentials;
207class ServiceAccountCredentials<
storage::internal::CurlRequestBuilder,
208 std::chrono::system_clock>
212 : ServiceAccountCredentials(std::move(info), {}) {}
216 StatusOr<std::string> AuthorizationHeader()
override {
217 return oauth2_internal::AuthorizationHeaderJoined(*impl_);
221
222
223
224
225
226
227
228
229
230
231
232
233 StatusOr<std::vector<std::uint8_t>> SignBlob(
235 std::string
const& blob)
const override {
236 return impl_->SignBlob((signing_account.has_value()
237 ? signing_account.value()
238 : absl::optional<std::string>(absl::nullopt)),
242 std::string AccountEmail()
const override {
return impl_->AccountEmail(); }
243 std::string KeyId()
const override {
return impl_->KeyId(); }
246 friend struct ServiceAccountCredentialsTester;
247 StatusOr<std::string> AuthorizationHeaderForTesting(
248 std::chrono::system_clock::time_point tp) {
249 return oauth2_internal::AuthorizationHeaderJoined(*impl_, tp);
251 std::unique_ptr<oauth2_internal::Credentials> impl_;
255template <
typename HttpRequestBuilderType,
typename ClockType>
256class ServiceAccountCredentials :
public Credentials {
259 : ServiceAccountCredentials(std::move(info), {}) {}
262 : info_(std::move(info)),
267 std::unique_lock<std::mutex> lock(mu_);
268 return refreshing_creds_.AuthorizationHeader(clock_.now(),
269 [
this] {
return Refresh(); });
273
274
275
276
277
278
279
280
281
282
283
284
287 std::string
const& blob)
const override {
288 if (signing_account.has_value() &&
291 "The current_credentials cannot sign blobs for " +
292 signing_account.value()
);
294 return internal::SignStringWithPem(blob, info_
.private_key,
305 if (UseOAuth())
return RefreshOAuth();
306 return RefreshSelfSigned();
310 HttpRequestBuilderType builder(
312 storage::internal::GetDefaultCurlHandleFactory(options_));
313 builder.AddHeader(
"Content-Type: application/x-www-form-urlencoded");
316 std::string grant_type(
"grant_type=");
318 builder.MakeEscapedString(
"urn:ietf:params:oauth:grant-type:jwt-bearer")
322 CreateServiceAccountRefreshPayload(info_, grant_type, clock_.now());
323 auto response = std::move(builder).BuildRequest().MakeRequest(payload);
324 if (!response)
return std::move(response).status();
325 if (response->status_code >= 300)
return AsStatus(*response);
326 return ParseServiceAccountRefreshResponse(*response, clock_.now());
331 auto const tp = clock_.now();
332 auto token = MakeSelfSignedJWT(info_, tp);
333 if (!token)
return std::move(token).status();
335 "Authorization: Bearer " + *token,
341 mutable std::mutex mu_;
350oauth2_internal::ServiceAccountCredentialsInfo MapServiceAccountCredentialsInfo(
354GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Options & set(ValueTypeT< T > v)
Options(Options const &rhs)
Status(StatusCode code, std::string message, ErrorInfo info={})
Describes the configuration for low-level connection features.
Definition: client_options.h:74
std::string ssl_root_path() const
Definition: client_options.h:77
Interface for OAuth 2.0 credentials used to access Google Cloud services.
Definition: credentials.h:47
Wrapper for refreshable parts of a Credentials object.
Definition: refreshing_credentials_wrapper.h:37
std::string KeyId() const override
Return the account's key_id associated with these credentials, if any.
Definition: service_account_credentials.h:299
ServiceAccountCredentials(ServiceAccountCredentialsInfo info)
Definition: service_account_credentials.h:258
StatusOr< std::vector< std::uint8_t > > SignBlob(SigningAccount const &signing_account, std::string const &blob) const override
Create a RSA SHA256 signature of the blob using the Credential object.
Definition: service_account_credentials.h:285
StatusOr< std::string > AuthorizationHeader() override
Attempts to obtain a value for the Authorization HTTP header.
Definition: service_account_credentials.h:266
std::string AccountEmail() const override
Return the account's email associated with these credentials, if any.
Definition: service_account_credentials.h:298
ServiceAccountCredentials(ServiceAccountCredentialsInfo info, ChannelOptions const &options)
Definition: service_account_credentials.h:260
Authentication components for Google Cloud Storage.
Definition: anonymous_credentials.h:26
std::pair< std::string, std::string > AssertionComponentsFromInfo(ServiceAccountCredentialsInfo const &info, std::chrono::system_clock::time_point now)
Splits a ServiceAccountCredentialsInfo into header and payload components and uses the current time t...
bool ServiceAccountUseOAuth(ServiceAccountCredentialsInfo const &info)
Return true if we need to use the OAuth path to create tokens.
std::string CreateServiceAccountRefreshPayload(ServiceAccountCredentialsInfo const &info, std::string const &grant_type, std::chrono::system_clock::time_point now)
Uses a ServiceAccountCredentialsInfo and the current time to construct a JWT assertion.
StatusOr< ServiceAccountCredentialsInfo > ParseServiceAccountCredentials(std::string const &content, std::string const &source, std::string const &default_token_uri=GoogleOAuthRefreshEndpoint())
Parses the contents of a JSON keyfile into a ServiceAccountCredentialsInfo.
char const * GoogleOAuthRefreshEndpoint()
The endpoint to fetch an OAuth 2.0 access token from.
Definition: credential_constants.h:67
StatusOr< RefreshingCredentialsWrapper::TemporaryToken > ParseServiceAccountRefreshResponse(storage::internal::HttpResponse const &response, std::chrono::system_clock::time_point now)
Parses a refresh response JSON string and uses the current time to create a TemporaryToken.
StatusOr< ServiceAccountCredentialsInfo > ParseServiceAccountP12File(std::string const &source, std::string const &default_token_uri=GoogleOAuthRefreshEndpoint())
Parses the contents of a P12 keyfile into a ServiceAccountCredentialsInfo.
StatusOr< std::string > MakeSelfSignedJWT(ServiceAccountCredentialsInfo const &info, std::chrono::system_clock::time_point tp)
Make a self-signed JWT from the service account.
constexpr std::chrono::seconds GoogleOAuthAccessTokenLifetime()
The max lifetime in seconds of an access token.
Definition: credential_constants.h:43
JwtSigningAlgorithms
Supported signing algorithms used in JWT auth flows.
Definition: credential_constants.h:36
std::string MakeJWTAssertion(std::string const &header, std::string const &payload, std::string const &pem_contents)
Given a key and a JSON header and payload, creates a JWT assertion string.
Contains all the Google Cloud Storage C++ client APIs.
Definition: auto_finalize.h:24
Specify the service account used to sign a blob.
Definition: signed_url_options.h:186
Definition: refreshing_credentials_wrapper.h:41
Object to hold information used to instantiate an ServiceAccountCredentials.
Definition: service_account_credentials.h:50
absl::optional< std::string > subject
Definition: service_account_credentials.h:58
std::string private_key
Definition: service_account_credentials.h:53
absl::optional< std::set< std::string > > scopes
Definition: service_account_credentials.h:56
std::string client_email
Definition: service_account_credentials.h:51
std::string token_uri
Definition: service_account_credentials.h:54
std::string private_key_id
Definition: service_account_credentials.h:52