使用阿里云sts鉴权模式实践(PHP)(转载)

技术分享 · Fecmall · 于 1年前 发布 · 886 次阅读

转载地址:https://bex.meishakeji.com/2019/04/13/aliyun-sts/

class STS
{
    protected $url = 'https://sts.aliyuncs.com';
    protected $accessKeySecret = '1234567890qwertyuioasdfghj';
    protected $accessKeyId = 'LT11234567898';
    protected $roleArn = 'acs:ram::$accountID:role/$roleName';//指定角色的 ARN ,角色策略权限
    protected $roleSessionName = 'client1';//用户自定义参数。此参数用来区分不同的 token,可用于用户级别的访问审计。格式:^[a-zA-Z0-9\.@\-_]+$
    protected $durationSeconds = '1800';//指定的过期时间
    protected $type = 'xxx';//方便调用时获取不同的权限

    public function __construct($type)
    {
        $this->type = $type;
        $this->setRoleArn();
    }

    public function sts()
    {
        $action = 'AssumeRole';//通过扮演角色接口获取令牌
        date_default_timezone_set('UTC');
        $param = array(
            'Format'           => 'JSON',
            'Version'          => '2015-04-01',
            'AccessKeyId'      => $this->accessKeyId,
            'SignatureMethod'  => 'HMAC-SHA1',
            'SignatureVersion' => '1.0',
            'SignatureNonce'   => $this->getRandChar(8),
            'Action'           => $action,
            'RoleArn'          => $this->roleArn,
            'RoleSessionName'  => $this->roleSessionName,
            'DurationSeconds'  => $this->durationSeconds,
            'Timestamp'        => date('Y-m-d') . 'T' . date('H:i:s') . 'Z'
            //'Policy'=>'' //此参数可以限制生成的 STS token 的权限,若不指定则返回的 token 拥有指定角色的所有权限。
        );
        $param['Signature'] = $this->computeSignature($param, 'POST');
        $res = CurlHandle::httpPost($this->url, $param);//curl post请求
        if ($res) {
            return self::_render($res);
        } else {
            return [];
        }
    }

    private static function _render($res)
    {
        $res = json_decode($res, true);
        if (empty($res['Credentials'])) {
            return [];
        } else {
            return [
                'accessKeySecret' => $res['Credentials']['AccessKeySecret'] ?? '',
                'accessKeyId'     => $res['Credentials']['AccessKeyId'] ?? '',
                'expiration'      => $res['Credentials']['Expiration'] ?? '',
                'securityToken'   => $res['Credentials']['SecurityToken'] ?? '',
            ];
        }
    }

    protected function computeSignature($parameters, $setMethod)
    {
        ksort($parameters);
        $canonicalizedQueryString = '';
        foreach ($parameters as $key => $value) {
            $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
        }
        $stringToSign = $setMethod . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
        $signature = $this->getSignature($stringToSign, $this->accessKeySecret . '&');

        return $signature;
    }

    public function getSignature($source, $accessSecret)
    {
        return base64_encode(hash_hmac('sha1', $source, $accessSecret, true));
    }

    protected function percentEncode($str)
    {
        $res = urlencode($str);
        $res = preg_replace('/\+/', '%20', $res);
        $res = preg_replace('/\*/', '%2A', $res);
        $res = preg_replace('/%7E/', '~', $res);
        return $res;
    }

    public function getRandChar($length)
    {
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol) - 1;

        for ($i = 0; $i < $length; $i++) {
            $str .= $strPol[rand(0, $max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }

        return $str;
    }

    protected function setRoleArn()
    {
        if ($this->type == '123') {//根据入参使用不同的策略,当然这里还可以有其他写法兼容更多的策略的情况
            $this->roleArn = 'acs:ram::123456789098:role/=$roleName';
        }
    }
}

返回结果

{
    "Credentials": {
        "AccessKeyId": "STS.xxxxxxxxxxxxx****",//访问密钥标识
        "AccessKeySecret": "xxxxxxxxxx****",//访问密钥
        "Expiration": "2019-04-09T11:52:19Z",//失效时间
        "SecurityToken": "********"//安全令牌
    },
    "AssumedRoleUser": {
        "arn": "acs:sts::123456765456****:assumed-role/AdminRole/client",
        "AssumedRoleUserId":"1234567121****:alice"
        },
    "RequestId": "xxxxxxxxxxxxxxxx"
}

添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
Your Site Analytics