add ecs ram authorization support

This commit is contained in:
York.GU 2020-02-21 21:30:32 +08:00
parent 397afbfa4f
commit 31e32529e0
2 changed files with 39 additions and 2 deletions

View File

@ -19,4 +19,5 @@ return [
'group' => env('ALIYUN_ACM_GROUP', 'DEFAULT_GROUP'),
'access_key' => env('ALIYUN_ACM_AK', ''),
'secret_key' => env('ALIYUN_ACM_SK', ''),
'ecs_ram_role' => env('ALIYUN_ACM_RAM_ROLE', ''),
];

View File

@ -47,10 +47,12 @@ class Client implements ClientInterface
*/
private $servers;
private $cachedSecurityCredentials = [];
public function __construct(ContainerInterface $container)
{
/**
* @var GuzzleClientFactory $clientFactory
* @var GuzzleClientFactory
*/
$clientFactory = $container->get(GuzzleClientFactory::class);
$this->client = $clientFactory->create();
@ -72,6 +74,16 @@ class Client implements ClientInterface
$group = $this->config->get('aliyun_acm.group', 'DEFAULT_GROUP');
$accessKey = $this->config->get('aliyun_acm.access_key', '');
$secretKey = $this->config->get('aliyun_acm.secret_key', '');
$ecsRamRole = $this->config->get('aliyun_acm.ecs_ram_role', '');
$securityToken = null;
if (empty($accessKey) && ! empty($ecsRamRole)) {
$securityCredentials = $this->getSecurityCredentialsWithEcsRamRole($ecsRamRole);
if (! empty($securityCredentials)) {
$accessKey = $securityCredentials['AccessKeyId'];
$secretKey = $securityCredentials['AccessKeySecret'];
$securityToken = $securityCredentials['SecurityToken'];
}
}
// Sign
$timestamp = round(microtime(true) * 1000);
@ -94,7 +106,8 @@ class Client implements ClientInterface
'Spas-AccessKey' => $accessKey,
'timeStamp' => $timestamp,
'Spas-Signature' => $sign,
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8'
'Spas-SecurityToken' => $securityToken ?? '',
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
],
'query' => [
'tenant' => $namespace,
@ -115,4 +128,27 @@ class Client implements ClientInterface
return [];
}
}
/**
* get ECS RAM authorization.
* @see https://help.aliyun.com/document_detail/72013.html
*/
private function getSecurityCredentialsWithEcsRamRole(string $ecsRamRole): ?array
{
$securityCredentials = $this->cachedSecurityCredentials[$ecsRamRole] ?? null;
if (! empty($securityCredentials) && time() > strtotime($securityCredentials['Expiration']) - 60) {
$securityCredentials = null;
}
if (empty($securityCredentials)) {
$response = $this->client->get('http://100.100.100.200/latest/meta-data/ram/security-credentials/' . $ecsRamRole);
if ($response->getStatusCode() !== 200) {
throw new RuntimeException('Get config failed from Aliyun ACM.');
}
$securityCredentials = Json::decode($response->getBody()->getContents());
if (! empty($securityCredentials)) {
$this->cachedSecurityCredentials[$ecsRamRole] = $securityCredentials;
}
}
return $securityCredentials;
}
}