云函数 函数 URL 认证鉴权配置

可以以通过配置认证鉴权策略来控制对函数 URL 的访问。在配置函数 URL 时,必须指定以下认证选项之一。

相关产品
云函数 产品页,含版本规格、价格与购买入口。

一、简介

·CAM 鉴权:需要对函数 CAM 鉴权验证,用户可以基于函数 InvokeFunctionUrl 接口进行资源管理和使用权限配置。你可以通过配置 InvokeFunctionUrl 策略权限来开放或限制接口的访问。

·开放:不需要对函数请求进行身份验证,支持匿名访问,任何人都可以发起 HTTP 请求调用你的函数。

二、配置 InvokeFunctionUrl 策略权限

你可以参考以下步骤配置 InvokeFunctionUrl 策略权限来开放或限制接口的访问。

1. 在访问管理控制台的 策略 页面,单击左上角的新建自定义策略。

2. 在弹出的选择创建方式窗口中,单击按策略生成器创建,进入编辑策略页面。

3. 在可视化策略生成器中添加服务与操作栏,补充以下信息,编辑一个授权声明。

·效果(必选):选择允许。

·服务(必选):选择云函数 (scf)。

·操作(必选):单击全部操作 (scf:*)右侧的展开,搜索 InvokeFunctionUrl,并勾选。如下:

·资源(必填):选择全部资源或你要授权的特定资源。

·条件(选填):设置上述授权的生效条件。

4. 完成策略授权声明编辑后,单击下一步,进入基本信息和关联用户/用户组/角色页面。

5. 在关联用户/用户组/角色页面,补充策略名称和描述信息,可同时关联用户/用户组/角色快速授权。

6. 单击完成,完成按策略生成器创建自定义策略的操作。

三、客户端生成签名

签名算法请参见 安全凭证服务签名方法。代码示例如下:

JavaGoNodeJSPythonimport 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,值为示例的 AKID*************** 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 uin = "xxxxxx";//此处替换为需要使用的真实uin 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; charset=utf-8\\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+canonicalUri) .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" "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() { // 需要填写账户UIN uin := "xxxx" // 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKID*************** 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 string httpRequestMethod := "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 sign date := 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 string secretDate := 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 authorization authorization := fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", algorithm, secretId, credentialScope, signedHeaders, signature) fmt.Println(authorization) curl := fmt.Sprintf(`curl -X %s https://%s -H "Authorization: %s" -H "Content-Type: application/json" -H "Host: %s" -H "X-Scf-Cam-Uin: %s" -H "X-Scf-Cam-Timestamp: %d" -d '%s'`, httpRequestMethod, 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({secretId,secretKey,uin,endpoint}){ const service = "scf" const timestamp = Math.round(new Date().getTime() / 1000); console.log(timestamp) //时间处理, 获取世界时间日期 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" + hashedRequestPayload console.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" + hashedCanonicalRequest console.log(stringToSign) // ************* 步骤 3:计算签名 ************* const kDate = sha256(date, 'TC3' + secretKey) 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=" + secretId + "/" + credentialScope + ", " + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature console.log(authorization) const curlcmd = 'curl -X POST ' + "https://" + endpoint + canonicalUri + ' -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:',curlcmd)}// 密钥参数// secretId,值为示例的 AKID***************// secretKey,值为示例的 Gu5t9xGARNpq86cd98joQYCN3*******// endpoint: 函数uri的host,如 ****-4m1ipprwba.ap-beijing.tencentscf.com// uin:主账号UINmain({ secretId: '*******************', secretKey: '*******************', endpoint: '*******-4m1ipprwba.ap-beijing.tencentscf.com', uin: '********'})# -*- coding: utf-8 -*-import hashlib, hmac, json, os, sys, timefrom datetime import datetime# 密钥参数# 需要设置环境变量 TENCENTCLOUD_SECRET_ID,值为示例的 AKID**************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 + "'")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 %s https://%s -H "Authorization: %s" -H "Content-Type: application/json" -H "Host: %s" -H "X-Scf-Cam-Uin: %s" -H "X-Scf-Cam-Timestamp: %d" -d '%s'`, httpRequestMethod, host, authorization, host, uin, timestamp, payload)fmt.Println(curl)

四、客户端调用参数

在 URL 请求的 Header 中需要添加以下参数:

参数 描述
Authorization 签名相关参数,必传。示例:
TC3-HMAC-SHA256 Credential=AKID****************/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 服务的签名和鉴权,请参见 访问管理。

赞 (0)
上一篇 4天前
下一篇 4天前