PHP配置访问凭证

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

使用PHP SDK发起OSS请求,您需要配置访问凭证。阿里云服务会通过访问凭证验证您的身份信息和访问权限。您可以根据使用场景对认证和授权的要求,选择不同类型的访问凭证。本文介绍如何配置临时访问凭证和长期访问凭证。

前提条件

在配置访问凭证前,您需要安装OSS PHP SDK。详情请参见安装

初始化凭证提供者

凭证提供者选型

OSS支持多种方式初始化凭证提供者,您可以根据使用场景对认证和授权的要求,选择对应的方式初始化凭证提供者。

凭证提供者初始化方式

适用场景

是否需要提供前置的AK或STS Token

底层实现基于的凭证

凭证有效期

凭证轮转或刷新方式

方式一:使用AK

部署运行在安全、稳定且不易受外部攻击的环境的应用程序,无需频繁轮转凭证就可以长期访问云服务

AK

长期

手动轮转

方式二:使用STS Token

部署运行在不可信的环境的应用程序,希望能控制访问的有效期、权限

STS Token

临时

手动刷新

方式三:使用RAMRoleARN

需要授权访问云服务,例如跨阿里云账号访问云服务的应用程序

STS Token

临时

自动刷新

方式四:使用ECSRAMRole

部署运行在阿里云的ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中的应用程序

STS Token

临时

自动刷新

方式五:使用函数计算上下文中的Credentials

部署运行在阿里云函数计算中的应用程序的函数

STS Token

临时

无需刷新

方式六:使用OIDCRoleARN

部署运行在阿里云的容器服务Kubernetes版的Worker节点中的不可信应用程序

STS Token

临时

自动刷新

方式七:使用CredentialsURI

需要通过外部系统获取访问凭证的应用程序

STS Token

临时

自动刷新

方式八:自定义访问凭证

如果以上凭证配置方式都不满足要求时,您可以自定义获取凭证的方式

自定义

自定义

自定义

自定义

方式一:使用AK

如果您的应用程序部署运行在安全、稳定且不易受外部攻击的环境中,需要长期访问您的OSS,且不能频繁轮转凭证时,您可以使用阿里云主账号或RAM用户的AK(Access Key ID、Access Key Secret)初始化凭证提供者。需要注意的是,该方式需要您手动维护一个AK,存在安全性风险和维护复杂度增加的风险。如何获取AK,请参见CreateAccessKey - 创建主账号或RAM用户访问密钥

环境变量

警告

