腾讯云云函数使用教程 - 函数 URL 认证鉴权配置
文档简介:
简介:
您可以通过配置认证鉴权策略来控制对函数 URL 的访问。
在配置函数 URL 时,必须指定以下认证选项之一:
CAM 鉴权:需要对函数 CAM 鉴权验证,用户可以基于函数 InvokeFunctionUrl 接口进行资源管理和使用权限配置。您可以通过配置 InvokeFunctionUrl 策略权限来开放或限制接口的访问。
开放:不需要对函数请求进行身份验证,支持匿名访问,任何人都可以发起 HTTP 请求调用您的函数。
简介
您可以通过配置认证鉴权策略来控制对函数 URL 的访问。
在配置函数 URL 时,必须指定以下认证选项之一:
CAM 鉴权:需要对函数 CAM 鉴权验证,用户可以基于函数 InvokeFunctionUrl 接口进行资源管理和使用权限配置。您可以通过配置 InvokeFunctionUrl 策略权限来开放或限制接口的访问。
开放:不需要对函数请求进行身份验证,支持匿名访问,任何人都可以发起 HTTP 请求调用您的函数。
配置 InvokeFunctionUrl 策略权限
您可以参考以下步骤配置 InvokeFunctionUrl 策略权限来开放或限制接口的访问。
1. 在访问管理控制台的 策略 页面,单击左上角的新建自定义策略。
2. 在弹出的选择创建方式窗口中,单击按策略生成器创建,进入编辑策略页面。
3. 在可视化策略生成器中添加服务与操作栏,补充以下信息,编辑一个授权声明。
效果(必选):选择允许。
服务(必选):选择云函数 (scf)。
操作(必选):单击全部操作 (scf:*)右侧的展开,搜索 InvokeFunctionUrl,并勾选。如下图所示:

资源(必填):选择全部资源或您要授权的特定资源。
条件(选填):设置上述授权的生效条件。
4. 完成策略授权声明编辑后,单击下一步,进入基本信息和关联用户/用户组/角色页面。
5. 在关联用户/用户组/角色页面,补充策略名称和描述信息,可同时关联用户/用户组/角色快速授权。
6. 单击完成,完成按策略生成器创建自定义策略的操作。
签名生成和认证流程
客户端生成签名
签名算法请参见 安全凭证服务签名方法。代码示例如下:
import java.nio.charset.Charset;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.text.SimpleDateFormat;import java.util.Date;import java.util.TimeZone;import java.util.TreeMap;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import javax.xml.bind.DatatypeConverter;public class TencentCloudAPITC3Demo {private final static Charset UTF8 = StandardCharsets.UTF_8;// 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******private final static String SECRET_ID = System.getenv("TENCENTCLOUD_SECRET_ID");// 需要设置环境变量 TENCENTCLOUD_SECRET_KEY,值为示例的 Gu5t9xGARNpq86cd98joQYCN3*******private final static String SECRET_KEY = System.getenv("TENCENTCLOUD_SECRET_KEY");private final static String CT_JSON = "application/json";public static byte[] hmac256(byte[] key, String msg) throws Exception {Mac mac = Mac.getInstance("HmacSHA256");SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());mac.init(secretKeySpec);return mac.doFinal(msg.getBytes(UTF8));}public static String sha256Hex(String s) throws Exception {MessageDigest md = MessageDigest.getInstance("SHA-256");byte[] d = md.digest(s.getBytes(UTF8));return DatatypeConverter.printHexBinary(d).toLowerCase();}public static void main(String[] args) throws Exception {String service = "scf";String host = "1253970226-xxxxxxx-cq.scf.tencentcs.com";String algorithm = "TC3-HMAC-SHA256";String timestamp = String.valueOf(System.currentTimeMillis() / 1000);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 注意时区,否则容易出错sdf.setTimeZone(TimeZone.getTimeZone("UTC"));String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));// ************* 步骤 1:拼接规范请求串 *************String httpRequestMethod = "POST";String canonicalUri = "/";String canonicalQueryString = "";String canonicalHeaders = "content-type:application/json\n"+ "host:" + host + "\n" ;String signedHeaders = "content-type;host";// 请求体String payload = "{\"Limit\": 1, \"Filters\": [{\"Values\": [\"\\u672a\\u547d\\u540d\"], \"Name\": \"instance-name\"}]}";String hashedRequestPayload = sha256Hex(payload);String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;System.out.println(canonicalRequest);// ************* 步骤 2:拼接待签名字符串 *************String credentialScope = date + "/" + service + "/" + "tc3_request";String hashedCanonicalRequest = sha256Hex(canonicalRequest);String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;System.out.println(stringToSign);// ************* 步骤 3:计算签名 *************byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);byte[] secretService = hmac256(secretDate, service);byte[] secretSigning = hmac256(secretService, "tc3_request");String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();System.out.println(signature);// ************* 步骤 4:拼接 Authorization *************String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;System.out.println(authorization);StringBuilder sb = new StringBuilder();sb.append("curl -X POST https://").append(host).append(" -H \"Authorization: ").append(authorization).append("\"").append(" -H \"Content-Type: application/json; charset=utf-8\"").append(" -H \"Host: ").append(host).append("\"").append(" -H \"X-Scf-Cam-Uin: ").append(uin).append("\"").append(" -H \"X-Scf-Cam-Timestamp: ").append(timestamp).append("\"").append(" -d '").append(payload).append("'");System.out.println(sb.toString());}}
package mainimport ("crypto/hmac""crypto/sha256""encoding/hex""fmt""os""strings""time")func sha256hex(s string) string {b := sha256.Sum256([]byte(s))return hex.EncodeToString(b[:])}func hmacsha256(s, key string) string {hashed := hmac.New(sha256.New, []byte(key))hashed.Write([]byte(s))return string(hashed.Sum(nil))}func main() {// 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******secretId := os.Getenv("TENCENTCLOUD_SECRET_ID")// 需要设置环境变量 TENCENTCLOUD_SECRET_KEY,值为示例的 Gu5t9xGARNpq86cd98joQYCN3*******secretKey := os.Getenv("TENCENTCLOUD_SECRET_KEY")host := "1253970226-xxxxxxx-cq.scf.tencentcs.com"algorithm := "TC3-HMAC-SHA256"service := "scf"var timestamp int64 = time.Now().Unix()// step 1: build canonical request stringhttpRequestMethod := "POST"canonicalURI := "/"canonicalQueryString := ""canonicalHeaders := fmt.Sprintf("content-type:%s\nhost:%s\n","application/json", host)signedHeaders := "content-type;host"payload := `{"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]}`hashedRequestPayload := sha256hex(payload)canonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s",httpRequestMethod,canonicalURI,canonicalQueryString,canonicalHeaders,signedHeaders,hashedRequestPayload)fmt.Println("canonicalRequest => ", canonicalRequest)// step 2: build string to signdate := time.Unix(timestamp, 0).UTC().Format("2006-01-02")credentialScope := fmt.Sprintf("%s/%s/tc3_request", date, service)hashedCanonicalRequest := sha256hex(canonicalRequest)string2sign := fmt.Sprintf("%s\n%d\n%s\n%s",algorithm,timestamp,credentialScope,hashedCanonicalRequest)fmt.Println("string2sign ==>", string2sign)// step 3: sign stringsecretDate := hmacsha256(date, "TC3"+secretKey)secretService := hmacsha256(service, secretDate)secretSigning := hmacsha256("tc3_request", secretService)signature := hex.EncodeToString([]byte(hmacsha256(string2sign, secretSigning)))fmt.Println(signature)// step 4: build authorizationauthorization := fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s",algorithm,secretId,credentialScope,signedHeaders,signature)fmt.Println(authorization)curl := fmt.Sprintf(`curl -X POST https://%s -H "Authorization: %s" -H "Content-Type:
application/json; charset=utf-8" -H "Host: %s" -H "X-Scf-Cam-Uin: %d" -H "X-Scf-Cam-Timestamp: %d" -d '%s'`,
host, authorization, host, uin, timestamp, payload)fmt.Println(curl)}
const crypto = require('crypto');function sha256(message, secret = '', encoding) {const hmac = crypto.createHmac('sha256', secret)return hmac.update(message).digest(encoding)}function getHash(message, encoding = 'hex') {const hash = crypto.createHash('sha256')return hash.update(message).digest(encoding)}function getDate(timestamp) {const date = new Date(timestamp * 1000)const year = date.getUTCFullYear()const month = ('0' + (date.getUTCMonth() + 1)).slice(-2)const day = ('0' + date.getUTCDate()).slice(-2)return `${year}-${month}-${day}`}function main(){// 密钥参数// 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******const SECRET_ID = process.env.TENCENTCLOUD_SECRET_ID// 需要设置环境变量 TENCENTCLOUD_SECRET_KEY,值为示例的 Gu5t9xGARNpq86cd98joQYCN3*******const SECRET_KEY = process.env.TENCENTCLOUD_SECRET_KEYconst endpoint = "1253970226-xxxxxxx-cq.scf.tencentcs.com"const service = "scf"const timestamp = getTime()//时间处理, 获取世界时间日期const date = getDate(timestamp)// ************* 步骤 1:拼接规范请求串 *************const payload = "{\"Limit\": 1, \"Filters\": [{\"Values\": [\"\\u672a\\u547d\\u540d\"], \"Name\": \"instance-name\"}]}"const hashedRequestPayload = getHash(payload);const httpRequestMethod = "POST"const canonicalUri = "/"const canonicalQueryString = ""const canonicalHeaders = "content-type:application/json\n"+ "host:" + endpoint + "\n"const signedHeaders = "content-type;host"const canonicalRequest = httpRequestMethod + "\n"+ canonicalUri + "\n"+ canonicalQueryString + "\n"+ canonicalHeaders + "\n"+ signedHeaders + "\n"+ hashedRequestPayloadconsole.log(canonicalRequest)// ************* 步骤 2:拼接待签名字符串 *************const algorithm = "TC3-HMAC-SHA256"const hashedCanonicalRequest = getHash(canonicalRequest);const credentialScope = date + "/" + service + "/" + "tc3_request"const stringToSign = algorithm + "\n" +timestamp + "\n" +credentialScope + "\n" +hashedCanonicalRequestconsole.log(stringToSign)// ************* 步骤 3:计算签名 *************const kDate = sha256(date, 'TC3' + SECRET_KEY)const kService = sha256(service, kDate)const kSigning = sha256('tc3_request', kService)const signature = sha256(stringToSign, kSigning, 'hex')console.log(signature)// ************* 步骤 4:拼接 Authorization *************const authorization = algorithm + " " +"Credential=" + SECRET_ID + "/" + credentialScope + ", " +"SignedHeaders=" + signedHeaders + ", " +"Signature=" + signatureconsole.log(authorization)const curlcmd = 'curl -X POST ' + "https://" + endpoint+ ' -H "Authorization: ' + authorization + '"'+ ' -H "Content-Type: application/json"'+ ' -H "Host: ' + endpoint + '"'+ ' -H "X-Scf-Cam-Uin: ' + uin + '"'+ ' -H "X-Scf-Cam-Timestamp: ' + timestamp.toString() + '"'+ " -d '" + payload + "'"console.log(curlcmd)}main()
# -*- coding: utf-8 -*-import hashlib, hmac, json, os, sys, timefrom datetime import datetime# 密钥参数# 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******secret_id = os.environ.get("TENCENTCLOUD_SECRET_ID")# 需要设置环境变量 TENCENTCLOUD_SECRET_KEY,值为示例的 Gu5t9xGARNpq86cd98joQYCN3*******secret_key = os.environ.get("TENCENTCLOUD_SECRET_KEY")service = "scf"host = "1253970226-xxxxxxx-cq.scf.tencentcs.com"endpoint = "https://" + hostalgorithm = "TC3-HMAC-SHA256"timestamp = int(time.time())date = datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d")params = {"Limit": 1, "Filters": [{"Values": [u"未命名"], "Name": "instance-name"}]}# ************* 步骤 1:拼接规范请求串 *************http_request_method = "POST"canonical_uri = "/"canonical_querystring = ""ct = "application/json"payload = json.dumps(params)canonical_headers = "content-type:%s\nhost:%s\n" % (ct, host)signed_headers = "content-type;host"hashed_request_payload = hashlib.sha256(payload.encode("utf-8")).hexdigest()canonical_request = (http_request_method + "\n" +canonical_uri + "\n" +canonical_querystring + "\n" +canonical_headers + "\n" +signed_headers + "\n" +hashed_request_payload)print(canonical_request)# ************* 步骤 2:拼接待签名字符串 *************credential_scope = date + "/" + service + "/" + "tc3_request"hashed_canonical_request = hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()string_to_sign = (algorithm + "\n" +str(timestamp) + "\n" +credential_scope + "\n" +hashed_canonical_request)print(string_to_sign)# ************* 步骤 3:计算签名 *************# 计算签名摘要函数def sign(key, msg):return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()secret_date = sign(("TC3" + secret_key).encode("utf-8"), date)secret_service = sign(secret_date, service)secret_signing = sign(secret_service, "tc3_request")signature = hmac.new(secret_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()print(signature)# ************* 步骤 4:拼接 Authorization *************authorization = (algorithm + " " +"Credential=" + secret_id + "/" + credential_scope + ", " +"SignedHeaders=" + signed_headers + ", " +"Signature=" + signature)print(authorization)print('curl -X POST ' + endpoint+ ' -H "Authorization: ' + authorization + '"'+ ' -H "Content-Type: application/json"'+ ' -H "Host: ' + host + '"'+ ' -H "X-Scf-Cam-Uin: ' + uin + '"'+ ' -H "X-Scf-Cam-Timestamp: ' + str(timestamp) + '"'+ " -d '" + payload + "'")
客户端调用参数
在 URL 请求的 Header 中需要添加以下参数:
参数
|
描述
|
Authorization
|
签名相关参数,必传。示例: TC3-HMAC-SHA256 Credential=AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******/2019-02-25/scf/tc3_request, SignedHeaders=content-type;host;xxx, Signature=be4f67d323c78ab9acb7395e43c0dbcf822a9cfac32fea2449a7bc7726b770a3
|
X-Scf-Cam-Timestamp
|
生成签名所使用的时间戳,必传。
|
X-Scf-Cam-Uin
|
主账户 Uin,必传。
|
X-Scf-Cam-Token
|
如果使用临时密钥生成签名,需要传入 token 信息。
|
服务器端验证签名
服务端调用 CAM 服务的签名和鉴权,请参见 访问管理。