适用于 PHP 的 AWS 开发工具包
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

使用凭证提供程序

凭证提供程序是一个函数,该函数返回一个用 GuzzleHttp\Promise\PromiseInterface 实例执行或因 Aws\Credentials\CredentialsInterface 而被拒绝的 Aws\Exception\CredentialsException。您可以使用凭证提供程序来实现自己用于创建凭证的自定义逻辑,或优化凭证加载。

凭证提供程序将被传入 credentials 客户端构造函数选项。凭证提供程序是异步的,因此每次调用 API 操作时都会强制对其进行延迟评估。因此,将凭证提供程序函数传入给开发工具包客户端构造函数不会立即验证凭证。如果凭证提供程序未返回凭证对象,将因 Aws\Exception\CredentialsException 而拒绝 API 操作。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; // Use the default credential provider $provider = CredentialProvider::defaultProvider(); // Pass the provider to the client $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

开发工具包中内置的提供程序

开发工具包提供了若干个可与任何自定义提供程序结合使用的内置提供程序。

重要

每次执行 API 操作时均会调用凭证提供程序。如果加载凭证是一项代价高昂的任务(例如从磁盘或网络资源加载)或者凭证未由提供程序缓存,请考虑将您的凭证提供程序包装在 Aws\Credentials\CredentialProvider::memoize 函数中。系统会自动记住开发工具包使用的默认凭证提供程序。

assumeRole 提供程序

如果您使用 Aws\Credentials\AssumeRoleCredentialProvider 通过代入角色创建凭证,则需要按所示方式使用 'client' 对象和 StsClient 详细信息来提供 'assume_role_params' 信息。

注意

为避免在每次 API 操作时都不必要地提取 AWS STS 凭证,您可以使用 memoize 函数在凭证过期时处理凭证的自动刷新。请参阅下面的示例代码。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; use Aws\Sts\StsClient; // Passing Aws\Credentials\AssumeRoleCredentialProvider options directly $profile = new InstanceProfileProvider(); $ARN = "arn:aws:iam::123456789012:role/xaccounts3access"; $sessionName = "s3-access-example"; $assumeRoleCredentials = new AssumeRoleCredentialProvider([ 'client' => new StsClient([ 'region' => 'us-east-2', 'version' => '2011-06-15' 'credentials' => $profile ]), 'assume_role_params' => [ 'RoleArn' => $ARN, 'RoleSessionName' => $sessionName, ], ]); // To avoid unnecessarily fetching STS credentials on every API operation, // the memoize function handles automatically refreshing the credentials when they expire $provider = CredentialProvider::memoize($assumeRoleCredentials); $client = new S3Client([ 'region' => 'us-east-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

有关 'assume_role_params' 的更多信息,请参阅 AssumeRole

串联提供程序

可以使用 Aws\Credentials\CredentialProvider::chain() 函数将凭证提供程序链接起来。此函数接受可变数量的参数,每个参数都是凭证提供程序函数。然后,此函数返回一个由所提供函数构成的新函数,这样便可以一个接一个地调用这些函数,直至其中一个提供程序返回已成功执行的 Promise。

defaultProvider 在失败之前使用此组合来检查多个提供程序。defaultProvider 的源代码演示了 chain 函数的使用。

// This function returns a provider public static function defaultProvider(array $config = []) { // This function is the provider, which is actually the composition // of multiple providers. Notice that we are also memoizing the result by // default. return self::memoize( self::chain( self::env(), self::ini(), self::instanceProfile($config) ) ); }

创建自定义提供程序

凭证提供程序只是在调用时返回承诺 (GuzzleHttp\Promise\PromiseInterface) 的函数,该承诺用 Aws\Credentials\CredentialsInterface 对象执行或因 Aws\Exception\CredentialsException 而被拒绝。

创建提供程序的最佳实践是创建一个函数,通过调用该函数来创建实际的凭证提供程序。例如,此处是 env 提供程序的源代码 (为了举例,略微进行了修改)。请注意,它是可返回实际提供程序函数的函数。这样,您便可以轻松地构建凭证提供程序并将其作为值来进行传递。

use GuzzleHttp\Promise; use GuzzleHttp\Promise\RejectedPromise; // This function CREATES a credential provider public static function env() { // This function IS the credential provider return function () { // Use credentials from environment variables, if available $key = getenv(self::ENV_KEY); $secret = getenv(self::ENV_SECRET); if ($key && $secret) { return Promise\promise_for( new Credentials($key, $secret, getenv(self::ENV_SESSION)) ); } $msg = 'Could not find environment variable ' . 'credentials in ' . self::ENV_KEY . '/' . self::ENV_SECRET; return new RejectedPromise(new CredentialsException($msg)); }; }

defaultProvider 提供程序

Aws\Credentials\CredentialProvider::defaultProvider 是默认的凭证提供程序。如果您在创建客户端时省略 credentials 选项,则会使用此提供程序。它首先尝试从环境变量加载凭证,然后从 .ini 文件加载(先是 .aws/credentials 文件,然后是 .aws/config 文件),再从实例配置文件加载(先是 EcsCredentials,然后是 Ec2 元数据)。

注意

系统会自动记住默认提供程序的结果。

ecsCredentials 提供程序

Aws\Credentials\CredentialProvider::ecsCredentials 尝试通过 GET 请求加载凭证,其 URI 由容器中的环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 指定。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::ecsCredentials(); // Be sure to memoize the credentials $memoizedProvider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $memoizedProvider ]);

env 提供程序

Aws\Credentials\CredentialProvider::env 尝试从环境变量中加载凭证。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => CredentialProvider::env() ]);

通过 Web 身份提供商代入角色

Aws\Credentials\CredentialProvider::assumeRoleWithWebIdentityCredentialProvider 尝试通过代入角色来加载凭证。如果存在环境变量 AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILE,则提供商将尝试使用磁盘上的令牌(位于在 AWS_WEB_IDENTITY_TOKEN_FILE 中指定的完整路径上),代入在 AWS_ROLE_ARN 上指定的角色。如果使用环境变量,则提供商将尝试从 AWS_ROLE_SESSION_NAME 环境变量设置会话。

如果未设置环境变量,则提供商将使用默认配置文件或者设置为 AWS_PROFILE 的配置文件。默认情况下,提供商从 ~/.aws/credentials~/.aws/config 读取配置文件,并可读取 filename 配置选项中指定的配置文件。提供商将代入配置文件的 role_arn 中的角色,从 web_identity_token_file 中设置的完整路径读取令牌。如果已在配置文件上设置,则将使用 role_session_name

提供商作为默认链的一部分调用,并可以直接调用。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::assumeRoleWithWebIdentityCredentialProvider(); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

默认情况下,此凭证提供程序会继承 StsClient 将使用的已配置区域来代入该角色。(可选)可以提供完整的 StsClient。应在任何提供的 StsClient 上将凭证设置为 false

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; use Aws\Sts\StsClient; $stsClient = new StsClient([ 'region' => 'us-west-2', 'version' => 'latest', 'credentials' => false ]) $provider = CredentialProvider::assumeRoleWithWebIdentityCredentialProvider([ 'stsClient' => $stsClient ]); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

ini 提供程序

Aws\Credentials\CredentialProvider::ini 尝试从 ini 凭证文件加载凭证。默认情况下,开发工具包会尝试从位于 ~/.aws/credentials 的文件中加载“默认”配置文件。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::ini(); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

您可以通过向创建提供程序的函数提供参数来使用自定义配置文件或 .ini 文件位置。

$profile = 'production'; $path = '/full/path/to/credentials.ini'; $provider = CredentialProvider::ini($profile, $path); $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

process provider

Aws\Credentials\CredentialProvider::process 将尝试从 ini 凭证文件中指定的 credential_process 加载凭证。默认情况下,开发工具包会尝试从位于 ~/.aws/credentials 的文件中加载“默认”配置文件。开发工具包将完全调用给定的 credential_process 命令,然后从 stdout 中读取 JSON 数据。credential_process 必须将采用以下格式将凭证写入 stdout:

{ "Version": 1, "AccessKeyId": "", "SecretAccessKey": "", "SessionToken": "", "Expiration": "" }

SessionTokenExpiration 是可选的。如果存在,凭证将被视为临时的。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::process(); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

您可以通过向创建提供程序的函数提供参数来使用自定义配置文件或 .ini 文件位置。

$profile = 'production'; $path = '/full/path/to/credentials.ini'; $provider = CredentialProvider::process($profile, $path); $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);

instanceProfile 提供程序

Aws\Credentials\CredentialProvider::instanceProfile 尝试从 Amazon EC2 实例配置文件加载凭证。

use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::instanceProfile(); // Be sure to memoize the credentials $memoizedProvider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $memoizedProvider ]);

默认情况下,提供商最多重新尝试提取凭证三次。重试次数可以使用 retries 选项设置,将选项设置为 0 可以完全禁用重试。

use Aws\Credentials\CredentialProvider; $provider = CredentialProvider::instanceProfile([ 'retries' => 0 ]); $memoizedProvider = CredentialProvider::memoize($provider);

注意

您可以通过将 AWS_EC2_METADATA_DISABLED 环境变量设置为 true 来禁用从 Amazon EC2 实例配置文件进行加载的尝试。

记忆凭证

有时,您可能需要创建能记住之前返回值的凭证提供程序。当加载凭证是一项代价高昂的操作时或在使用 Aws\Sdk 类跨多个客户端共享凭证提供程序时,这有助于改进性能。您可以通过将凭证提供程序函数包装在 memoize 函数中来向凭证提供程序中添加记忆功能。

use Aws\Credentials\CredentialProvider; $provider = CredentialProvider::instanceProfile(); // Wrap the actual provider in a memoize function $provider = CredentialProvider::memoize($provider); // Pass the provider into the Sdk class and share the provider // across multiple clients. Each time a new client is constructed, // it will use the previously returned credentials as long as // they haven't yet expired. $sdk = new Aws\Sdk(['credentials' => $provider]); $s3 = $sdk->getS3(['region' => 'us-west-2', 'version' => 'latest']); $ec2 = $sdk->getEc2(['region' => 'us-west-2', 'version' => 'latest']); assert($s3->getCredentials() === $ec2->getCredentials());

当记住的凭证过期时,记忆包装器将调用可尝试刷新凭证的包装器提供程序。