1. 概述
1.1 应用场景
用户需要对阿里云产品进行数据监控,实时掌握服务器性能情况。由于阿里云服务器签名认证很复杂,官方文档仅提供代码形式来获取签名。比如python或者java,且由于代码是开源的,扫描会有安全漏洞的风险。
因此用户希望能提供更简便安全的方式对产品进行数据监控。
1.2 实现思路
通过接口的形式(例如 查询指定监控项的最新监控数据 )实现阿里云签名认证来获取服务器CPU数据,更安全、步骤也较简单,可满足客户安全、业务需求。
注:用户可根据具体需求更换其他接口,认证方式是一样的。
1)准备 V3版本请求体&签名机制 中的部分公共请求头和 查询指定监控项的最新监控数据 接口请求参数
2)准备 V3版本请求体&签名机制 请求头的签名认证
3)使用接口 查询指定监控项的最新监控数据 获取返回的服务器数据,并落入指定数据库。
Demo 示例详情参见:https://demo.finedatalink.com/ 「使用FDL接口形式实现阿里云服务器数据监听」任务
2. 操作步骤
2.1 准备请求头和请求参数
新建定时任务,设置公共请求头和请求头参数,如下图所示:
其中MetricName和Namespace为 查询指定监控项的最新监控数据 的请求参数,Credential 为 Authorization 公共请求头签名认证的组成参数。
由于 V3版本请求体&签名机制 中的公共请求头中 x-acs-content-sha256 参数为请求正文 Hash 摘要后再 base-16 编码的结果,因此需要使用 SparkSQL 进行提前设置。
新增数据转换节点,由于 查询指定监控项的最新监控数据 中 body 为空,则字符串为空,因此输入公式:select SHA2('',256) as body
点击预览即可看到输出结果:
将结果设置为参数 x-acs-content-sha256,以备后续作为请求头使用,如下图所示:
2.2 准备签名认证和Authorization
新增数据转换节点,进入编辑界面后,使用 DB 表输入,将 2.1 节设置的参数使用以下 SQL 语句构建规范化请求头,并准备生成签名值 Signature 所需要的CanonicalQueryString 等参数。
注:示例为 MySQL 语法,语句通用的,只需要根据接口的需求增加、删除请求头参数。
with A1 AS
(
select '${Credential}' as "value",'Credential' as "para"
union all
select '${host}' as "value", 'host' as "para"
union all
select '${user-agent}' as "value", 'user-agent' as "para"
union all
select '${x-acs-action}' as "value", 'x-acs-action' as "para"
union all
select '${x-acs-content-sha256}' as "value", 'x-acs-content-sha256' as "para"
union all
select DATE_FORMAT(DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 8 HOUR), '%Y-%m-%dT%H:%i:%sZ') as "value", 'x-acs-date' as "para"
union all
select uuid() as "value", 'x-acs-signature-nonce' as "para"
union all
select '${x-acs-version}' as "value", 'x-acs-version' as "para"
union all
select '${MetricName}' as "value", 'MetricName' as "para"
union all
select '${Namespace}' as "value", 'Namespace' as "para"
union all
select '${AccessKeySecret}' as "value",'AccessKeySecret' as "para"
)
,B1 AS
(
SELECT CONCAT(para,'=',value) as stringToSign FROM A1
where para in ('MetricName','Namespace')
ORDER BY para
)
,C1 AS
(
SELECT GROUP_CONCAT(B1.stringToSign SEPARATOR '&') AS CanonicalQueryString
FROM B1
)
,D1 AS
(
select CONCAT(para,':',value) as stringToHeader from A1
where para in ('host','x-acs-action','x-acs-content-sha256','x-acs-date','x-acs-signature-nonce','x-acs-version','','')
order by para
)
,E1 AS
(
SELECT GROUP_CONCAT(D1.stringToHeader SEPARATOR '\n') AS CanonicalHeaders
FROM D1
)
,F1 AS
(
select GROUP_CONCAT(para SEPARATOR ';') as header from A1
where para in ('host','x-acs-action','x-acs-content-sha256','x-acs-date','x-acs-signature-nonce','x-acs-version')
order by para
)
SELECT * FROM
(
SELECT * FROM A1
UNION all
select (SELECT C1.CanonicalQueryString FROM C1) as 'value','CanonicalQueryString' as "para"
UNION all
select (SELECT E1.CanonicalHeaders FROM E1) as 'value','CanonicalHeaders' as "para"
UNION all
select (SELECT F1.header FROM F1) as 'value','header' as "para"
) T1
ORDER BY T1.para
点击预览即可看到准备好的数据,如下图所示:
使用 SparkSQL HMACSHA256函数,利用 2.1、2.2 节生成的请求、请求头参数,计算签名值,并构造加密后的 Authorization 请求头和标准化请求的明文 Authorization,其中标准化请求明文便于后面问题排查,如下图所示:
select * from $[DB表输入]
union all
select concat("ACS3-HMAC-SHA256 Credential=",'${Credential}',",SignedHeaders=host;x-acs-action;x-acs-content-sha256;x-acs-date;x-acs-signature-nonce;x-acs-version,Signature=",LOWER(HMACSHA256(concat("ACS3-HMAC-SHA256","\n",SHA2(CONCAT("POST","\n","/","\n",t.CanonicalQueryString,"\n",t.CanonicalHeaders,"\n\n",t.header,"\n",SHA2("",256)),256)),t.AccessKeySecret,'HEX'))) as value, "Authorization" as para from
(
select (select value from $[DB表输入] where para='host') as host,
(select value from $[DB表输入] where para='CanonicalQueryString') as CanonicalQueryString,
(select value from $[DB表输入] where para='CanonicalHeaders') as CanonicalHeaders,
(select value from $[DB表输入] where para='header') as header,
(select value from $[DB表输入] where para='AccessKeySecret') as AccessKeySecret
) t
union all
select CONCAT("POST","\n","/","\n",t1.CanonicalQueryString,"\n",t1.CanonicalHeaders,"\n\n",t1.header,"\n",SHA2("",256)) as value, "Authorizationstring" as para from
(
select (select value from $[DB表输入] where para='host') as host,
(select value from $[DB表输入] where para='CanonicalQueryString') as CanonicalQueryString,
(select value from $[DB表输入] where para='CanonicalHeaders') as CanonicalHeaders,
(select value from $[DB表输入] where para='header') as header,
(select value from $[DB表输入] where para='AccessKeySecret') as AccessKeySecret
) t1
预览即可看到 Authorization 等,如下图所示:
将 Authorization、x-acs-content-sha256、x-acs-date、x-acs-signature-nonce 作为参数输出,便于后续作为接口请求头参数使用,如下图所示:
2.3 API 获取服务器监控数据
新增数据转换,使用 API 输入算子,并输入接口 URL 和接口 Query 参数(此参数在 2.1 节已经在参数列表中设置),接口请参考:查询指定监控项的最新监控数据,如下图所示:
在请求头中输入准备好的参数,公共请求头参数详情参见: V3版本请求体&签名机制
参数列表如下图所示:
接口返回值如下图所示:
然后即可对返回值使用 JSON 解析解析为二维表。
最后将数据输出至指定数据库即可,如下图所示:
得到数据库中数据如下图所示: