CHANGELOG.md000064400000000531147134004340006354 0ustar00# CHANGELOG ## 1.1.3 - 2020-12-24 - Require guzzle ^6.3|^7.0 ## 1.0.2 - 2020-02-14 - Update Tea. ## 1.0.1 - 2019-12-30 - Supported get `Role Name` automatically. ## 1.0.0 - 2019-09-01 - Initial release of the Alibaba Cloud Credentials for PHP Version 1.0.0 on Packagist See for more information. CONTRIBUTING.md000064400000003232147134004340006775 0ustar00# CONTRIBUTING We work hard to provide a high-quality and useful SDK for Alibaba Cloud, and we greatly value feedback and contributions from our community. Please submit your [issues][issues] or [pull requests][pull-requests] through GitHub. ## Tips - The SDK is released under the [Apache license][license]. Any code you submit will be released under that license. For substantial contributions, we may ask you to sign a [Alibaba Documentation Corporate Contributor License Agreement (CLA)][cla]. - We follow all of the relevant PSR recommendations from the [PHP Framework Interop Group][php-fig]. Please submit code that follows these standards. The [PHP CS Fixer][cs-fixer] tool can be helpful for formatting your code. Your can use `composer fixer` to fix code. - We maintain a high percentage of code coverage in our unit tests. If you make changes to the code, please add, update, and/or remove tests as appropriate. - If your code does not conform to the PSR standards, does not include adequate tests, or does not contain a changelog document, we may ask you to update your pull requests before we accept them. We also reserve the right to deny any pull requests that do not align with our standards or goals. [issues]: https://github.com/aliyun/credentials-php/issues [pull-requests]: https://github.com/aliyun/credentials-php/pulls [license]: http://www.apache.org/licenses/LICENSE-2.0 [cla]: https://alibaba-cla-2018.oss-cn-beijing.aliyuncs.com/Alibaba_Documentation_Open_Source_Corporate_CLA.pdf [php-fig]: http://php-fig.org [cs-fixer]: http://cs.sensiolabs.org/ [docs-readme]: https://github.com/aliyun/credentials-php/blob/master/README.md LICENSE.md000064400000001115147134004340006146 0ustar00Copyright (c) 2009-present, Alibaba Cloud All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. NOTICE.md000064400000007662147134004340006062 0ustar00# NOTICE Copyright (c) 2009-present, Alibaba Cloud All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # Guzzle Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # jmespath.php Copyright (c) 2014 Michael Dowling, https://github.com/mtdowling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # Dot Copyright (c) 2016-2019 Riku Särkinen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. README-zh-CN.md000064400000041050147134004340006740 0ustar00[English](/README.md) | 简体中文 ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg) # Alibaba Cloud Credentials for PHP [![PHP CI](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml/badge.svg)](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/aliyun/credentials-php/graph/badge.svg?token=YIkSjtfKbB)](https://codecov.io/gh/aliyun/credentials-php) [![Latest Stable Version](https://poser.pugx.org/alibabacloud/credentials/v/stable)](https://packagist.org/packages/alibabacloud/credentials) [![composer.lock](https://poser.pugx.org/alibabacloud/credentials/composerlock)](https://packagist.org/packages/alibabacloud/credentials) [![Total Downloads](https://poser.pugx.org/alibabacloud/credentials/downloads)](https://packagist.org/packages/alibabacloud/credentials) [![License](https://poser.pugx.org/alibabacloud/credentials/license)](https://packagist.org/packages/alibabacloud/credentials) Alibaba Cloud Credentials for PHP 是帮助 PHP 开发者管理凭据的工具。 ## 先决条件 您的系统需要满足[先决条件](/docs/zh-CN/0-Prerequisites.md),包括 PHP> = 5.6。 我们强烈建议使用cURL扩展,并使用TLS后端编译cURL 7.16.2+。 ## 安装依赖 如果已在系统上[全局安装 Composer](https://getcomposer.org/doc/00-intro.md#globally),请直接在项目目录中运行以下内容来安装 Alibaba Cloud Credentials for PHP 作为依赖项: ```sh composer require alibabacloud/credentials ``` > 一些用户可能由于网络问题无法安装,可以使用[阿里云 Composer 全量镜像](https://developer.aliyun.com/composer)。 请看[安装](/docs/zh-CN/1-Installation.md)有关通过 Composer 和其他方式安装的详细信息。 ## 快速使用 在您开始之前,您需要注册阿里云帐户并获取您的[凭证](https://usercenter.console.aliyun.com/#/manage/ak)。 ### 凭证类型 #### 使用默认凭据链 当您在初始化凭据客户端不传入任何参数时,Credentials工具会使用默认凭据链方式初始化客户端。默认凭据的读取逻辑请参见[默认凭据链](#默认凭证提供程序链)。 ```php getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### AccessKey 通过[用户信息管理][ak]设置 access_key,它们具有该账户完全的权限,请妥善保管。有时出于安全考虑,您不能把具有完全访问权限的主账户 AccessKey 交于一个项目的开发者使用,您可以[创建RAM子账户][ram]并为子账户[授权][permissions],使用RAM子用户的 AccessKey 来进行API调用。 ```php 'access_key', 'accessKeyId' => '', 'accessKeySecret' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); ``` #### STS 通过安全令牌服务(Security Token Service,简称 STS),申请临时安全凭证(Temporary Security Credentials,简称 TSC),创建临时安全凭证。 ```php 'sts', 'accessKeyId' => '', 'accessKeySecret' => '', 'securityToken' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### RamRoleArn 通过指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以帮助开发者前往STS换取STS Token。您也可以通过为 `Policy` 赋值来限制RAM角色到一个更小的权限集合。 ```php 'ram_role_arn', 'accessKeyId' => '', 'accessKeySecret' => '', // 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通过环境变量ALIBABA_CLOUD_ROLE_ARN设置role_arn 'roleArn' => '', // 角色会话名称,可以通过环境变量ALIBABA_CLOUD_ROLE_SESSION_NAME设置role_session_name 'roleSessionName' => '', // 设置更小的权限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"} 'policy' => '', # 设置session过期时间 'roleSessionExpiration' => 3600, ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### EcsRamRole Credentials工具会自动获取ECS实例绑定的RAM角色,调用ECS的元数据服务(Meta Data Server)换取STS Token,完成凭据客户端初始化。ECI实例,容器服务 Kubernetes 版的Worker节点均支持绑定实例RAM角色。 ```php 'ecs_ram_role', // 选填,该ECS角色的角色名称,不填会自动获取,但是建议加上以减少请求次数,可以通过环境变量ALIBABA_CLOUD_ECS_METADATA设置role_name 'roleName' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### OIDCRoleArn 在容器服务 Kubernetes 版中设置了Worker节点RAM角色后,对应节点内的Pod中的应用也就可以像ECS上部署的应用一样,通过元数据服务(Meta Data Server)获取关联角色的STS Token。但如果容器集群上部署的是不可信的应用(比如部署您的客户提交的应用,代码也没有对您开放),您可能并不希望它们能通过元数据服务获取Worker节点关联实例RAM角色的STS Token。为了避免影响云上资源的安全,同时又能让这些不可信的应用安全地获取所需的 STS Token,实现应用级别的权限最小化,您可以使用RRSA(RAM Roles for Service Account)功能。阿里云容器集群会为不同的应用Pod创建和挂载相应的服务账户OIDC Token文件,并将相关配置信息注入到环境变量中,Credentials工具通过获取环境变量的配置信息,调用STS服务的AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证接口换取绑定角色的STS Token。详情请参见[通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/use-rrsa-to-authorize-pods-to-access-different-cloud-services#task-2142941)。 ```php 'oidc_role_arn', // OIDC提供商ARN,可以通过环境变量ALIBABA_CLOUD_OIDC_PROVIDER_ARN设置oidc_provider_arn 'oidcProviderArn' => '', // OIDC Token文件路径,可以通过环境变量ALIBABA_CLOUD_OIDC_TOKEN_FILE设置oidc_token_file_path 'oidcTokenFilePath' => '', // 要扮演的RAM角色ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通过环境变量ALIBABA_CLOUD_ROLE_ARN设置role_arn 'roleArn' => '', // 角色会话名称,可以通过环境变量ALIBABA_CLOUD_ROLE_SESSION_NAME设置role_session_name 'roleSessionName' => '', // 设置更小的权限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"} 'policy' => '', # 设置session过期时间 'roleSessionExpiration' => 3600, ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### Credentials URI 通过指定提供凭证的自定义网络服务地址,让凭证自动申请维护 STS Token。 ```php 'credentials_uri', // 凭证的 URI,格式为http://local_or_remote_uri/,可以通过环境变量ALIBABA_CLOUD_CREDENTIALS_URI设置credentials_uri 'credentialsURI' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getBearerToken(); ``` #### Bearer Token 目前只有云呼叫中心 CCC 这款产品支持 Bearer Token 的凭据初始化方式。 ```php 'bearer', // 填入您的Bearer Token 'bearerToken' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getBearerToken(); ``` ## 默认凭证提供程序链 当您的程序开发环境和生产环境采用不同的凭据类型,常见做法是在代码中获取当前环境信息,编写获取不同凭据的分支代码。借助Credentials工具的默认凭据链,您可以用同一套代码,通过程序之外的配置来控制不同环境下的凭据获取方式。当您在不传入参数的情况下,直接使用$credential = new Credential();初始化凭据客户端时,阿里云SDK将会尝试按照如下顺序查找相关凭据信息。 ### 1. 使用环境变量 Credentials工具会优先在环境变量中获取凭据信息。 - 如果系统环境变量 `ALIBABA_CLOUD_ACCESS_KEY_ID`(密钥Key) 和 `ALIBABA_CLOUD_ACCESS_KEY_SECRET`(密钥Value) 不为空,Credentials工具会优先使用它们作为默认凭据。 - 如果系统环境变量 `ALIBABA_CLOUD_ACCESS_KEY_ID`(密钥Key)、`ALIBABA_CLOUD_ACCESS_KEY_SECRET`(密钥Value)、`ALIBABA_CLOUD_SECURITY_TOKEN`(Token)均不为空,Credentials工具会优先使用STS Token作为默认凭据。 ### 2. 使用OIDC RAM角色 若不存在优先级更高的凭据信息,Credentials工具会在环境变量中获取如下内容: `ALIBABA_CLOUD_ROLE_ARN`:RAM角色名称ARN; `ALIBABA_CLOUD_OIDC_PROVIDER_ARN`:OIDC提供商ARN; `ALIBABA_CLOUD_OIDC_TOKEN_FILE`:OIDC Token文件路径; 若以上三个环境变量都已设置内容,Credentials将会使用变量内容调用STS服务的[AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证](https://help.aliyun.com/zh/ram/developer-reference/api-sts-2015-04-01-assumerolewithoidc)接口换取STS Token作为默认凭据。 ### 3. 使用 Aliyun CLI 工具的 config.json 配置文件 若不存在优先级更高的凭据信息,Credentials工具会优先在如下位置查找 `config.json` 文件是否存在: Linux系统:`~/.aliyun/config.json` Windows系统: `C:\Users\USER_NAME\.aliyun\config.json` 如果文件存在,程序将会使用配置文件中 `current` 指定的凭据信息初始化凭据客户端。当然,您也可以通过环境变量 `ALIBABA_CLOUD_PROFILE` 来指定凭据信息,例如设置 `ALIBABA_CLOUD_PROFILE` 的值为 `AK`。 在config.json配置文件中每个module的值代表了不同的凭据信息获取方式: - AK:使用用户的Access Key作为凭据信息; - RamRoleArn:使用RAM角色的ARN来获取凭据信息; - EcsRamRole:利用ECS绑定的RAM角色来获取凭据信息; - OIDC:通过OIDC ARN和OIDC Token来获取凭据信息; - ChainableRamRoleArn:采用角色链的方式,通过指定JSON文件中的其他凭据,以重新获取新的凭据信息。 配置示例信息如下: ```json { "current": "AK", "profiles": [ { "name": "AK", "mode": "AK", "access_key_id": "access_key_id", "access_key_secret": "access_key_secret" }, { "name": "RamRoleArn", "mode": "RamRoleArn", "access_key_id": "access_key_id", "access_key_secret": "access_key_secret", "ram_role_arn": "ram_role_arn", "ram_session_name": "ram_session_name", "expired_seconds": 3600, "sts_region": "cn-hangzhou" }, { "name": "EcsRamRole", "mode": "EcsRamRole", "ram_role_name": "ram_role_name" }, { "name": "OIDC", "mode": "OIDC", "ram_role_arn": "ram_role_arn", "oidc_token_file": "path/to/oidc/file", "oidc_provider_arn": "oidc_provider_arn", "ram_session_name": "ram_session_name", "expired_seconds": 3600, "sts_region": "cn-hangzhou" }, { "name": "ChainableRamRoleArn", "mode": "ChainableRamRoleArn", "source_profile": "AK", "ram_role_arn": "ram_role_arn", "ram_session_name": "ram_session_name", "expired_seconds": 3600, "sts_region": "cn-hangzhou" } ] } ``` ### 4. 使用配置文件 > > 如果用户主目录存在默认文件 `~/.alibabacloud/credentials` (Windows 为 `C:\Users\USER_NAME\.alibabacloud\credentials`),程序会自动创建指定类型和名称的凭证。您也可通过环境变量 `ALIBABA_CLOUD_CREDENTIALS_FILE` 指定配置文件路径。如果文件存在,程序将会使用配置文件中 default 指定的凭据信息初始化凭据客户端。当然,您也可以通过环境变量 `ALIBABA_CLOUD_PROFILE` 来指定凭据信息,例如设置 `ALIBABA_CLOUD_PROFILE` 的值为 `client1`。 配置示例信息如下: ```ini [default] type = access_key # 认证方式为 access_key access_key_id = foo # Key access_key_secret = bar # Secret [project1] type = ecs_ram_role # 认证方式为 ecs_ram_role role_name = EcsRamRoleTest # Role Name,非必填,不填则自动获取,建议设置,可以减少网络请求。 [project2] type = ram_role_arn # 认证方式为 ram_role_arn access_key_id = foo access_key_secret = bar role_arn = role_arn role_session_name = session_name [project3] type=oidc_role_arn # 认证方式为 oidc_role_arn oidc_provider_arn=oidc_provider_arn oidc_token_file_path=oidc_token_file_path role_arn=role_arn role_session_name=session_name ``` ### 5. 使用 ECS 实例RAM角色 如果定义了环境变量 `ALIBABA_CLOUD_ECS_METADATA` 且不为空,程序会将该环境变量的值作为角色名称,请求 `http://100.100.100.200/latest/meta-data/ram/security-credentials/` 获取临时安全凭证作为默认凭证。 ### 6. 使用外部服务 Credentials URI 若不存在优先级更高的凭据信息,Credentials工具会在环境变量中获取ALIBABA_CLOUD_CREDENTIALS_URI,若存在,程序将请求该URI地址,获取临时安全凭证作为默认凭据信息。 外部服务响应结构应如下: ```json { "Code": "Success", "AccessKeyId": "AccessKeyId", "AccessKeySecret": "AccessKeySecret", "SecurityToken": "SecurityToken", "Expiration": "2024-10-26T03:46:38Z" } ``` ## 文档 * [先决条件](/docs/zh-CN/0-Prerequisites.md) * [安装](/docs/zh-CN/1-Installation.md) ## 问题 [提交 Issue](https://github.com/aliyun/credentials-php/issues/new/choose),不符合指南的问题可能会立即关闭。 ## 发行说明 每个版本的详细更改记录在[发行说明](/CHANGELOG.md)中。 ## 贡献 提交 Pull Request 之前请阅读[贡献指南](/CONTRIBUTING.md)。 ## 相关 * [OpenAPI 开发者门户][open-api] * [Packagist][packagist] * [Composer][composer] * [Guzzle中文文档][guzzle-docs] * [最新源码][latest-release] ## 许可证 [Apache-2.0](/LICENSE.md) Copyright (c) 2009-present, Alibaba Cloud All rights reserved. [open-api]: https://api.aliyun.com [latest-release]: https://github.com/aliyun/credentials-php [guzzle-docs]: https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html [composer]: https://getcomposer.org [packagist]: https://packagist.org/packages/alibabacloud/credentials README.md000064400000043326147134004340006033 0ustar00English | [简体中文](/README-zh-CN.md) ![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg) # Alibaba Cloud Credentials for PHP [![PHP CI](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml/badge.svg)](https://github.com/aliyun/credentials-php/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/aliyun/credentials-php/graph/badge.svg?token=YIkSjtfKbB)](https://codecov.io/gh/aliyun/credentials-php) [![Latest Stable Version](https://poser.pugx.org/alibabacloud/credentials/v/stable)](https://packagist.org/packages/alibabacloud/credentials) [![composer.lock](https://poser.pugx.org/alibabacloud/credentials/composerlock)](https://packagist.org/packages/alibabacloud/credentials) [![Total Downloads](https://poser.pugx.org/alibabacloud/credentials/downloads)](https://packagist.org/packages/alibabacloud/credentials) [![License](https://poser.pugx.org/alibabacloud/credentials/license)](https://packagist.org/packages/alibabacloud/credentials) Alibaba Cloud Credentials for PHP is a tool that helps PHP developers manage their credentials. ## Prerequisites Your system needs to meet [Prerequisites](/docs/zh-CN/0-Prerequisites.md), including PHP> = 5.6. We strongly recommend using the cURL extension and compiling cURL 7.16.2+ using the TLS backend. ## Installation If you have [Globally Install Composer](https://getcomposer.org/doc/00-intro.md#globally) on your system, install Alibaba Cloud Credentials for PHP as a dependency by running the following directly in the project directory: ```sh composer require alibabacloud/credentials ``` > Some users may not be able to install due to network problems, you can switch to the [Alibaba Cloud Composer Mirror](https://developer.aliyun.com/composer). See [Installation](/docs/zh-CN/1-Installation.md) for details on installing through Composer and other means. ## Quick Examples Before you begin, you need to sign up for an Alibaba Cloud account and retrieve your [Credentials](https://usercenter.console.aliyun.com/#/manage/ak). ### Credential Type #### Default credential provider chain If you do not specify a method to initialize a Credentials client, the default credential provider chain is used. For more information, see the Default credential provider chain section of this topic. ```php getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### AccessKey Setup access_key credential through [User Information Management][ak], it have full authority over the account, please keep it safe. Sometimes for security reasons, you cannot hand over a primary account AccessKey with full access to the developer of a project. You may create a sub-account [RAM Sub-account][ram] , grant its [authorization][permissions],and use the AccessKey of RAM Sub-account. ```php 'access_key', 'accessKeyId' => '', 'accessKeySecret' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); ``` #### STS Create a temporary security credential by applying Temporary Security Credentials (TSC) through the Security Token Service (STS). ```php 'sts', 'accessKeyId' => '', 'accessKeySecret' => '', 'securityToken' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### RamRoleArn By specifying [RAM Role][RAM Role], the credential will be able to automatically request maintenance of STS Token. If you want to limit the permissions([How to make a policy][policy]) of STS Token, you can assign value for `Policy`. ```php 'ram_role_arn', 'accessKeyId' => '', 'accessKeySecret' => '', // Specify the ARN of the RAM role to be assumed. Example: acs:ram::123456789012****:role/adminrole. 'roleArn' => '', // Specify the name of the role session. 'roleSessionName' => '', // Optional. Specify limited permissions for the RAM role. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}. 'policy' => '', # Specify the expiration of the session 'roleSessionExpiration' => 3600, ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### EcsRamRole The Credentials tool automatically obtains the RAM role attached to an ECS instance and uses the metadata server of ECS to obtain an STS token. The STS token is then used to initialize a Credentials client. You can also attach a RAM role to an elastic container instance or a worker node in an Alibaba Cloud Container Service for Kubernetes (ACK) cluster. ```php 'ecs_ram_role', // Optional. Specify the name of the RAM role of the ECS instance. If you do not specify this parameter, its value is automatically obtained. To reduce the number of requests, we recommend that you specify this parameter. 'roleName' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### OIDCRoleArn After you attach a RAM role to a worker node in an Container Service for Kubernetes, applications in the pods on the worker node can use the metadata server to obtain an STS token the same way in which applications on ECS instances do. However, if an untrusted application is deployed on the worker node, such as an application that is submitted by your customer and whose code is unavailable to you, you may not want the application to use the metadata server to obtain an STS token of the RAM role attached to the worker node. To ensure the security of cloud resources and enable untrusted applications to securely obtain required STS tokens, you can use the RAM Roles for Service Accounts (RRSA) feature to grant minimum necessary permissions to an application. In this case, the ACK cluster creates a service account OpenID Connect (OIDC) token file, associates the token file with a pod, and then injects relevant environment variables into the pod. Then, the Credentials tool uses the environment variables to call the AssumeRoleWithOIDC operation of STS and obtains an STS token of the RAM role. For more information about the RRSA feature, see [Use RRSA to authorize different pods to access different cloud services](https://www.alibabacloud.com/help/en/ack/ack-managed-and-ack-dedicated/user-guide/use-rrsa-to-authorize-pods-to-access-different-cloud-services#task-2142941). ```php 'oidc_role_arn', // Specify the ARN of the OIDC IdP by specifying the ALIBABA_CLOUD_OIDC_PROVIDER_ARN environment variable. 'oidcProviderArn' => '', // Specify the path of the OIDC token file by specifying the ALIBABA_CLOUD_OIDC_TOKEN_FILE environment variable. 'oidcTokenFilePath' => '', // Specify the ARN of the RAM role by specifying the ALIBABA_CLOUD_ROLE_ARN environment variable. 'roleArn' => '', // Specify the role session name by specifying the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable. 'roleSessionName' => '', // Optional. Specify limited permissions for the RAM role. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}. 'policy' => '', // Optional. Specify the validity period of the session. 'roleSessionExpiration' => 3600, ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getAccessKeyId(); $credential->getAccessKeySecret(); $credential->getSecurityToken(); ``` #### Credentials URI By specifying the url, the credential will be able to automatically request maintenance of STS Token. ```php 'credentials_uri', // Format: http url. `credentialsURI` can be replaced by setting environment variable: ALIBABA_CLOUD_CREDENTIALS_URI 'credentialsURI' => '', ]); $client = new Credential($config); $credential = $client->getCredential(); $credential->getBearerToken(); ``` #### Bearer Token If credential is required by the Cloud Call Centre (CCC), please apply for Bearer Token maintenance by yourself. ```php 'bearer', 'bearer_token' => '', ]); $bearerToken->getBearerToken(); ``` ## Default credential provider chain If you want to use different types of credentials in the development and production environments of your application, you generally need to obtain the environment information from the code and write code branches to obtain different credentials for the development and production environments. The default credential provider chain of the Credentials tool allows you to use the same code to obtain credentials for different environments based on configurations independent of the application. If you use $credential = new Credential(); to initialize a Credentials client without specifying an initialization method, the Credentials tool obtains the credential information in the following order: ### 1. Environmental certificate Look for environment credentials in environment variable. - If the `ALIBABA_CLOUD_ACCESS_KEY_ID` and `ALIBABA_CLOUD_ACCESS_KEY_SECRET` environment variables are defined and are not empty, the program will use them to create default credentials. - If the `ALIBABA_CLOUD_ACCESS_KEY_ID`, `ALIBABA_CLOUD_ACCESS_KEY_SECRET` and `ALIBABA_CLOUD_SECURITY_TOKEN` environment variables are defined and are not empty, the program will use them to create temporary security credentials(STS). Note: This token has an expiration time, it is recommended to use it in a temporary environment. ### 2. The RAM role of an OIDC IdP If no credentials are found in the previous step, the Credentials tool obtains the values of the following environment variables: `ALIBABA_CLOUD_ROLE_ARN`: the ARN of the RAM role. `ALIBABA_CLOUD_OIDC_PROVIDER_ARN`: the ARN of the OIDC IdP. `ALIBABA_CLOUD_OIDC_TOKEN_FILE`: the path of the OIDC token file. If the preceding three environment variables are specified, the Credentials tool uses the environment variables to call the [AssumeRoleWithOIDC](https://www.alibabacloud.com/help/en/ram/developer-reference/api-sts-2015-04-01-assumerolewithoidc) operation of STS to obtain an STS token as the default credential. ### 3. Using the config.json Configuration File of Aliyun CLI Tool If there is no higher-priority credential information, the Credentials tool will first check the following locations to see if the config.json file exists: Linux system: `~/.aliyun/config.json` Windows system: `C:\Users\USER_NAME\.aliyun\config.json` If the file exists, the program will use the credential information specified by `current` in the configuration file to initialize the credentials client. Of course, you can also use the environment variable `ALIBABA_CLOUD_PROFILE` to specify the credential information, for example by setting the value of `ALIBABA_CLOUD_PROFILE` to `AK`. In the config.json configuration file, the value of each module represents different ways to obtain credential information: - AK: Use the Access Key of the user as credential information; - RamRoleArn: Use the ARN of the RAM role to obtain credential information; - EcsRamRole: Use the RAM role bound to the ECS to obtain credential information; - OIDC: Obtain credential information through OIDC ARN and OIDC Token; - ChainableRamRoleArn: Use the role chaining method to obtain new credential information by specifying other credentials in the JSON file. The configuration example information is as follows: ```json { "current": "AK", "profiles": [ { "name": "AK", "mode": "AK", "access_key_id": "access_key_id", "access_key_secret": "access_key_secret" }, { "name": "RamRoleArn", "mode": "RamRoleArn", "access_key_id": "access_key_id", "access_key_secret": "access_key_secret", "ram_role_arn": "ram_role_arn", "ram_session_name": "ram_session_name", "expired_seconds": 3600, "sts_region": "cn-hangzhou" }, { "name": "EcsRamRole", "mode": "EcsRamRole", "ram_role_name": "ram_role_name" }, { "name": "OIDC", "mode": "OIDC", "ram_role_arn": "ram_role_arn", "oidc_token_file": "path/to/oidc/file", "oidc_provider_arn": "oidc_provider_arn", "ram_session_name": "ram_session_name", "expired_seconds": 3600, "sts_region": "cn-hangzhou" }, { "name": "ChainableRamRoleArn", "mode": "ChainableRamRoleArn", "source_profile": "AK", "ram_role_arn": "ram_role_arn", "ram_session_name": "ram_session_name", "expired_seconds": 3600, "sts_region": "cn-hangzhou" } ] } ``` ### 4. Configuration file > > If the user's home directory has the default file `~/.alibabacloud/credentials` (Windows is `C:\Users\USER_NAME\.alibabacloud\credentials`), the program will automatically create credentials with the specified type and name. You can also specify the configuration file path by configuring the `ALIBABA_CLOUD_CREDENTIALS_FILE` environment variable. If the configuration file exists, the application initializes a Credentials client by using the credential information that is specified by default in the configuration file. You can also configure the `ALIBABA_CLOUD_PROFILE` environment variable to modify the default credential information that is read. Configuration example: ```ini [default] type = access_key # Authentication method is access_key access_key_id = foo # Key access_key_secret = bar # Secret [project1] type = ecs_ram_role # Authentication method is ecs_ram_role role_name = EcsRamRoleTest # Role name, optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. [project2] type = ram_role_arn # Authentication method is ram_role_arn access_key_id = foo access_key_secret = bar role_arn = role_arn role_session_name = session_name [project3] type=oidc_role_arn # Authentication method is oidc_role_arn oidc_provider_arn=oidc_provider_arn oidc_token_file_path=oidc_token_file_path role_arn=role_arn role_session_name=session_name ``` ### 5. Instance RAM role If the environment variable `ALIBABA_CLOUD_ECS_METADATA` is defined and not empty, the program will take the value of the environment variable as the role name and request `http://100.100.100.200/latest/meta-data/ram/security-credentials/` to get the temporary Security credentials are used as default credentials. ### 6. Using External Service Credentials URI If there are no higher-priority credential information, the Credentials tool will obtain the `ALIBABA_CLOUD_CREDENTIALS_URI` from the environment variables. If it exists, the program will request the URI address to obtain temporary security credentials as the default credential information. The external service response structure should be as follows: ```json { "Code": "Success", "AccessKeyId": "AccessKeyId", "AccessKeySecret": "AccessKeySecret", "SecurityToken": "SecurityToken", "Expiration": "2024-10-26T03:46:38Z" } ``` ## Documentation * [Prerequisites](/docs/zh-CN/0-Prerequisites.md) * [Installation](/docs/zh-CN/1-Installation.md) ## Issue [Submit Issue](https://github.com/aliyun/credentials-php/issues/new/choose), Problems that do not meet the guidelines may close immediately. ## Release notes Detailed changes for each version are recorded in the [Release Notes](/CHANGELOG.md). ## Contribution Please read the [Contribution Guide](/CONTRIBUTING.md) before submitting a Pull Request. ## Related * [OpenAPI Developer Portal][open-api] * [Packagist][packagist] * [Composer][composer] * [Guzzle Doc][guzzle-docs] * [Latest Release][latest-release] ## License [Apache-2.0](/LICENSE.md) Copyright (c) 2009-present, Alibaba Cloud All rights reserved. [open-api]: https://api.alibabacloud.com [latest-release]: https://github.com/aliyun/credentials-php [guzzle-docs]: http://docs.guzzlephp.org/en/stable/request-options.html [composer]: https://getcomposer.org [packagist]: https://packagist.org/packages/alibabacloud/credentials SECURITY.md000064400000001153147134004340006335 0ustar00# Security Policy ## Supported Versions Use this section to tell people about which versions of your project are currently being supported with security updates. | Version | Supported | | ------- | ------------------ | | 5.1.x | :white_check_mark: | | 5.0.x | :x: | | 4.0.x | :white_check_mark: | | < 4.0 | :x: | ## Reporting a Vulnerability Use this section to tell people how to report a vulnerability. Tell them where to go, how often they can expect to get an update on a reported vulnerability, what to expect if the vulnerability is accepted or declined, etc. UPGRADING.md000064400000000240147134004340006402 0ustar00Upgrading Guide =============== 1.x ----------------------- - This is the first version. See for more information. composer.json000064400000006105147134004340007270 0ustar00{ "name": "alibabacloud/credentials", "homepage": "https://www.alibabacloud.com/", "description": "Alibaba Cloud Credentials for PHP", "keywords": [ "sdk", "tool", "cloud", "client", "aliyun", "library", "alibaba", "Credentials", "alibabacloud" ], "type": "library", "license": "Apache-2.0", "support": { "source": "https://github.com/aliyun/credentials-php", "issues": "https://github.com/aliyun/credentials-php/issues" }, "authors": [ { "name": "Alibaba Cloud SDK", "email": "sdk-team@alibabacloud.com", "homepage": "http://www.alibabacloud.com" } ], "require": { "php": ">=5.6", "ext-curl": "*", "ext-json": "*", "ext-libxml": "*", "ext-openssl": "*", "ext-mbstring": "*", "ext-simplexml": "*", "ext-xmlwriter": "*", "guzzlehttp/guzzle": "^6.3|^7.0", "adbario/php-dot-notation": "^2.2", "alibabacloud/tea": "^3.0" }, "require-dev": { "ext-spl": "*", "ext-dom": "*", "ext-pcre": "*", "psr/cache": "^1.0", "ext-sockets": "*", "drupal/coder": "^8.3", "symfony/dotenv": "^3.4", "phpunit/phpunit": "^5.7|^6.6|^9.3", "monolog/monolog": "^1.24", "composer/composer": "^1.8", "mikey179/vfsstream": "^1.6", "symfony/var-dumper": "^3.4" }, "suggest": { "ext-sockets": "To use client-side monitoring" }, "autoload": { "psr-4": { "AlibabaCloud\\Credentials\\": "src" } }, "autoload-dev": { "psr-4": { "AlibabaCloud\\Credentials\\Tests\\": "tests/" } }, "config": { "preferred-install": "dist", "optimize-autoloader": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } }, "minimum-stability": "dev", "prefer-stable": true, "scripts-descriptions": { "cs": "Tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard.", "cbf": "Automatically correct coding standard violations.", "fixer": "Fixes code to follow standards.", "test": "Run all tests.", "unit": "Run Unit tests.", "feature": "Run Feature tests.", "clearCache": "Clear cache like coverage.", "coverage": "Show Coverage html.", "endpoints": "Update endpoints from OSS." }, "scripts": { "cs": "phpcs --standard=PSR2 -n ./", "cbf": "phpcbf --standard=PSR2 -n ./", "fixer": "php-cs-fixer fix ./", "test": [ "phpunit --colors=always" ], "unit": [ "@clearCache", "phpunit --testsuite=Unit --colors=always" ], "feature": [ "@clearCache", "phpunit --testsuite=Feature --colors=always" ], "coverage": "open cache/coverage/index.html", "clearCache": "rm -rf cache/*" } } src/AccessKeyCredential.php000064400000003346147134004340011717 0ustar00accessKeyId = $access_key_id; $this->accessKeySecret = $access_key_secret; } /** * @return string */ public function getAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getAccessKeySecret() { return $this->accessKeySecret; } /** * @return string */ public function __toString() { return "$this->accessKeyId#$this->accessKeySecret"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } public function getSecurityToken() { return ''; } /** * @inheritDoc */ public function getCredential() { return new CredentialModel([ 'accessKeyId' => $this->accessKeyId, 'accessKeySecret' => $this->accessKeySecret, 'type' => 'access_key', ]); } } src/BearerTokenCredential.php000064400000002313147134004340012237 0ustar00bearerToken = $bearer_token; } /** * @return string */ public function getBearerToken() { return $this->bearerToken; } /** * @return string */ public function __toString() { return "bearerToken#$this->bearerToken"; } /** * @return BearerTokenSignature */ public function getSignature() { return new BearerTokenSignature(); } /** * @inheritDoc */ public function getCredential() { return new CredentialModel([ 'bearerToken' => $this->bearerToken, 'type' => 'bearer', ]); } } src/Credential.php000064400000021275147134004340010125 0ustar00config = null; } else { $this->config = new Config($this->parseConfig($config)); } } else { $this->config = $config; } $this->credential = $this->getCredentials($this->config); } /** * @param array $config * * @return array */ private function parseConfig($config) { $res = []; foreach (\array_change_key_case($config) as $key => $value) { $res[Helper::snakeToCamelCase($key)] = $value; } return $res; } /** * Credentials getter. * * @param Config $config * @return CredentialsInterface * */ private function getCredentials($config) { if (is_null($config)) { return new CredentialsProviderWrap('default', new DefaultCredentialsProvider()); } switch ($config->type) { case 'access_key': $provider = new StaticAKCredentialsProvider([ 'accessKeyId' => $config->accessKeyId, 'accessKeySecret' => $config->accessKeySecret, ]); return new CredentialsProviderWrap('access_key', $provider); case 'sts': $provider = new StaticSTSCredentialsProvider([ 'accessKeyId' => $config->accessKeyId, 'accessKeySecret' => $config->accessKeySecret, 'securityToken' => $config->securityToken, ]); return new CredentialsProviderWrap('sts', $provider); case 'bearer': return new BearerTokenCredential($config->bearerToken); case 'ram_role_arn': if (!is_null($config->securityToken) && $config->securityToken !== '') { $innerProvider = new StaticSTSCredentialsProvider([ 'accessKeyId' => $config->accessKeyId, 'accessKeySecret' => $config->accessKeySecret, 'securityToken' => $config->securityToken, ]); } else { $innerProvider = new StaticAKCredentialsProvider([ 'accessKeyId' => $config->accessKeyId, 'accessKeySecret' => $config->accessKeySecret, ]); } $provider = new RamRoleArnCredentialsProvider([ 'credentialsProvider' => $innerProvider, 'roleArn' => $config->roleArn, 'roleSessionName' => $config->roleSessionName, 'policy' => $config->policy, 'durationSeconds' => $config->roleSessionExpiration, 'externalId' => $config->externalId, 'stsEndpoint' => $config->STSEndpoint, ], [ 'connectTimeout' => $config->connectTimeout, 'readTimeout' => $config->readTimeout, ]); return new CredentialsProviderWrap('ram_role_arn', $provider); case 'rsa_key_pair': $provider = new RsaKeyPairCredentialsProvider([ 'publicKeyId' => $config->publicKeyId, 'privateKeyFile' => $config->privateKeyFile, 'durationSeconds' => $config->roleSessionExpiration, 'stsEndpoint' => $config->STSEndpoint, ], [ 'connectTimeout' => $config->connectTimeout, 'readTimeout' => $config->readTimeout, ]); return new CredentialsProviderWrap('rsa_key_pair', $provider); case 'ecs_ram_role': $provider = new EcsRamRoleCredentialsProvider([ 'roleName' => $config->roleName, 'disableIMDSv1' => $config->disableIMDSv1, ], [ 'connectTimeout' => $config->connectTimeout, 'readTimeout' => $config->readTimeout, ]); return new CredentialsProviderWrap('ecs_ram_role', $provider); case 'oidc_role_arn': $provider = new OIDCRoleArnCredentialsProvider([ 'roleArn' => $config->roleArn, 'oidcProviderArn' => $config->oidcProviderArn, 'oidcTokenFilePath' => $config->oidcTokenFilePath, 'roleSessionName' => $config->roleSessionName, 'policy' => $config->policy, 'durationSeconds' => $config->roleSessionExpiration, 'stsEndpoint' => $config->STSEndpoint, ], [ 'connectTimeout' => $config->connectTimeout, 'readTimeout' => $config->readTimeout, ]); return new CredentialsProviderWrap('oidc_role_arn', $provider); case "credentials_uri": $provider = new URLCredentialsProvider([ 'credentialsURI' => $config->credentialsURI, ], [ 'connectTimeout' => $config->connectTimeout, 'readTimeout' => $config->readTimeout, ]); return new CredentialsProviderWrap('credentials_uri', $provider); default: throw new InvalidArgumentException('Unsupported credential type option: ' . $config->type . ', support: access_key, sts, bearer, ecs_ram_role, ram_role_arn, rsa_key_pair, oidc_role_arn, credentials_uri'); } } /** * @return CredentialModel * @throws RuntimeException * @throws GuzzleException */ public function getCredential() { return $this->credential->getCredential(); } /** * @return array */ public function getConfig() { return $this->config->toMap(); } /** * @deprecated use getCredential() instead * * @return string * @throws RuntimeException * @throws GuzzleException */ public function getType() { return $this->credential->getCredential()->getType(); } /** * @deprecated use getCredential() instead * * @return string * @throws RuntimeException * @throws GuzzleException */ public function getAccessKeyId() { return $this->credential->getCredential()->getAccessKeyId(); } /** * @deprecated use getCredential() instead * * @return string * @throws RuntimeException * @throws GuzzleException */ public function getAccessKeySecret() { return $this->credential->getCredential()->getAccessKeySecret(); } /** * @deprecated use getCredential() instead * * @return string * @throws RuntimeException * @throws GuzzleException */ public function getSecurityToken() { return $this->credential->getCredential()->getSecurityToken(); } /** * @deprecated use getCredential() instead * * @return string * @throws RuntimeException * @throws GuzzleException */ public function getBearerToken() { return $this->credential->getCredential()->getBearerToken(); } /** * @param string $name * @param array $arguments * * @return mixed */ public function __call($name, $arguments) { return $this->credential->$name($arguments); } } src/Credential/Config.php000064400000014073147134004340011330 0ustar00accessKeyId) { $res['accessKeyId'] = $this->accessKeyId; } if (null !== $this->accessKeySecret) { $res['accessKeySecret'] = $this->accessKeySecret; } if (null !== $this->securityToken) { $res['securityToken'] = $this->securityToken; } if (null !== $this->bearerToken) { $res['bearerToken'] = $this->bearerToken; } if (null !== $this->durationSeconds) { $res['durationSeconds'] = $this->durationSeconds; } if (null !== $this->roleArn) { $res['roleArn'] = $this->roleArn; } if (null !== $this->policy) { $res['policy'] = $this->policy; } if (null !== $this->roleSessionExpiration) { $res['roleSessionExpiration'] = $this->roleSessionExpiration; } if (null !== $this->roleSessionName) { $res['roleSessionName'] = $this->roleSessionName; } if (null !== $this->publicKeyId) { $res['publicKeyId'] = $this->publicKeyId; } if (null !== $this->privateKeyFile) { $res['privateKeyFile'] = $this->privateKeyFile; } if (null !== $this->roleName) { $res['roleName'] = $this->roleName; } if (null !== $this->credentialsURI) { $res['credentialsURI'] = $this->credentialsURI; } if (null !== $this->type) { $res['type'] = $this->type; } if (null !== $this->STSEndpoint) { $res['STSEndpoint'] = $this->STSEndpoint; } if (null !== $this->externalId) { $res['externalId'] = $this->externalId; } return $res; } /** * @param array $map * @return Config */ public static function fromMap($map = []) { $model = new self(); if (isset($map['accessKeyId'])) { $model->accessKeyId = $map['accessKeyId']; } if (isset($map['accessKeySecret'])) { $model->accessKeySecret = $map['accessKeySecret']; } if (isset($map['securityToken'])) { $model->securityToken = $map['securityToken']; } if (isset($map['bearerToken'])) { $model->bearerToken = $map['bearerToken']; } if (isset($map['durationSeconds'])) { $model->durationSeconds = $map['durationSeconds']; } if (isset($map['roleArn'])) { $model->roleArn = $map['roleArn']; } if (isset($map['policy'])) { $model->policy = $map['policy']; } if (isset($map['roleSessionExpiration'])) { $model->roleSessionExpiration = $map['roleSessionExpiration']; } if (isset($map['roleSessionName'])) { $model->roleSessionName = $map['roleSessionName']; } if (isset($map['publicKeyId'])) { $model->publicKeyId = $map['publicKeyId']; } if (isset($map['privateKeyFile'])) { $model->privateKeyFile = $map['privateKeyFile']; } if (isset($map['roleName'])) { $model->roleName = $map['roleName']; } if (isset($map['credentialsURI'])) { $model->credentialsURI = $map['credentialsURI']; } if (isset($map['type'])) { $model->type = $map['type']; } if (isset($map['STSEndpoint'])) { $model->STSEndpoint = $map['STSEndpoint']; } if (isset($map['externalId'])) { $model->externalId = $map['externalId']; } return $model; } /** * @description credential type * @example access_key * @var string */ public $type = 'default'; /** * @description accesskey id * @var string */ public $accessKeyId; /** * @description accesskey secret * @var string */ public $accessKeySecret; /** * @description security token * @var string */ public $securityToken; /** * @description bearer token * @var string */ public $bearerToken; /** * @description role name * @var string */ public $roleName; /** * @description role arn * @var string */ public $roleArn; /** * @description oidc provider arn * @var string */ public $oidcProviderArn; /** * @description oidc token file path * @var string */ public $oidcTokenFilePath; /** * @description role session expiration * @example 3600 * @var int */ public $roleSessionExpiration; /** * @description role session name * @var string */ public $roleSessionName; /** * @description role arn policy * @var string */ public $policy; /** * @description external id for ram role arn * @var string */ public $externalId; /** * @description sts endpoint * @var string */ public $STSEndpoint; public $publicKeyId; public $privateKeyFile; /** * @description read timeout * @var int */ public $readTimeout; /** * @description connection timeout * @var int */ public $connectTimeout; /** * @description disable IMDS v1 * @var bool */ public $disableIMDSv1; /** * @description credentials URI * @var string */ public $credentialsURI; /** * @deprecated */ public $metadataTokenDuration; /** * @deprecated */ public $durationSeconds; /** * @deprecated */ public $host; /** * @deprecated */ public $expiration; /** * @deprecated */ public $certFile = ""; /** * @deprecated */ public $certPassword = ""; /** * @internal */ public $proxy; } src/Credential/CredentialModel.php000064400000005071147134004340013154 0ustar00accessKeyId) { $res['accessKeyId'] = $this->accessKeyId; } if (null !== $this->accessKeySecret) { $res['accessKeySecret'] = $this->accessKeySecret; } if (null !== $this->securityToken) { $res['securityToken'] = $this->securityToken; } if (null !== $this->bearerToken) { $res['bearerToken'] = $this->bearerToken; } if (null !== $this->type) { $res['type'] = $this->type; } return $res; } /** * @param array $map * @return CredentialModel */ public static function fromMap($map = []) { $model = new self(); if (isset($map['accessKeyId'])) { $model->accessKeyId = $map['accessKeyId']; } if (isset($map['accessKeySecret'])) { $model->accessKeySecret = $map['accessKeySecret']; } if (isset($map['securityToken'])) { $model->securityToken = $map['securityToken']; } if (isset($map['bearerToken'])) { $model->bearerToken = $map['bearerToken']; } if (isset($map['type'])) { $model->type = $map['type']; } return $model; } /** * @description accesskey id * @var string */ public $accessKeyId; /** * @description accesskey secret * @var string */ public $accessKeySecret; /** * @description security token * @var string */ public $securityToken; /** * @description bearer token * @var string */ public $bearerToken; /** * @description type * @example access_key * @var string */ public $type; /** * @return string */ public function getAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getAccessKeySecret() { return $this->accessKeySecret; } /** * @return string */ public function getSecurityToken() { return $this->securityToken; } /** * @return string */ public function getBearerToken() { return $this->bearerToken; } public function getType() { return $this->type; } } src/Credentials.php000064400000004226147134004340010305 0ustar00typeName = $typeName; $this->credentialsProvider = $credentialsProvider; } /** * @inheritDoc */ public function getCredential() { $credentials = $this->credentialsProvider->getCredentials(); return new CredentialModel([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'type' => $this->typeName, ]); } /** * @param string $name * @param array $arguments * * @return mixed */ public function __call($name, $arguments) { return $this->credentialsProvider->$name($arguments); } public function __toString() { return "credentialsProviderWrap#$this->typeName"; } /** * @return ShaHmac1Signature */ public function getSignature() { return null; } }src/EcsRamRoleCredential.php000064400000011012147134004340012026 0ustar00roleName = $role_name; Filter::disableIMDSv1($disable_imdsv1); $this->disableIMDSv1 = $disable_imdsv1; $this->metadataTokenDuration = $metadata_token_duration; } /** * @return string * @throws GuzzleException * @throws Exception */ public function getRoleName() { if ($this->roleName !== null) { return $this->roleName; } $this->roleName = $this->getRoleNameFromMeta(); return $this->roleName; } /** * @return string * @throws Exception */ public function getRoleNameFromMeta() { $options = [ 'http_errors' => false, 'timeout' => 1, 'connect_timeout' => 1, ]; $result = Request::createClient()->request( 'GET', 'http://100.100.100.200/latest/meta-data/ram/security-credentials/', $options ); if ($result->getStatusCode() === 404) { throw new InvalidArgumentException('The role name was not found in the instance'); } if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error retrieving credentials from result: ' . $result->getBody()); } $role_name = (string) $result; if (!$role_name) { throw new RuntimeException('Error retrieving credentials from result is empty'); } return $role_name; } /** * @return string */ public function __toString() { return "roleName#$this->roleName"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeyId() { return $this->getSessionCredential()->getAccessKeyId(); } /** * @return AlibabaCloud\Credentials\Providers\Credentials * @throws Exception * @throws GuzzleException */ protected function getSessionCredential() { $params = [ "roleName" => $this->roleName, 'disableIMDSv1' => $this->disableIMDSv1, 'metadataTokenDuration' => $this->metadataTokenDuration, ]; return (new EcsRamRoleCredentialsProvider($params))->getCredentials(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeySecret() { return $this->getSessionCredential()->getAccessKeySecret(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getSecurityToken() { return $this->getSessionCredential()->getSecurityToken(); } /** * @return int * @throws Exception * @throws GuzzleException */ public function getExpiration() { return $this->getSessionCredential()->getExpiration(); } /** * @return bool */ public function isDisableIMDSv1() { return $this->disableIMDSv1; } /** * @inheritDoc */ public function getCredential() { $credentials = $this->getSessionCredential(); return new CredentialModel([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'type' => 'ecs_ram_role', ]); } } src/Providers/CLIProfileCredentialsProvider.php000064400000016335147134004340015652 0ustar00filterProfileName($params); } private function filterProfileName(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) { $this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE'); } if (isset($params['profileName'])) { $this->profileName = $params['profileName']; } } /** * @return bool */ private function shouldReloadCredentialsProvider() { if (is_null($this->credentialsProvider)) { return true; } return false; } /** * @return CredentialsProvider */ protected function reloadCredentialsProvider($profileFile, $profileName) { if (!Helper::inOpenBasedir($profileFile)) { throw new RuntimeException('Unable to open credentials file: ' . $profileFile); } if (!\is_readable($profileFile) || !\is_file($profileFile)) { throw new RuntimeException('Credentials file is not readable: ' . $profileFile); } $jsonContent = \file_get_contents($profileFile); $fileArray = json_decode($jsonContent, true); if (\is_array($fileArray) && !empty($fileArray)) { if (is_null($profileName) || $profileName === '') { $profileName = $fileArray['current']; } if (isset($fileArray['profiles'])) { foreach ($fileArray['profiles'] as $profile) { if (Helper::unsetReturnNull($profile, 'name') === $profileName) { switch (Helper::unsetReturnNull($profile, 'mode')) { case 'AK': return new StaticAKCredentialsProvider([ 'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'), 'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'), ]); case 'RamRoleArn': $innerProvider = new StaticAKCredentialsProvider([ 'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'), 'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'), ]); return new RamRoleArnCredentialsProvider([ 'credentialsProvider' => $innerProvider, 'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'), 'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'), 'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'), 'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'), ]); case 'EcsRamRole': return new EcsRamRoleCredentialsProvider([ 'roleName' => Helper::unsetReturnNull($profile, 'ram_role_name'), ]); case 'OIDC': return new OIDCRoleArnCredentialsProvider([ 'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'), 'oidcProviderArn' => Helper::unsetReturnNull($profile, 'oidc_provider_arn'), 'oidcTokenFilePath' => Helper::unsetReturnNull($profile, 'oidc_token_file'), 'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'), 'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'), 'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'), ]); case 'ChainableRamRoleArn': $previousProvider = $this->reloadCredentialsProvider($profileFile, Helper::unsetReturnNull($profile, 'source_profile')); return new RamRoleArnCredentialsProvider([ 'credentialsProvider' => $previousProvider, 'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'), 'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'), 'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'), 'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'), ]); default: throw new RuntimeException('Unsupported credential mode from CLI credentials file: ' . Helper::unsetReturnNull($profile, 'mode')); } } } } } throw new RuntimeException('Failed to get credential from CLI credentials file: ' . $profileFile); } /** * Get credential. * * @return Credentials * @throws RuntimeException */ public function getCredentials() { if (Helper::envNotEmpty('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') && Helper::env('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') === true) { throw new RuntimeException('CLI credentials file is disabled'); } $cliProfileFile = self::getDefaultFile(); if ($this->shouldReloadCredentialsProvider()) { $this->credentialsProvider = $this->reloadCredentialsProvider($cliProfileFile, $this->profileName); } $credentials = $this->credentialsProvider->getCredentials(); return new Credentials([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(), ]); } /** * Get the default credential file. * * @return string */ private function getDefaultFile() { return Helper::getHomeDirectory() . DIRECTORY_SEPARATOR . '.aliyun' . DIRECTORY_SEPARATOR . 'config.json'; } /** * @return string */ public function getProviderName() { return 'cli_profile'; } } src/Providers/ChainProvider.php000064400000010557147134004340012566 0ustar00 'access_key', 'access_key_id' => $accessKeyId, 'access_key_secret' => $accessKeySecret, ] ); } }; } /** * @return string */ public static function getDefaultName() { $name = Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE'); if ($name) { return $name; } return 'default'; } /** * @return Closure */ public static function ini() { return static function () { $filename = Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE'); if (!$filename) { $filename = self::getDefaultFile(); } if (!Helper::inOpenBasedir($filename)) { return; } if ($filename !== self::getDefaultFile() && (!\is_readable($filename) || !\is_file($filename))) { throw new RuntimeException( 'Credentials file is not readable: ' . $filename ); } $file_array = \parse_ini_file($filename, true); if (\is_array($file_array) && !empty($file_array)) { foreach (\array_change_key_case($file_array) as $name => $configures) { Credentials::set($name, $configures); } } }; } /** * Get the default credential file. * * @return string */ public static function getDefaultFile() { return Helper::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials'; } /** * @return Closure */ public static function instance() { return static function () { $instance = Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA'); if ($instance) { Credentials::set( self::getDefaultName(), [ 'type' => 'ecs_ram_role', 'role_name' => $instance, ] ); } }; } }src/Providers/Credentials.php000064400000002513147134004340012257 0ustar00 $v) { $this->{$k} = $v; } } } /** * @return string */ public function getAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getAccessKeySecret() { return $this->accessKeySecret; } /** * @return string */ public function getSecurityToken() { return $this->securityToken; } /** * @return int */ public function getExpiration() { return $this->expiration; } /** * @return string */ public function getProviderName() { return $this->providerName; } } src/Providers/CredentialsProvider.php000064400000000607147134004340013774 0ustar00filterReuseLastProviderEnabled($params); $this->createDefaultChain(); Filter::reuseLastProviderEnabled($this->reuseLastProviderEnabled); } private function filterReuseLastProviderEnabled(array $params) { $this->reuseLastProviderEnabled = true; if (isset($params['reuseLastProviderEnabled'])) { $this->reuseLastProviderEnabled = $params['reuseLastProviderEnabled']; } } private function createDefaultChain() { self::$defaultProviders = [ new EnvironmentVariableCredentialsProvider(), ]; if ( Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN') && Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_PROVIDER_ARN') && Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_TOKEN_FILE') ) { array_push( self::$defaultProviders, new OIDCRoleArnCredentialsProvider() ); } array_push( self::$defaultProviders, new CLIProfileCredentialsProvider() ); array_push( self::$defaultProviders, new ProfileCredentialsProvider() ); if (Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA')) { array_push( self::$defaultProviders, new EcsRamRoleCredentialsProvider() ); } if (Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_URI')) { array_push( self::$defaultProviders, new URLCredentialsProvider() ); } } /** * @param CredentialsProvider ...$providers */ public static function set(...$providers) { if (empty($providers)) { throw new InvalidArgumentException('No providers in chain'); } foreach ($providers as $provider) { if (!$provider instanceof CredentialsProvider) { throw new InvalidArgumentException('Providers must all be CredentialsProvider'); } } self::$customChain = $providers; } /** * @return bool */ public static function hasCustomChain() { return (bool) self::$customChain; } public static function flush() { self::$customChain = []; } /** * Get credential. * * @return Credentials * @throws RuntimeException */ public function getCredentials() { if ($this->reuseLastProviderEnabled && !is_null($this->lastUsedCredentialsProvider)) { $credentials = $this->lastUsedCredentialsProvider->getCredentials(); return new Credentials([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'providerName' => $this->getProviderName() . '/' . $this->lastUsedCredentialsProvider->getProviderName(), ]); } $providerChain = array_merge( self::$customChain, self::$defaultProviders ); $exceptionMessages = []; foreach ($providerChain as $provider) { try { $credentials = $provider->getCredentials(); $this->lastUsedCredentialsProvider = $provider; return new Credentials([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'providerName' => $this->getProviderName() . '/' . $provider->getProviderName(), ]); } catch (Exception $exception) { array_push($exceptionMessages, basename(str_replace('\\', '/', get_class($provider))) . ': ' . $exception->getMessage()); } } throw new RuntimeException('Unable to load credentials from any of the providers in the chain: ' . implode(', ', $exceptionMessages)); } /** * @inheritDoc */ public function getProviderName() { return "default"; } }src/Providers/EcsRamRoleCredentialsProvider.php000064400000015702147134004340015713 0ustar00filterOptions($options); $this->filterRoleName($params); $this->filterDisableECSIMDSv1($params); Filter::roleName($this->roleName); Filter::disableIMDSv1($this->disableIMDSv1); } private function filterOptions(array $options) { if (isset($options['connectTimeout'])) { $this->connectTimeout = $options['connectTimeout']; } if (isset($options['readTimeout'])) { $this->readTimeout = $options['readTimeout']; } Filter::timeout($this->connectTimeout, $this->readTimeout); } private function filterRoleName(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ECS_METADATA')) { $this->roleName = Helper::env('ALIBABA_CLOUD_ECS_METADATA'); } if (isset($params['roleName'])) { $this->roleName = $params['roleName']; } if (is_null($this->roleName) || $this->roleName === '') { $this->roleName = $this->getRoleNameFromMeta(); } } private function filterDisableECSIMDSv1($params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_IMDSV1_DISABLED')) { $this->disableIMDSv1 = Helper::env('ALIBABA_CLOUD_IMDSV1_DISABLED') === true ? true : false; } if (isset($params['disableIMDSv1'])) { $this->disableIMDSv1 = $params['disableIMDSv1']; } } /** * Get credentials by request. * * @return array * @throws InvalidArgumentException * @throws RuntimeException * @throws GuzzleException */ public function refreshCredentials() { $url = $this->metadataHost . $this->ecsUri . $this->roleName; $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $metadataToken = $this->getMetadataToken(); if (!is_null($metadataToken)) { $options['headers']['X-aliyun-ecs-metadata-token'] = $metadataToken; } $result = Request::createClient()->request('GET', $url, $options); if ($result->getStatusCode() === 404) { throw new InvalidArgumentException('The role was not found in the instance' . (string) $result); } if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error refreshing credentials from IMDS, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result); } $credentials = $result->toArray(); if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) { throw new RuntimeException('Error retrieving credentials from IMDS result:' . $result->toJson()); } if (!isset($credentials['Code']) || $credentials['Code'] !== 'Success') { throw new RuntimeException('Error retrieving credentials from IMDS result, Code is not Success:' . $result->toJson()); } return $credentials; } /** * @return string * @throws InvalidArgumentException * @throws RuntimeException * @throws GuzzleException */ private function getRoleNameFromMeta() { $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $metadataToken = $this->getMetadataToken(); if (!is_null($metadataToken)) { $options['headers']['X-aliyun-ecs-metadata-token'] = $metadataToken; } $result = Request::createClient()->request( 'GET', 'http://100.100.100.200/latest/meta-data/ram/security-credentials/', $options ); if ($result->getStatusCode() === 404) { throw new InvalidArgumentException('The role name was not found in the instance' . (string) $result); } if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error retrieving role name from result: ' . (string) $result); } $role_name = (string) $result; if (!$role_name) { throw new RuntimeException('Error retrieving role name from result is empty'); } return $role_name; } /** * Get metadata token by request. * * @return string * @throws RuntimeException * @throws GuzzleException */ private function getMetadataToken() { $url = $this->metadataHost . $this->metadataTokenUri; $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $options['headers']['X-aliyun-ecs-metadata-token-ttl-seconds'] = $this->metadataTokenDuration; $result = Request::createClient()->request('PUT', $url, $options); if ($result->getStatusCode() != 200) { if ($this->disableIMDSv1) { throw new RuntimeException('Failed to get token from ECS Metadata Service. HttpCode= ' . $result->getStatusCode()); } return null; } return (string) $result; } /** * @return string */ public function key() { return 'ecs_ram_role#roleName#' . $this->roleName; } /** * @return string */ public function getProviderName() { return 'ecs_ram_role'; } /** * @return string */ public function getRoleName() { return $this->roleName; } /** * @return bool */ public function isDisableIMDSv1() { return $this->disableIMDSv1; } } src/Providers/EnvironmentVariableCredentialsProvider.php000064400000003406147134004340017667 0ustar00 $accessKeyId, 'accessKeySecret' => $accessKeySecret, 'securityToken' => $securityToken, 'providerName' => $this->getProviderName(), ]); } /** * @inheritDoc */ public function getProviderName() { return "env"; } }src/Providers/OIDCRoleArnCredentialsProvider.php000064400000016554147134004340015726 0ustar00filterOptions($options); $this->filterRoleArn($params); $this->filterOIDCProviderArn($params); $this->filterOIDCTokenFilePath($params); $this->filterRoleSessionName($params); $this->filterDurationSeconds($params); $this->filterPolicy($params); $this->filterSTSEndpoint($params); } private function filterRoleArn(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')) { $this->roleArn = Helper::env('ALIBABA_CLOUD_ROLE_ARN'); } if (isset($params['roleArn'])) { $this->roleArn = $params['roleArn']; } Filter::roleArn($this->roleArn); } private function filterOIDCProviderArn(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_PROVIDER_ARN')) { $this->oidcProviderArn = Helper::env('ALIBABA_CLOUD_OIDC_PROVIDER_ARN'); } if (isset($params['oidcProviderArn'])) { $this->oidcProviderArn = $params['oidcProviderArn']; } Filter::oidcProviderArn($this->oidcProviderArn); } private function filterOIDCTokenFilePath(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_OIDC_TOKEN_FILE')) { $this->oidcTokenFilePath = Helper::env('ALIBABA_CLOUD_OIDC_TOKEN_FILE'); } if (isset($params['oidcTokenFilePath'])) { $this->oidcTokenFilePath = $params['oidcTokenFilePath']; } Filter::oidcTokenFilePath($this->oidcTokenFilePath); } private function filterRoleSessionName(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_SESSION_NAME')) { $this->roleSessionName = Helper::env('ALIBABA_CLOUD_ROLE_SESSION_NAME'); } if (isset($params['roleSessionName'])) { $this->roleSessionName = $params['roleSessionName']; } if (is_null($this->roleSessionName) || $this->roleSessionName === '') { $this->roleSessionName = 'phpSdkRoleSessionName'; } } private function filterDurationSeconds(array $params) { if (isset($params['durationSeconds'])) { if (is_int($params['durationSeconds'])) { $this->durationSeconds = $params['durationSeconds']; } } if ($this->durationSeconds < 900) { throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration'); } } private function filterPolicy(array $params) { if (isset($params['policy'])) { if (is_string($params['policy'])) { $this->policy = $params['policy']; } if (is_array($params['policy'])) { $this->policy = json_encode($params['policy']); } } } private function filterSTSEndpoint(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_STS_REGION')) { $this->stsEndpoint = 'sts' . Helper::env('ALIBABA_CLOUD_STS_REGION') . '.aliyuncs.com'; } if (isset($params['stsRegionId'])) { $this->stsEndpoint = 'sts' . $params['stsRegionId'] . '.aliyuncs.com'; } if (isset($params['stsEndpoint'])) { $this->stsEndpoint = $params['stsEndpoint']; } if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') { $this->stsEndpoint = 'sts.aliyuncs.com'; } } private function filterOptions(array $options) { if (isset($options['connectTimeout'])) { $this->connectTimeout = $options['connectTimeout']; } if (isset($options['readTimeout'])) { $this->readTimeout = $options['readTimeout']; } Filter::timeout($this->connectTimeout, $this->readTimeout); } /** * Get credentials by request. * * @return array * @throws RuntimeException * @throws GuzzleException */ public function refreshCredentials() { $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $options['query']['Action'] = 'AssumeRoleWithOIDC'; $options['query']['Version'] = '2015-04-01'; $options['query']['Format'] = 'JSON'; $options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z'); $options['query']['RoleArn'] = $this->roleArn; $options['query']['OIDCProviderArn'] = $this->oidcProviderArn; try { $oidcToken = file_get_contents($this->oidcTokenFilePath); $options['query']['OIDCToken'] = $oidcToken; } catch (Exception $exception) { throw new InvalidArgumentException($exception->getMessage()); } $options['query']['RoleSessionName'] = $this->roleSessionName; $options['query']['DurationSeconds'] = (string) $this->durationSeconds; if (!is_null($this->policy)) { $options['query']['Policy'] = $this->policy; } $url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint); $result = Request::createClient()->request('POST', $url, $options); if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error refreshing credentials from OIDC, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result); } $json = $result->toArray(); $credentials = $json['Credentials']; if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) { throw new RuntimeException('Error retrieving credentials from OIDC result:' . $result->toJson()); } return $credentials; } public function key() { return 'oidc_role_arn#roleArn#' . $this->roleArn . '#oidcProviderArn#' . $this->oidcProviderArn . '#roleSessionName#' . $this->roleSessionName; } public function getProviderName() { return 'oidc_role_arn'; } } src/Providers/ProfileCredentialsProvider.php000064400000015207147134004340015317 0ustar00filterProfileName($params); $this->filterProfileFile(); } private function filterProfileName(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) { $this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE'); } if (isset($params['profileName'])) { $this->profileName = $params['profileName']; } if (is_null($this->profileName) || $this->profileName === '') { $this->profileName = 'default'; } } private function filterProfileFile() { $this->profileFile = Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_FILE'); if (!$this->profileFile) { $this->profileFile = self::getDefaultFile(); } } /** * @return bool */ private function shouldReloadCredentialsProvider() { if (is_null($this->credentialsProvider)) { return true; } return false; } /** * @return CredentialsProvider */ private function reloadCredentialsProvider($profileFile, $profileName) { if (!Helper::inOpenBasedir($profileFile)) { throw new RuntimeException('Unable to open credentials file: ' . $profileFile); } if (!\is_readable($profileFile) || !\is_file($profileFile)) { throw new RuntimeException('Credentials file is not readable: ' . $profileFile); } $fileArray = \parse_ini_file($profileFile, true); if (\is_array($fileArray) && !empty($fileArray)) { $credentialsConfigures = []; foreach (\array_change_key_case($fileArray) as $name => $configures) { if ($name === $profileName) { $credentialsConfigures = $configures; break; } } if (\is_array($credentialsConfigures) && !empty($credentialsConfigures)) { switch (Helper::unsetReturnNull($credentialsConfigures, 'type')) { case 'access_key': return new StaticAKCredentialsProvider([ 'accessKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_id'), 'accessKeySecret' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_secret'), ]); case 'ram_role_arn': $innerProvider = new StaticAKCredentialsProvider([ 'accessKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_id'), 'accessKeySecret' => Helper::unsetReturnNull($credentialsConfigures, 'access_key_secret'), ]); return new RamRoleArnCredentialsProvider([ 'credentialsProvider' => $innerProvider, 'roleArn' => Helper::unsetReturnNull($credentialsConfigures, 'role_arn'), 'roleSessionName' => Helper::unsetReturnNull($credentialsConfigures, 'role_session_name'), 'policy' => Helper::unsetReturnNull($credentialsConfigures, 'policy'), ]); case 'ecs_ram_role': return new EcsRamRoleCredentialsProvider([ 'roleName' => Helper::unsetReturnNull($credentialsConfigures, 'role_name'), ]); case 'oidc_role_arn': return new OIDCRoleArnCredentialsProvider([ 'roleArn' => Helper::unsetReturnNull($credentialsConfigures, 'role_arn'), 'oidcProviderArn' => Helper::unsetReturnNull($credentialsConfigures, 'oidc_provider_arn'), 'oidcTokenFilePath' => Helper::unsetReturnNull($credentialsConfigures, 'oidc_token_file_path'), 'roleSessionName' => Helper::unsetReturnNull($credentialsConfigures, 'role_session_name'), 'policy' => Helper::unsetReturnNull($credentialsConfigures, 'policy'), ]); case 'rsa_key_pair': return new RsaKeyPairCredentialsProvider([ 'publicKeyId' => Helper::unsetReturnNull($credentialsConfigures, 'public_key_id'), 'privateKeyFile' => Helper::unsetReturnNull($credentialsConfigures, 'private_key_file'), ]); default: throw new RuntimeException('Unsupported credential type from credentials file: ' . Helper::unsetReturnNull($credentialsConfigures, 'type')); } } } throw new RuntimeException('Failed to get credential from credentials file: ' . $profileFile); } /** * Get credential. * * @return Credentials * @throws RuntimeException */ public function getCredentials() { if ($this->shouldReloadCredentialsProvider()) { $this->credentialsProvider = $this->reloadCredentialsProvider($this->profileFile, $this->profileName); } $credentials = $this->credentialsProvider->getCredentials(); return new Credentials([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(), ]); } /** * Get the default credential file. * * @return string */ private function getDefaultFile() { return Helper::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials'; } /** * @return string */ public function getProviderName() { return 'profile'; } } src/Providers/RamRoleArnCredentialsProvider.php000064400000022414147134004340015717 0ustar00filterOptions($options); $this->filterCredentials($params); $this->filterRoleArn($params); $this->filterRoleSessionName($params); $this->filterDurationSeconds($params); $this->filterPolicy($params); $this->filterExternalId($params); $this->filterSTSEndpoint($params); } private function filterRoleArn(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_ARN')) { $this->roleArn = Helper::env('ALIBABA_CLOUD_ROLE_ARN'); } if (isset($params['roleArn'])) { $this->roleArn = $params['roleArn']; } Filter::roleArn($this->roleArn); } private function filterRoleSessionName(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ROLE_SESSION_NAME')) { $this->roleSessionName = Helper::env('ALIBABA_CLOUD_ROLE_SESSION_NAME'); } if (isset($params['roleSessionName'])) { $this->roleSessionName = $params['roleSessionName']; } if (is_null($this->roleSessionName) || $this->roleSessionName === '') { $this->roleSessionName = 'phpSdkRoleSessionName'; } } private function filterDurationSeconds(array $params) { if (isset($params['durationSeconds'])) { if (is_int($params['durationSeconds'])) { $this->durationSeconds = $params['durationSeconds']; } } if ($this->durationSeconds < 900) { throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration'); } } private function filterPolicy(array $params) { if (isset($params['policy'])) { if (is_string($params['policy'])) { $this->policy = $params['policy']; } if (is_array($params['policy'])) { $this->policy = json_encode($params['policy']); } } } private function filterExternalId(array $params) { if (isset($params['externalId'])) { if (is_string($params['externalId'])) { $this->externalId = $params['externalId']; } } } private function filterSTSEndpoint(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_STS_REGION')) { $this->stsEndpoint = 'sts.' . Helper::env('ALIBABA_CLOUD_STS_REGION') . '.aliyuncs.com'; } if (isset($params['stsRegionId'])) { $this->stsEndpoint = 'sts.' . $params['stsRegionId'] . '.aliyuncs.com'; } if (isset($params['stsEndpoint'])) { $this->stsEndpoint = $params['stsEndpoint']; } if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') { $this->stsEndpoint = 'sts.aliyuncs.com'; } } private function filterCredentials(array $params) { if (isset($params['credentialsProvider'])) { if (!($params['credentialsProvider'] instanceof CredentialsProvider)) { throw new InvalidArgumentException('Invalid credentialsProvider option for ram_role_arn'); } $this->credentialsProvider = $params['credentialsProvider']; } else if (isset($params['accessKeyId']) && isset($params['accessKeySecret']) && isset($params['securityToken'])) { Filter::accessKey($params['accessKeyId'], $params['accessKeySecret']); Filter::securityToken($params['securityToken']); $this->credentialsProvider = new StaticSTSCredentialsProvider($params); } else if (isset($params['accessKeyId']) && isset($params['accessKeySecret'])) { Filter::accessKey($params['accessKeyId'], $params['accessKeySecret']); $this->credentialsProvider = new StaticAKCredentialsProvider($params); } else { throw new InvalidArgumentException('Missing required credentials option for ram_role_arn'); } } private function filterOptions(array $options) { if (isset($options['connectTimeout'])) { $this->connectTimeout = $options['connectTimeout']; } if (isset($options['readTimeout'])) { $this->readTimeout = $options['readTimeout']; } Filter::timeout($this->connectTimeout, $this->readTimeout); } /** * Get credentials by request. * * @return array * @throws RuntimeException * @throws GuzzleException */ public function refreshCredentials() { $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $options['query']['Action'] = 'AssumeRole'; $options['query']['Version'] = '2015-04-01'; $options['query']['Format'] = 'JSON'; $options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z'); $options['query']['SignatureMethod'] = 'HMAC-SHA1'; $options['query']['SignatureVersion'] = '1.0'; $options['query']['SignatureNonce'] = Request::uuid(json_encode($options['query'])); $options['query']['RoleArn'] = $this->roleArn; $options['query']['RoleSessionName'] = $this->roleSessionName; $options['query']['DurationSeconds'] = (string) $this->durationSeconds; if (!is_null($this->policy) && $this->policy !== '') { $options['query']['Policy'] = $this->policy; } if (!is_null($this->externalId) && $this->externalId !== '') { $options['query']['ExternalId'] = $this->externalId; } $sessionCredentials = $this->credentialsProvider->getCredentials(); $options['query']['AccessKeyId'] = $sessionCredentials->getAccessKeyId(); if (!is_null($sessionCredentials->getSecurityToken())) { $options['query']['SecurityToken'] = $sessionCredentials->getSecurityToken(); } $options['query']['Signature'] = Request::shaHmac1sign( Request::signString('GET', $options['query']), $sessionCredentials->getAccessKeySecret() . '&' ); $url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint); $result = Request::createClient()->request('GET', $url, $options); if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error refreshing credentials from RamRoleArn, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result); } $json = $result->toArray(); $credentials = $json['Credentials']; if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken'])) { throw new RuntimeException('Error retrieving credentials from RamRoleArn result:' . $result->toJson()); } return $credentials; } public function key() { $credentials = $this->credentialsProvider->getCredentials(); return 'ram_role_arn#credential#' . $credentials->getAccessKeyId() . '#roleArn#' . $this->roleArn . '#roleSessionName#' . $this->roleSessionName; } public function getProviderName() { return 'ram_role_arn/' . $this->credentialsProvider->getProviderName(); } /** * @return string */ public function getRoleArn() { return $this->roleArn; } /** * @return string */ public function getRoleSessionName() { return $this->roleSessionName; } /** * @return string */ public function getPolicy() { return $this->policy; } /** * @deprecated * @return string */ public function getOriginalAccessKeyId() { return $this->credentialsProvider->getCredentials()->getAccessKeyId(); } /** * @deprecated * @return string */ public function getOriginalAccessKeySecret() { return $this->credentialsProvider->getCredentials()->getAccessKeySecret(); } } src/Providers/RsaKeyPairCredentialsProvider.php000064400000013026147134004340015726 0ustar00filterOptions($options); $this->filterDurationSeconds($params); $this->filterSTSEndpoint($params); $this->publicKeyId = isset($params['publicKeyId']) ? $params['publicKeyId'] : null; $privateKeyFile = isset($params['privateKeyFile']) ? $params['privateKeyFile'] : null; Filter::publicKeyId($this->publicKeyId); Filter::privateKeyFile($privateKeyFile); try { $this->privateKey = file_get_contents($privateKeyFile); } catch (Exception $exception) { throw new InvalidArgumentException($exception->getMessage()); } } private function filterOptions(array $options) { if (isset($options['connectTimeout'])) { $this->connectTimeout = $options['connectTimeout']; } if (isset($options['readTimeout'])) { $this->readTimeout = $options['readTimeout']; } Filter::timeout($this->connectTimeout, $this->readTimeout); } private function filterDurationSeconds(array $params) { if (isset($params['durationSeconds'])) { if (is_int($params['durationSeconds'])) { $this->durationSeconds = $params['durationSeconds']; } } if ($this->durationSeconds < 900) { throw new InvalidArgumentException('Role session expiration should be in the range of 900s - max session duration'); } } private function filterSTSEndpoint(array $params) { if (isset($params['stsEndpoint'])) { $this->stsEndpoint = $params['stsEndpoint']; } if (is_null($this->stsEndpoint) || $this->stsEndpoint === '') { $this->stsEndpoint = 'sts.ap-northeast-1.aliyuncs.com'; } } /** * Get credentials by request. * * @return array * @throws RuntimeException * @throws GuzzleException */ public function refreshCredentials() { $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $options['query']['Action'] = 'GenerateSessionAccessKey'; $options['query']['Version'] = '2015-04-01'; $options['query']['Format'] = 'JSON'; $options['query']['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z'); $options['query']['SignatureMethod'] = 'SHA256withRSA'; $options['query']['SignatureType'] = 'PRIVATEKEY'; $options['query']['SignatureVersion'] = '1.0'; $options['query']['SignatureNonce'] = Request::uuid(json_encode($options['query'])); $options['query']['DurationSeconds'] = (string) $this->durationSeconds; $options['query']['AccessKeyId'] = $this->publicKeyId; $options['query']['Signature'] = Request::shaHmac256WithRsasign( Request::signString('GET', $options['query']), $this->privateKey ); $url = (new Uri())->withScheme('https')->withHost($this->stsEndpoint); $result = Request::createClient()->request('GET', $url, $options); if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error refreshing credentials from RsaKeyPair, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result); } $json = $result->toArray(); if (!isset($json['SessionAccessKey']['SessionAccessKeyId']) || !isset($json['SessionAccessKey']['SessionAccessKeySecret'])) { throw new RuntimeException('Error retrieving credentials from RsaKeyPair result:' . $result->toJson()); } $credentials = []; $credentials['AccessKeyId'] = $json['SessionAccessKey']['SessionAccessKeyId']; $credentials['AccessKeySecret'] = $json['SessionAccessKey']['SessionAccessKeySecret']; $credentials['Expiration'] = $json['SessionAccessKey']['Expiration']; $credentials['SecurityToken'] = null; return $credentials; } public function key() { return 'rsa_key_pair#publicKeyId#' . $this->publicKeyId; } public function getProviderName() { return 'rsa_key_pair'; } /** * @return string */ public function getPublicKeyId() { return $this->publicKeyId; } /** * @return mixed */ public function getPrivateKey() { return $this->privateKey; } } src/Providers/SessionCredentialsProvider.php000064400000003731147134004340015341 0ustar00key()])) { $result = self::$credentialsCache[$this->key()]; if (\strtotime($result['Expiration']) - \time() >= $this->expirationSlot) { return $result; } } return null; } /** * Cache credentials. * * @param array $credential */ protected function cache(array $credential) { self::$credentialsCache[$this->key()] = $credential; } /** * Get credential. * * @return Credentials */ public function getCredentials() { $credentials = $this->getCredentialsInCache(); if ($credentials === null) { $credentials = $this->refreshCredentials(); $this->cache($credentials); } return new Credentials([ 'accessKeyId' => $credentials['AccessKeyId'], 'accessKeySecret' => $credentials['AccessKeySecret'], 'securityToken' => $credentials['SecurityToken'], 'expiration' => \strtotime($credentials['Expiration']), 'providerName' => $this->getProviderName(), ]); } /** * @return array */ abstract function refreshCredentials(); /** * Get the toString of the credentials provider as the key. * * @return string */ abstract function key(); } src/Providers/StaticAKCredentialsProvider.php000064400000003454147134004340015363 0ustar00filterAK($params); } private function filterAK(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) { $this->accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID'); } if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) { $this->accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET'); } if (isset($params['accessKeyId'])) { $this->accessKeyId = $params['accessKeyId']; } if (isset($params['accessKeySecret'])) { $this->accessKeySecret = $params['accessKeySecret']; } Filter::accessKey($this->accessKeyId, $this->accessKeySecret); } /** * Get credential. * * @return Credentials */ public function getCredentials() { return new Credentials([ 'accessKeyId' => $this->accessKeyId, 'accessKeySecret' => $this->accessKeySecret, 'providerName' => $this->getProviderName(), ]); } /** * @inheritDoc */ public function getProviderName() { return "static_ak"; } }src/Providers/StaticSTSCredentialsProvider.php000064400000004356147134004340015543 0ustar00filterSTS($params); } private function filterSTS(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_ID')) { $this->accessKeyId = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_ID'); } if (Helper::envNotEmpty('ALIBABA_CLOUD_ACCESS_KEY_SECRET')) { $this->accessKeySecret = Helper::env('ALIBABA_CLOUD_ACCESS_KEY_SECRET'); } if (Helper::envNotEmpty('ALIBABA_CLOUD_SECURITY_TOKEN')) { $this->securityToken = Helper::env('ALIBABA_CLOUD_SECURITY_TOKEN'); } if (isset($params['accessKeyId'])) { $this->accessKeyId = $params['accessKeyId']; } if (isset($params['accessKeySecret'])) { $this->accessKeySecret = $params['accessKeySecret']; } if (isset($params['securityToken'])) { $this->securityToken = $params['securityToken']; } Filter::accessKey($this->accessKeyId, $this->accessKeySecret); Filter::securityToken($this->securityToken); } /** * Get credential. * * @return Credentials */ public function getCredentials() { return new Credentials([ 'accessKeyId' => $this->accessKeyId, 'accessKeySecret' => $this->accessKeySecret, 'securityToken' => $this->securityToken, 'providerName' => $this->getProviderName(), ]); } /** * @inheritDoc */ public function getProviderName() { return "static_sts"; } }src/Providers/URLCredentialsProvider.php000064400000006075147134004340014364 0ustar00filterOptions($options); $this->filterCredentialsURI($params); } private function filterOptions(array $options) { if (isset($options['connectTimeout'])) { $this->connectTimeout = $options['connectTimeout']; } if (isset($options['readTimeout'])) { $this->readTimeout = $options['readTimeout']; } Filter::timeout($this->connectTimeout, $this->readTimeout); } private function filterCredentialsURI(array $params) { if (Helper::envNotEmpty('ALIBABA_CLOUD_CREDENTIALS_URI')) { $this->credentialsURI = Helper::env('ALIBABA_CLOUD_CREDENTIALS_URI'); } if (isset($params['credentialsURI'])) { $this->credentialsURI = $params['credentialsURI']; } Filter::credentialsURI($this->credentialsURI); } /** * Get credentials by request. * * @return array * @throws InvalidArgumentException * @throws RuntimeException * @throws GuzzleException */ public function refreshCredentials() { $options = Request::commonOptions(); $options['read_timeout'] = $this->readTimeout; $options['connect_timeout'] = $this->connectTimeout; $result = Request::createClient()->request('GET', $this->credentialsURI, $options); if ($result->getStatusCode() !== 200) { throw new RuntimeException('Error refreshing credentials from credentialsURI, statusCode: ' . $result->getStatusCode() . ', result: ' . (string) $result); } $credentials = $result->toArray(); if (!isset($credentials['AccessKeyId']) || !isset($credentials['AccessKeySecret']) || !isset($credentials['SecurityToken']) || !isset($credentials['Expiration'])) { throw new RuntimeException('Error retrieving credentials from credentialsURI result:' . $result->toJson()); } return $credentials; } /** * @return string */ public function key() { return 'credential_uri#' . $this->credentialsURI; } /** * @return string */ public function getProviderName() { return 'credential_uri'; } } src/RamRoleArnCredential.php000064400000013061147134004340012042 0ustar00filterParameters($credential); $this->filterPolicy($credential); Filter::accessKey($credential['access_key_id'], $credential['access_key_secret']); $this->config = $config; $this->accessKeyId = $credential['access_key_id']; $this->accessKeySecret = $credential['access_key_secret']; $this->roleArn = $credential['role_arn']; $this->roleSessionName = $credential['role_session_name']; } /** * @param array $credential */ private function filterParameters(array $credential) { if (!isset($credential['access_key_id'])) { throw new InvalidArgumentException('Missing required access_key_id option in config for ram_role_arn'); } if (!isset($credential['access_key_secret'])) { throw new InvalidArgumentException('Missing required access_key_secret option in config for ram_role_arn'); } if (!isset($credential['role_arn'])) { throw new InvalidArgumentException('Missing required role_arn option in config for ram_role_arn'); } if (!isset($credential['role_session_name'])) { throw new InvalidArgumentException('Missing required role_session_name option in config for ram_role_arn'); } } /** * @param array $credential */ private function filterPolicy(array $credential) { if (isset($credential['policy'])) { if (is_string($credential['policy'])) { $this->policy = $credential['policy']; } if (is_array($credential['policy'])) { $this->policy = json_encode($credential['policy']); } } } /** * @return array */ public function getConfig() { return $this->config; } /** * @return string */ public function getRoleArn() { return $this->roleArn; } /** * @return string */ public function getRoleSessionName() { return $this->roleSessionName; } /** * @return string */ public function getPolicy() { return $this->policy; } /** * @return string */ public function __toString() { return "$this->accessKeyId#$this->accessKeySecret#$this->roleArn#$this->roleSessionName"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @return string */ public function getOriginalAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getOriginalAccessKeySecret() { return $this->accessKeySecret; } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeyId() { return $this->getSessionCredential()->getAccessKeyId(); } /** * @return AlibabaCloud\Credentials\Providers\Credentials * @throws Exception * @throws GuzzleException */ protected function getSessionCredential() { $params = [ 'accessKeyId' => $this->accessKeyId, 'accessKeySecret' => $this->accessKeyId, 'roleArn' => $this->roleArn, 'roleSessionName' => $this->roleSessionName, 'policy' => $this->policy, ]; return (new RamRoleArnCredentialsProvider($params))->getCredentials(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeySecret() { return $this->getSessionCredential()->getAccessKeySecret(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getSecurityToken() { return $this->getSessionCredential()->getSecurityToken(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getExpiration() { return $this->getSessionCredential()->getExpiration(); } /** * @inheritDoc */ public function getCredential() { $credentials = $this->getSessionCredential(); return new CredentialModel([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'type' => 'ram_role_arn', ]); } } src/Request/Request.php000064400000007551147134004340011134 0ustar00 $value) { $canonicalized .= '&' . self::percentEncode($key) . '=' . self::percentEncode($value); } return $method . '&%2F&' . self::percentEncode(substr($canonicalized, 1)); } /** * @param string $string * @param string $accessKeySecret * * @return string */ public static function shaHmac1sign($string, $accessKeySecret) { return base64_encode(hash_hmac('sha1', $string, $accessKeySecret, true)); } /** * @param string $string * @param string $accessKeySecret * * @return string */ public static function shaHmac256sign($string, $accessKeySecret) { return base64_encode(hash_hmac('sha256', $string, $accessKeySecret, true)); } /** * @param string $string * @param string $privateKey * * @return string */ public static function shaHmac256WithRsasign($string, $privateKey) { $binarySignature = ''; try { openssl_sign( $string, $binarySignature, $privateKey, \OPENSSL_ALGO_SHA256 ); } catch (Exception $exception) { throw new InvalidArgumentException( $exception->getMessage() ); } return base64_encode($binarySignature); } /** * @param string $string * * @return null|string|string[] */ private static function percentEncode($string) { $result = rawurlencode($string); $result = str_replace(['+', '*'], ['%20', '%2A'], $result); $result = preg_replace('/%7E/', '~', $result); return $result; } /** * @return Client * @throws Exception */ public static function createClient() { if (Credentials::hasMock()) { $stack = HandlerStack::create(Credentials::getMock()); $history = Credentials::getHandlerHistory(); $stack->push($history); } else { $stack = HandlerStack::create(); } $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) { return new Response($response); })); self::$config['handler'] = $stack; return new Client(self::$config); } } src/RsaKeyPairCredential.php000064400000007720147134004340012057 0ustar00publicKeyId = $public_key_id; $this->privateKeyFile = $private_key_file; $this->config = $config; try { $this->privateKey = file_get_contents($private_key_file); } catch (Exception $exception) { throw new InvalidArgumentException($exception->getMessage()); } } /** * @return array */ public function getConfig() { return $this->config; } /** * @return string */ public function getOriginalAccessKeyId() { return $this->getPublicKeyId(); } /** * @return string */ public function getPublicKeyId() { return $this->publicKeyId; } /** * @return string */ public function getOriginalAccessKeySecret() { return $this->getPrivateKey(); } /** * @return mixed */ public function getPrivateKey() { return $this->privateKey; } /** * @return string */ public function __toString() { return "publicKeyId#$this->publicKeyId"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeyId() { return $this->getSessionCredential()->getAccessKeyId(); } /** * @return AlibabaCloud\Credentials\Providers\Credentials * @throws Exception * @throws GuzzleException */ protected function getSessionCredential() { $params = [ 'publicKeyId' => $this->publicKeyId, 'privateKeyFile' => $this->privateKeyFile, ]; return (new RsaKeyPairCredentialsProvider($params))->getCredentials(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getAccessKeySecret() { return $this->getSessionCredential()->getAccessKeySecret(); } /** * @return string * @throws Exception * @throws GuzzleException */ public function getSecurityToken() { return $this->getSessionCredential()->getSecurityToken(); } /** * @return int * @throws Exception * @throws GuzzleException */ public function getExpiration() { return $this->getSessionCredential()->getExpiration(); } /** * @inheritDoc */ public function getCredential() { $credentials = $this->getSessionCredential(); return new CredentialModel([ 'accessKeyId' => $credentials->getAccessKeyId(), 'accessKeySecret' => $credentials->getAccessKeySecret(), 'securityToken' => $credentials->getSecurityToken(), 'type' => 'rsa_key_pair', ]); } } src/Signature/BearerTokenSignature.php000064400000001316147134004340014071 0ustar00getMessage() ); } return base64_encode($binarySignature); } } src/Signature/SignatureInterface.php000064400000001055147134004340013570 0ustar00accessKeyId = $access_key_id; $this->accessKeySecret = $access_key_secret; $this->expiration = $expiration; $this->securityToken = $security_token; } /** * @return int */ public function getExpiration() { return $this->expiration; } /** * @return string */ public function getAccessKeyId() { return $this->accessKeyId; } /** * @return string */ public function getAccessKeySecret() { return $this->accessKeySecret; } /** * @return string */ public function getSecurityToken() { return $this->securityToken; } /** * @return string */ public function __toString() { return "$this->accessKeyId#$this->accessKeySecret#$this->securityToken"; } /** * @return ShaHmac1Signature */ public function getSignature() { return new ShaHmac1Signature(); } /** * @inheritDoc */ public function getCredential() { return new CredentialModel([ 'accessKeyId' => $this->accessKeyId, 'accessKeySecret' => $this->accessKeySecret, 'securityToken' => $this->securityToken, 'type' => 'sts', ]); } } src/Utils/Filter.php000064400000013336147134004340010377 0ustar00 $value) { if (is_int($key)) { $result[] = $value; continue; } if (isset($result[$key]) && is_array($result[$key])) { $result[$key] = self::merge( [$result[$key], $value] ); continue; } $result[$key] = $value; } } return $result; } /** * @param $filename * * @return bool */ public static function inOpenBasedir($filename) { $open_basedir = ini_get('open_basedir'); if (!$open_basedir) { return true; } if (0 === strpos($filename, vfsStream::SCHEME)) { // 虚拟文件忽略 return true; } $dirs = explode(PATH_SEPARATOR, $open_basedir); return empty($dirs) || self::inDir($filename, $dirs); } /** * @param string $filename * @param array $dirs * * @return bool */ public static function inDir($filename, array $dirs) { foreach ($dirs as $dir) { if ($dir[strlen($dir) - 1] !== DIRECTORY_SEPARATOR) { $dir .= DIRECTORY_SEPARATOR; } if (0 === strpos($filename, $dir)) { return true; } } return false; } /** * @return bool */ public static function isWindows() { return PATH_SEPARATOR === ';'; } /** * @param $key * * @return bool|mixed */ public static function envNotEmpty($key) { $value = self::env($key, false); if ($value) { return $value; } return false; } /** * Gets the value of an environment variable. * * @param string $key * @param mixed $default * * @return mixed */ public static function env($key, $default = null) { $value = getenv($key); if ($value === false) { return self::value($default); } if (self::envSubstr($value)) { return substr($value, 1, -1); } return self::envConversion($value); } /** * Return the default value of the given value. * * @param mixed $value * * @return mixed */ public static function value($value) { return $value instanceof Closure ? $value() : $value; } /** * @param $value * * @return bool */ public static function envSubstr($value) { return ($valueLength = strlen($value)) > 1 && strpos($value, '"') === 0 && $value[$valueLength - 1] === '"'; } /** * @param $value * * @return bool|string|null */ public static function envConversion($value) { $key = strtolower($value); if ($key === 'null' || $key === '(null)') { return null; } $list = [ 'true' => true, '(true)' => true, 'false' => false, '(false)' => false, 'empty' => '', '(empty)' => '', ]; return isset($list[$key]) ? $list[$key] : $value; } /** * Gets the environment's HOME directory. * * @return null|string */ public static function getHomeDirectory() { if (getenv('HOME')) { return getenv('HOME'); } return (getenv('HOMEDRIVE') && getenv('HOMEPATH')) ? getenv('HOMEDRIVE') . getenv('HOMEPATH') : null; } /** * @param mixed ...$parameters * * @codeCoverageIgnore */ public static function dd(...$parameters) { dump(...$parameters); exit; } /** * Snake to camel case. * * @param string $str * * @return string */ public static function snakeToCamelCase($str) { $components = explode('_', $str); $camelCaseStr = $components[0]; for ($i = 1; $i < count($components); $i++) { $camelCaseStr .= ucfirst($components[$i]); } return $camelCaseStr; } /** * Get user agent. * * @param string $userAgent * * @return string */ public static function getUserAgent() { return sprintf('AlibabaCloud (%s; %s) PHP/%s Credentials/%s TeaDSL/1', PHP_OS, \PHP_SAPI, PHP_VERSION, Credential::VERSION); } /** * @param array $arrays * @param string $key * * @return mix */ public static function unsetReturnNull(array $arrays, $key) { if(isset($arrays[$key])) { return $arrays[$key]; } return null; } } src/Utils/MockTrait.php000064400000004742147134004340011050 0ustar00