签名认证

适用场景

开发者应用访问浪潮云的OpenAPI时,需要使用由浪潮云颁发的ACCESS KEY SECRET对请求进行签名。并携带签名信息发起请求。这个调用不应该在浏览器端,因为ACCESS KEY SECRET不可能保存在浏览器端。

开发者需要将请求中的所有内容,包括请求uri、请求Body体、请求方式、请求头(header)及请求参数等信息,按照一定的顺序组装。使用指定的加密算法计算得出签名值signatrue。并携带此签名作为身份凭证访问浪潮云资源。

使用方式

步骤一

构建标准请求url签名字符串:

  1. 参数排序。以参数字母顺序排序,排序参数包括Query查询参数和Form表单参数。
  2. 获取请求uri,即url绝对路径部分。
  3. 将排序后的参数列表按照uri?key1=value1&key2=value2的方式拼接,得到url签名参数(uriToSign) 例如: 原始请求url为:
https://iam.inspurcloudapi.com/auth/v1/policies/testPolicyId?name=policy1&description=策略1

则按照步骤一得到的结果为:

/auth/v1/policies/testPolicyId?description=策略1&name=policy1

步骤二

构建header签名字符串: 生成13位毫秒级时间戳x-time,生成一组随机字符串x-random

将x-time、x-random、ACCESS KEY SECRET(即SK。由浪潮云颁发)按照x-time+x-random+SK 的顺序直接拼接得到header签名参数(headerToSign)

步骤三

对请求body体字符串进行MD5加密运算,并转换为16进制,得出bodyToSign

例如,有请求body如下:

[{"action":"CreateEip", "context":{}, "region":"cn-north-3", "resourceType":"instance", "resourceAccountId":"", "instanceId": null, "resourceCreator":"", "service":"eip" }]

对其进行MD5加密,并转换为16进制后,得到

09ad60b0ed0e428af0fd3dd937ef5f49

示例代码如下:

String bodyToSign = DigestUtils.md5Hex(body)

步骤四

将httpMethod(本次请求方式,如GET、POST等)、headerToSign、uriToSign、bodyToSign,以换行符“\n”为分隔拼接。得到最终签名的字符串(fullToSign)。 例如: 原始请求为:

GET https://iam.inspurcloudapi.com/auth/v1/policies/testPolicyId?name=policy1&description=策略1
x-time: 1566789683802
x-random: f81c2640d4ed48cc8049e48f5833e163
x-secret-id: YTQxMGI1NWYtMTViOC00ODk2LThhZjUtZWJjZjA4OGUyMTMx
x-sign-algorithm: MD5
ACCESS KEY SECRET为YzkxZjc4YWEtZDUzYi00MzQ1LWI0YTItZGY2OTkyNTcxNmM2

则最终得到的签名字符串(fullToSign)为:

GET
1566789683802f81c2640d4ed48cc8049e48f5833e163YzkxZjc4YWEtZDUzYi00MzQ1LWI0YTItZGY2OTkyNTcxNmM2
/auth/v1/policies/testPolicyId?description=策略1&name=policy1

步骤五

选择加密算法algorithm(支持sha1、md5、sha256)对fullToSign进行加密运算,并转换为16进制,再对结果进行base64编码后,得到最终的签名值signatrue。参考java示例代码如下:

signToBase64 = DigestUtils.md5Hex(fullToSign.getBytes())
signature = new String(Base64.encodeBase64(signToBase64.getBytes()), "UTF-8");

将signatrue以x-sign为键带入请求header中,发起请求,请求头中必须包含如下信息:

含义
x-sign-algorithm 哈希算法,支持sha1、md5、sha256(步骤五选择的算法algorithm)
x-secret-id Access Key Id(即AK)
x-time 13位毫秒级时间戳(步骤二生成)
x-random 随机字符串(步骤二生成)
x-sign 签名运算后得到的签名值signatrue

备注

使用浪潮云签名SDK,可简化签名操作

调用SDK中SecretUtil.signRequest签名方法,可直接获取签名值,具体方法入参含义如下:

