source: vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php

Last change on this file was e3d4e0a, checked in by Vlado 222039 <vlado.popovski@…>, 7 days ago

Upload project files

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[e3d4e0a]1<?php
2/*
3 * Copyright 2015 Google Inc.
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
18namespace Google\Auth\Credentials;
19
20use Google\Auth\CredentialsLoader;
21use Google\Auth\GetQuotaProjectInterface;
22use Google\Auth\OAuth2;
23use Google\Auth\ProjectIdProviderInterface;
24use Google\Auth\ServiceAccountSignerTrait;
25use Google\Auth\SignBlobInterface;
26
27/**
28 * Authenticates requests using Google's Service Account credentials via
29 * JWT Access.
30 *
31 * This class allows authorizing requests for service accounts directly
32 * from credentials from a json key file downloaded from the developer
33 * console (via 'Generate new Json Key'). It is not part of any OAuth2
34 * flow, rather it creates a JWT and sends that as a credential.
35 */
36class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements
37 GetQuotaProjectInterface,
38 SignBlobInterface,
39 ProjectIdProviderInterface
40{
41 use ServiceAccountSignerTrait;
42
43 /**
44 * Used in observability metric headers
45 *
46 * @var string
47 */
48 private const CRED_TYPE = 'jwt';
49
50 /**
51 * The OAuth2 instance used to conduct authorization.
52 *
53 * @var OAuth2
54 */
55 protected $auth;
56
57 /**
58 * The quota project associated with the JSON credentials
59 *
60 * @var string
61 */
62 protected $quotaProject;
63
64 /**
65 * @var string
66 */
67 public $projectId;
68
69 /**
70 * Create a new ServiceAccountJwtAccessCredentials.
71 *
72 * @param string|array<mixed> $jsonKey JSON credential file path or JSON credentials
73 * as an associative array
74 * @param string|string[] $scope the scope of the access request, expressed
75 * either as an Array or as a space-delimited String.
76 */
77 public function __construct($jsonKey, $scope = null)
78 {
79 if (is_string($jsonKey)) {
80 if (!file_exists($jsonKey)) {
81 throw new \InvalidArgumentException('file does not exist');
82 }
83 $jsonKeyStream = file_get_contents($jsonKey);
84 if (!$jsonKey = json_decode((string) $jsonKeyStream, true)) {
85 throw new \LogicException('invalid json for auth config');
86 }
87 }
88 if (!array_key_exists('client_email', $jsonKey)) {
89 throw new \InvalidArgumentException(
90 'json key is missing the client_email field'
91 );
92 }
93 if (!array_key_exists('private_key', $jsonKey)) {
94 throw new \InvalidArgumentException(
95 'json key is missing the private_key field'
96 );
97 }
98 if (array_key_exists('quota_project_id', $jsonKey)) {
99 $this->quotaProject = (string) $jsonKey['quota_project_id'];
100 }
101 $this->auth = new OAuth2([
102 'issuer' => $jsonKey['client_email'],
103 'sub' => $jsonKey['client_email'],
104 'signingAlgorithm' => 'RS256',
105 'signingKey' => $jsonKey['private_key'],
106 'scope' => $scope,
107 ]);
108
109 $this->projectId = $jsonKey['project_id'] ?? null;
110 }
111
112 /**
113 * Updates metadata with the authorization token.
114 *
115 * @param array<mixed> $metadata metadata hashmap
116 * @param string $authUri optional auth uri
117 * @param callable|null $httpHandler callback which delivers psr7 request
118 * @return array<mixed> updated metadata hashmap
119 */
120 public function updateMetadata(
121 $metadata,
122 $authUri = null,
123 ?callable $httpHandler = null
124 ) {
125 $scope = $this->auth->getScope();
126 if (empty($authUri) && empty($scope)) {
127 return $metadata;
128 }
129
130 $this->auth->setAudience($authUri);
131
132 return parent::updateMetadata($metadata, $authUri, $httpHandler);
133 }
134
135 /**
136 * Implements FetchAuthTokenInterface#fetchAuthToken.
137 *
138 * @param callable|null $httpHandler
139 *
140 * @return null|array{access_token:string} A set of auth related metadata
141 */
142 public function fetchAuthToken(?callable $httpHandler = null)
143 {
144 $audience = $this->auth->getAudience();
145 $scope = $this->auth->getScope();
146 if (empty($audience) && empty($scope)) {
147 return null;
148 }
149
150 if (!empty($audience) && !empty($scope)) {
151 throw new \UnexpectedValueException(
152 'Cannot sign both audience and scope in JwtAccess'
153 );
154 }
155
156 $access_token = $this->auth->toJwt();
157
158 // Set the self-signed access token in OAuth2 for getLastReceivedToken
159 $this->auth->setAccessToken($access_token);
160
161 return [
162 'access_token' => $access_token,
163 'expires_in' => $this->auth->getExpiry(),
164 'token_type' => 'Bearer'
165 ];
166 }
167
168 /**
169 * Return the cache key for the credentials.
170 * The format for the Cache Key one of the following:
171 * ClientEmail.Scope
172 * ClientEmail.Audience
173 *
174 * @return string
175 */
176 public function getCacheKey()
177 {
178 $scopeOrAudience = $this->auth->getScope();
179 if (!$scopeOrAudience) {
180 $scopeOrAudience = $this->auth->getAudience();
181 }
182
183 return $this->auth->getIssuer() . '.' . $scopeOrAudience;
184 }
185
186 /**
187 * @return array<mixed>
188 */
189 public function getLastReceivedToken()
190 {
191 return $this->auth->getLastReceivedToken();
192 }
193
194 /**
195 * Get the project ID from the service account keyfile.
196 *
197 * Returns null if the project ID does not exist in the keyfile.
198 *
199 * @param callable|null $httpHandler Not used by this credentials type.
200 * @return string|null
201 */
202 public function getProjectId(?callable $httpHandler = null)
203 {
204 return $this->projectId;
205 }
206
207 /**
208 * Get the client name from the keyfile.
209 *
210 * In this case, it returns the keyfile's client_email key.
211 *
212 * @param callable|null $httpHandler Not used by this credentials type.
213 * @return string
214 */
215 public function getClientName(?callable $httpHandler = null)
216 {
217 return $this->auth->getIssuer();
218 }
219
220 /**
221 * Get the private key from the keyfile.
222 *
223 * In this case, it returns the keyfile's private_key key, needed for JWT signing.
224 *
225 * @return string
226 */
227 public function getPrivateKey()
228 {
229 return $this->auth->getSigningKey();
230 }
231
232 /**
233 * Get the quota project used for this API request
234 *
235 * @return string|null
236 */
237 public function getQuotaProject()
238 {
239 return $this->quotaProject;
240 }
241
242 protected function getCredType(): string
243 {
244 return self::CRED_TYPE;
245 }
246}
Note: See TracBrowser for help on using the repository browser.