阿里云账号拥有资源的全部权限,AK一旦泄露,会给系统带来巨大风险,不建议使用。推荐使用最小化授权的RAM用户的AK。

  1. 使用AK设置环境变量。

    Mac OS X/Linux/Unix

    export OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    export OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>

    Windows

    set OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    set OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
  2. 使用环境变量来传递凭证信息。

    <?php
    require_once __DIR__ . '/vendor/autoload.php';
    use OSS\Credentials\EnvironmentVariableCredentialsProvider;
    use OSS\OssClient;
    use OSS\Core\OssException;
    
    try {
        // 从环境变量中获取访问凭证,并保存在provider中。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        $provider = new EnvironmentVariableCredentialsProvider();
        // 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        $endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
        $bucket = "bucket";
        $config = array(
            "provider" => $provider,
            "endpoint" => $endpoint,
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        var_dump($ossClient);
    } catch (OssException $e) {
        printf($e->getMessage() . "\n");
        return;
    }
    

静态凭证

您可以在代码中使用变量来引用凭证,这些变量在运行时会被环境变量、配置文件或其他外部数据源中的实际凭证值填充。

以下操作步骤以配置文件为例。

  1. 创建配置文件config.ini

    [credentials]
    alibaba_cloud_access_key_id = <ALIBABA_CLOUD_ACCESS_KEY_ID>
    alibaba_cloud_access_key_secret = <ALIBABA_CLOUD_ACCESS_KEY_SECRET>
  2. 使用配置文件来传递凭证信息。

    <?php
    if (is_file(__DIR__ . '/../autoload.php')) {
        require_once __DIR__ . '/../autoload.php';
    }
    if (is_file(__DIR__ . '/../vendor/autoload.php')) {
        require_once __DIR__ . '/../vendor/autoload.php';
    }
    use OSS\Credentials\StaticCredentialsProvider;
    use OSS\OssClient;
    use OSS\Core\OssException;
    
    try {
        $config = parse_ini_file('config.ini');
        // 获取AK和SK信息
        $accessKeyId = $config['alibaba_cloud_access_key_id'];
        $accessKeySecret = $config['alibaba_cloud_access_key_secret'];
        $provider = new StaticCredentialsProvider($accessKeyId,$accessKeySecret);
        $endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
        $config = array(
            "provider" => $provider,
            "endpoint" => $endpoint,
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        printf($ossClient);
    } catch (OssException $e) {
        printf($e->getMessage() . "\n");
        return;
    }
    

方式二:使用STS Token

如果您的应用程序需要临时访问OSS,您可以使用通过STS服务获取的临时身份凭证(Access Key ID、Access Key Secret和Security Token)初始化凭证提供者。需要注意的是,该方式需要您手动维护一个STS Token,存在安全性风险和维护复杂度增加的风险。此外,如果您需要多次临时访问OSS,您需要手动刷新STS Token。如何获取STS Token,请参见AssumeRole - 获取扮演角色的临时身份凭证

  1. 使用临时身份凭证设置环境变量。

    Mac OS X/Linux/Unix

    export OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    export OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
    export OSS_SESSION_TOKEN=<ALIBABA_CLOUD_SECURITY_TOKEN>

    Windows

    set OSS_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    set OSS_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
    set OSS_SESSION_TOKEN=<ALIBABA_CLOUD_SECURITY_TOKEN>
  2. 通过环境变量来传递凭证信息。

    <?php
    require_once __DIR__ . '/vendor/autoload.php';
    use OSS\Credentials\EnvironmentVariableCredentialsProvider;
    use OSS\OssClient;
    use OSS\Core\OssException;
    
    try {
        // 从环境变量中获取访问凭证,并保存在provider中。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET,OSS_SESSION_TOKEN。
        $provider = new EnvironmentVariableCredentialsProvider();
        // 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        $endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
        $bucket = "bucket";
        $config = array(
            "provider" => $provider,
            "endpoint" => $endpoint,
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        var_dump($ossClient);
    } catch (OssException $e) {
        printf($e->getMessage() . "\n");
        return;
    }
    

方式三:使用RAMRoleARN

重要

此方法需要使用alibabacloud/credentials 1.2.0及以上版本。

如果您的应用程序需要授权访问OSS,例如跨阿里云账号访问OSS,您可以使用RAMRoleARN初始化凭证提供者。该方式底层实现是STS Token。通过指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具会前往STS服务获取STS Token,并在会话到期前自动刷新STS Token。此外,您还可以通过为policy赋值来限制RAM角色到一个更小的权限集合。需要注意的是,该方式需要您提供一个AK,存在安全性风险和维护复杂度增加的风险。如何获取AK,请参见CreateAccessKey - 为RAM用户创建访问密钥。如何获取RAMRoleARN,请参见CreateRole - 创建角色

  1. 添加凭据客户端依赖。

    composer require alibabacloud/credentials
  2. 配置访问凭证。

    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    use AlibabaCloud\Credentials\Credential;
    use OSS\Core\OssException;
    use OSS\OssClient;
    use OSS\Credentials\CredentialsProvider;
    use OSS\Credentials\StaticCredentialsProvider;
    
    class AlibabaCloudCredentialsWrapper implements CredentialsProvider
    {
        /**
         * @var Credential
         */
        private $wrapper;
    
        public function __construct($wrapper)
        {
            $this->wrapper = $wrapper;
        }
    
        public function getCredentials()
        {
            $cred = $this->wrapper->getCredential();
            $ak = $cred->getAccessKeyId();
            $sk = $cred->getAccessKeySecret();
            $token = $cred->getSecurityToken();
            return new StaticCredentialsProvider($ak, $sk, $token);
        }
    }
    
    try {
        $config = new Credential\Config([
            // 填写Credential类型,固定值为ram_role_arn。
            'type' => 'ram_role_arn',
            // 从环境变量中获取RAM用户的访问密钥(AccessKey ID和AccessKey Secret)。
            'accessKeyId' => getenv('OSS_ACCESS_KEY_ID'),
            'accessKeySecret' => getenv('OSS_ACCESS_KEY_SECRET'),
            // 从环境变量中获取RAM角色的RamRoleArn。即需要扮演的角色ID,格式为acs:ram::$accountID:role/$roleName。
            'roleArn' => getenv('OSS_STS_ROLE_ARN'),
            // 自定义角色会话名称,用于区分不同的令牌。
            'roleSessionName' => 'yourRoleSessionName',
            // 自定义权限策略。
            'policy' => '',
        ]);
    
        $credential = new Credential($config);
        $providerWrapper = new AlibabaCloudCredentialsWrapper($credential);
        $provider = $providerWrapper->getCredentials();
        $config = array(
            'provider' => $provider,
            // 以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其他Region请按实际情况填写。
            'endpoint' => 'https://oss-cn-hangzhou.aliyuncs.com'
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        var_dump($ossClient);
    } catch (OssException $e) {
        print $e->getMessage();
    }

方式四:使用ECSRAMRole

说明

请注意,此方法需要使用alibabacloud/credentials 1.2.0及以上版本。

如果您的应用程序运行在ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中,建议您使用ECSRAMRole初始化凭证提供者。该方式底层实现是STS Token。ECSRAMRole允许您将一个角色关联到ECS实例、ECI实例或容器服务 Kubernetes 版的Worker节点,实现在实例内部自动刷新STS Token。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。如何获取ECSRAMRole,请参见CreateRole - 创建角色

  1. 添加凭据客户端依赖。

    composer require alibabacloud/credentials
  2. 配置ECSRAMRole作为访问凭证。

    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    use AlibabaCloud\Credentials\Credential;
    use OSS\Core\OssException;
    use OSS\OssClient;
    use OSS\Credentials\CredentialsProvider;
    use OSS\Credentials\StaticCredentialsProvider;
    
    class AlibabaCloudCredentialsWrapper implements CredentialsProvider
    {
        /**
         * @var Credential
         */
        private $wrapper;
    
        public function __construct($wrapper)
        {
            $this->wrapper = $wrapper;
        }
    
        public function getCredentials()
        {
            $cred = $this->wrapper->getCredential();
            $ak = $cred->getAccessKeyId();
            $sk = $cred->getAccessKeySecret();
            $token = $cred->getSecurityToken();
            return new StaticCredentialsProvider($ak, $sk, $token);
        }
    }
    
    try {
        $config = new Credential\Config([
            // 填写Credential类型,固定值为ecs_ram_role。
            'type' => 'ecs_ram_role',
            'roleName' => "<role_name>",
        ]);
        $credential = new Credential($config);
        $providerWrapper = new AlibabaCloudCredentialsWrapper($credential);
        $provider = $providerWrapper->getCredentials();
        $config = array(
            'provider' => $provider,
            // 以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其他Region请按实际情况填写。
            'endpoint' => 'https://oss-cn-hangzhou.aliyuncs.com'
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        var_dump($ossClient);
    } catch (OssException $e) {
        print $e->getMessage();
    }

方式五:使用函数计算上下文中的Credentials

如果您的应用程序的函数部署运行在函数计算中,您可以使用函数计算上下文中的Credentials初始化凭证提供者。该方式底层实现是STS Token。函数计算根据函数配置的角色,通过扮演服务角色,而获取一个STS Token,然后通过上下文中的参数Credentials将STS Token传递给您的应用程序。该STS Token的有效期为36小时,且不支持修改。函数的最大执行时间为24小时,因此,执行函数过程中,STS Token不会过期,您无需考虑刷新问题。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。如何授予函数计算访问OSS的权限,请参见授予函数计算访问其他云服务的权限

  • 使用函数计算上下文中的Credentials初始化凭证提供者。

    <?php
    
    use OSS\OssClient;
    use OSS\Core\OssException;
    
    function handler($event, $context) {
        /*
          阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
          建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
          本示例以从上下文中获取AccessKey/AccessSecretKey为例。
        */
        $creds = $context["credentials"];
        $accessKeyId = $creds["accessKeyId"];
        $accessKeySecret = $creds["accessKeySecret"];
        $securityToken = $creds["securityToken"];
        $endpoint = "https://oss-cn-hangzhou-internal.aliyuncs.com";
    
        try{
            $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken);
            print_r($ossClient);
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": FAILED\n");
            printf($e->getMessage() . "\n");
            return $e->getMessage();
        }
        return 'hello world';
    }

方式六:使用OIDCRoleARN

说明

请注意,此方法需要使用alibabacloud/credentials 1.2.0及以上版本。

容器服务Kubernetes版中设置了Worker节点RAM角色后,对应节点内的Pod中的应用也就可以像ECS上部署的应用一样,通过元数据服务(Meta Data Server)获取关联角色的STS Token。但如果容器集群上部署的是不可信的应用(比如部署您的客户提交的应用,代码也没有对您开放),您可能并不希望它们能通过元数据服务获取Worker节点关联实例RAM角色的STS Token。为了避免影响云上资源的安全,同时又能让这些不可信的应用安全地获取所需的STS Token,实现应用级别的权限最小化,您可以使用RRSA(RAM Roles for Service Account)功能。该方式底层实现是STS Token。阿里云容器集群会为不同的应用Pod创建和挂载相应的服务账户OIDC Token文件,并将相关配置信息注入到环境变量中,Credentials工具通过获取环境变量的配置信息,调用STS服务的AssumeRoleWithOIDC接口换取绑定角色的STS Token。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。详情请参见通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离

  1. 添加凭据客户端依赖。

    composer require alibabacloud/credentials
  2. 配置OIDC的RAM角色作为访问凭证的示例如下。

    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    use OSS\Credentials\CredentialsProvider;
    use AlibabaCloud\Credentials\Credential;
    use OSS\Credentials\StaticCredentialsProvider;
    use OSS\Core\OssException;
    use OSS\OssClient;
    
    class AlibabaCloudCredentialsWrapper implements CredentialsProvider
    {
        /**
         * @var Credential
         */
        private $wrapper;
    
        public function __construct($wrapper)
        {
            $this->wrapper = $wrapper;
        }
    
        public function getCredentials()
        {
            $cred = $this->wrapper->getCredential();
            $ak = $cred->getAccessKeyId();
            $sk = $cred->getAccessKeySecret();
            $token = $cred->getSecurityToken();
            return new StaticCredentialsProvider($ak, $sk, $token);
        }
    }
    
    try {
        // 使用OIDCRoleArn初始化Credentials Client。
        $config = new Credential\Config([
            // 凭证类型。
            'type' => 'oidc_role_arn',
            // OIDC提供商ARN,可以通过环境变量ALIBABA_CLOUD_OIDC_PROVIDER_ARN设置oidc_provider_arn
            'oidcProviderArn' => '<OidcProviderArn>',
            // OIDC Token文件路径,可以通过环境变量ALIBABA_CLOUD_OIDC_TOKEN_FILE设置oidc_token_file_path
            'oidcTokenFilePath' => '<OidcTokenFilePath>',
            // RAM角色名称ARN,示例值:acs:ram::123456789012****:role/adminrole,可以通过环境变量ALIBABA_CLOUD_ROLE_ARN设置role_arn
            'roleArn' => '<RoleArn>',
            // 角色会话名称,可以通过环境变量ALIBABA_CLOUD_ROLE_SESSION_NAME设置role_session_name
            'roleSessionName' => '<RoleSessionName>',
            // 设置更小的权限策略,非必填。示例值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
            'policy' => '<Policy>',
            # 设置session过期时间
            'durationSeconds' => 3600,
        ]);
        $credential = new Credential($config);
        $providerWrapper = new AlibabaCloudCredentialsWrapper($credential);
        $provider = $providerWrapper->getCredentials();
        $config = array(
            'provider' => $provider,
            // 以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其他Region请按实际情况填写。
            'endpoint' => 'https://oss-cn-hangzhou.aliyuncs.com'
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        var_dump($ossClient);
    } catch (OssException $e) {
        print $e->getMessage();
    }

方式七:使用CredentialsURI

说明

请注意,此方法需要使用alibabacloud/credentials 1.2.0及以上版本。

如果您的应用程序需要通过外部系统获取阿里云凭证,从而实现灵活的凭证管理和无密钥访问,您可以使用CredentialsURI初始化凭证提供者。该方式底层实现是STS Token。Credentials工具通过您提供的URI获取STS Token,完成凭证客户端初始化。该方式无需您提供一个AK或STS Token,消除了手动维护AK或STS Token的风险。需要注意的是,提供CredentialsURI响应的后端服务需要实现STS Token的自动刷新逻辑,确保您的应用程序始终能获取到有效凭证。

  1. 添加凭据客户端依赖。

    composer require alibabacloud/credentials
  2. 配置CredentialsURI作为访问凭证的示例如下。

    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    use AlibabaCloud\Credentials\Credential;
    use OSS\Core\OssException;
    use OSS\Credentials\CredentialsProvider;
    use OSS\Credentials\StaticCredentialsProvider;
    use OSS\OssClient;
    
    class AlibabaCloudCredentialsWrapper implements CredentialsProvider
    {
        /**
         * @var Credential
         */
        private $wrapper;
    
        public function __construct($wrapper)
        {
            $this->wrapper = $wrapper;
        }
    
        public function getCredentials()
        {
            $cred = $this->wrapper->getCredential();
            $ak = $cred->getAccessKeyId();
            $sk = $cred->getAccessKeySecret();
            $token = $cred->getSecurityToken();
            return new StaticCredentialsProvider($ak, $sk, $token);
        }
    }
    
    try {
        $config = new Credential\Config([
            // 凭证类型。
            'type' => 'credentials_uri',
            // 凭证的 URI,格式为http://local_or_remote_uri/,可以通过环境变量ALIBABA_CLOUD_CREDENTIALS_URI设置credentials_uri
            'credentialsURI' => '<CredentialsUri>',
        ]);
        $credential = new Credential($config);
        $providerWrapper = new AlibabaCloudCredentialsWrapper($credential);
        $provider = $providerWrapper->getCredentials();
        $config = array(
            'provider' => $provider,
            // 以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其他Region请按实际情况填写。
            'endpoint' => 'https://oss-cn-hangzhou.aliyuncs.com'
            "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
            "region"=> "cn-hangzhou"
        );
        $ossClient = new OssClient($config);
        var_dump($ossClient);
    } catch (OssException $e) {
        print $e->getMessage();
    }

方式八:自定义访问凭证

如果以上凭证配置方式都不满足要求时,您还可以通过实现Credential Providers接口的方式,来自定义凭证提供方式。

<?php
  if (is_file(__DIR__ . '/../autoload.php')) {
  require_once __DIR__ . '/../autoload.php';
  }
  if (is_file(__DIR__ . '/../vendor/autoload.php')) {
  require_once __DIR__ . '/../vendor/autoload.php';
  }

use OSS\Credentials\CredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;

class CustomerCredentialsProvider implements CredentialsProvider
{
  public function getCredentials()
  {
    // 返回长期凭证
    return [
      'AccessKeyId' => 'id',
      'AccessKeySecret' => 'secret',
      ];
    // 返回临时凭证
    //return [
    //    'AccessKeyId' => 'id',
    //    'AccessKeySecret' => 'secret',
    //    'SecurityToken' => 'token',
    //];
  }
}

$provider = new CustomerCredentialsProvider();

try {
  $provider = new CustomerCredentialsProvider();
  $endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  $config = array(
    "provider" => $provider,
    "endpoint" => $endpoint,
    "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
    "region"=> "cn-hangzhou"
  );
  $ossClient = new OssClient($config);
  printf($ossClient);
} catch (OssException $e) {
  printf($e->getMessage() . "\n");
  return;
}

后续步骤

初始化凭证提供者后,您需要使用凭证提供者来创建OSSClient实例。详情请参见初始化