/**
     * 计算HTTP请求签名
     *
     * @param secretKey        密钥值SK(由浪潮云颁发)
     * @param uri              原始HTTP请求PATH(不包含Query参数)
     * @param httpMethod       原始HTTP请求方法
     * @param headers          要签名的请求头集合(签名时必须包含x-time、x-random、x-sign-algorithm)
     * @param queryParams      原始HTTP请求Query参数(包含Form表单参数)
     * @param body             原始HTTP请求Body体(非表单请求参数)--进行MD5加密后的
     * @return 签名结果
     */
    public static String signRequest(String secretKey, String uri, String httpMethod, Map<String, String> headers,
            Map<String, Object> queryParams, String body)

POST请求示例

现有post请求如下:

curl -X POST \
  https://iam.inspurcloudapi.com/auth/v1/has-permissions \
  -d '[{"action":"CreateEip", "context":{}, "region":"cn-north-3", "resourceType":"instance", "resourceAccountId":"", "instanceId": null, "resourceCreator":"", "service":"eip" }]'

按照步骤一操作得到uriToSign:

/auth/v1/has-permissions

按照步骤二操作得到headerToSign:

声明随机数x-random:da3df059255345b5b07e23601109f5e7
当前时间戳x-time:1573722631879
浪潮云颁发的SK:NmNmNzhmNGItNzczMi00ODJhLTkwNmEtYWExMWQ4NmI0NjA0
拼接得到
1573722631879da3df059255345b5b07e23601109f5e7NmNmNzhmNGItNzczMi00ODJhLTkwNmEtYWExMWQ4NmI0NjA0

按照步骤三操作得到bodyToSign:

09ad60b0ed0e428af0fd3dd937ef5f49

按照步骤四操作得到fullToSign:

POST
1573722631879da3df059255345b5b07e23601109f5e7NmNmNzhmNGItNzczMi00ODJhLTkwNmEtYWExMWQ4NmI0NjA0
/auth/v1/has-permissions
09ad60b0ed0e428af0fd3dd937ef5f49

按照步骤五操作得到signatrue:

YzdhMWI4NjBmNzRlNjI1NjAzOGE3Yzg4NTM0MzYxMTM=

最后,将x-random、x-time、x-sign(即signatrue)、x-secret-id(即AccessKeyId,由浪潮云颁发),x-sign-algorithm(签名加密算法,本例选择MD5)放入header中发起请求。最终请求信息如下:

curl -X POST \
  https://iam.inspurcloudapi.com/auth/v1/has-permissions \
  -H 'x-random: da3df059255345b5b07e23601109f5e7' \
  -H 'x-secret-id: N2QxZWYxMzMtMjY1MS00NGE4LWFhMTMtNjVjOGMyODgyNDk0' \
  -H 'x-time: 1573722631879' \
  -H 'x-sign-algorithm: MD5' \
  -H 'x-sign: YzdhMWI4NjBmNzRlNjI1NjAzOGE3Yzg4NTM0MzYxMTM=' \
  -d '[{"action":"CreateEip", "context":{}, "region":"cn-north-3", "resourceType":"instance", "resourceAccountId":"", "instanceId": null, "resourceCreator":"", "service":"eip" }]'

获取token接口

URI

POST /auth/v1/token

请求参数

content-type:application/json;

名称 位置 类型 是否必须 描述
username body String 用户名(若为子用户,则用户名为“主用户名.子用户名”)
password body String 密码

返回参数

名称 位置 类型 是否必须 描述
access_token Body String Token
expires_in Body String 失效时间(毫秒)
refresh_token Body String 刷新token
refresh_expires_in Body String 刷新token失效时间

示例

请求示例

content-type:application/json; 请求url为:POST https://iam.inspurcloudapi.com/auth/v1/token

{
    "username":"cloud-operator.testuser1",
    "password":"123456a?"
}

响应示例

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lk...ygzrBPvyK5A",
    "expires_in": 5400,
    "refresh_expires_in": 7200,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwi...nh54bxMbC6Dsg",
    "token_type": "bearer",
    "not-before-policy": 0,
    "session_state": "f2e3f54e-5251-4cab-a12b-d918d3687e7f",
    "scope": ""
}

返回值

请参考通用请求返回值

错误码

请参考错误码