# ============================================================================= # 企微IT智能服务台 — ITSM OpenAPI 签名工具 # ============================================================================= # 说明:ITSM 一站式运维平台 OpenAPI 采用 SHA1 签名认证。 # 每次请求需在 header 中携带 appId、timestamp、sign 三个字段。 # sign 的计算方式由 ITSM API 文档定义,此模块封装为静态工具类。 # ============================================================================= import hashlib import json import time from urllib.parse import quote_plus class ITSMSigner: """ITSM OpenAPI 签名工具 — SHA1 签名认证。 签名算法(来自 ITSM API 文档): 1. 组装 sign_params = {appId, timestamp, appSecret, bizData=json.dumps(body)} 2. 按 key 升序排列 3. 拼接所有 value 为一个字符串 4. quote_plus 编码 5. SHA1 哈希 6. 转大写 hex 设计为纯静态工具类,无需实例化,线程安全。 """ @staticmethod def compute_signature(app_id: str, timestamp: str, app_secret: str, biz_data: dict) -> str: """计算 ITSM API 签名。 Args: app_id: ITSM OpenAPI app_id timestamp: 毫秒级时间戳字符串 app_secret: ITSM OpenAPI app_secret biz_data: 请求体(业务数据),将被 json 序列化后参与签名 Returns: str: 大写 hex 格式的 SHA1 签名 """ sign_params = { "appSecret": app_secret, "appId": app_id, "timestamp": timestamp, "bizData": json.dumps(biz_data, ensure_ascii=False), } # 按 key 升序排列后拼接所有 value sorted_params = sorted(sign_params.items(), key=lambda x: x[0]) canonicalized = "".join(str(v) for _, v in sorted_params) # URL 编码 quoted = quote_plus(canonicalized) # SHA1 哈希转大写 return hashlib.sha1(quoted.encode("utf-8")).hexdigest().upper() @staticmethod def get_headers(app_id: str, app_secret: str, biz_data: dict) -> dict: """生成带签名的请求头。 Args: app_id: ITSM OpenAPI app_id app_secret: ITSM OpenAPI app_secret biz_data: 请求体(业务数据),用于计算签名 Returns: dict: 包含 appId、timestamp、sign、Content-Type 的请求头 """ timestamp = str(int(time.time() * 1000)) sign = ITSMSigner.compute_signature(app_id, timestamp, app_secret, biz_data) return { "appId": app_id, "timestamp": timestamp, "sign": sign, "Content-Type": "application/json", }