You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apex类上传文件至Azure Blob报MAC签名不匹配错误如何解决

签名不匹配的具体问题定位

    1. 文件名编码使用错误
      构造签名用的blobName参数使用了URL编码后的文件名,Azure计算签名时要求使用原始未编码的文件路径,仅请求端点的文件名需要做URL编码,二者混用直接导致签名校验失败。
    1. 签名字符串换行符数量不匹配
      按照2015-12-11版本的Azure Blob签名规则,PUT请求的签名字符串中Content-Type字段后应跟随6个换行符(对应6个未使用的请求头空位),你的代码中多写了1个换行符,导致签名结构不符合要求。
    1. 日期格式化未指定英文Locale
      Apex的formatGMT方法默认使用当前用户的Locale,如果用户Locale为非英文,生成的星期缩写、月份缩写会是本地语言,Azure无法识别该日期格式,最终导致签名校验失败。

修正代码片段

1. 修改uploadBlob方法内的文件名处理逻辑

public Boolean uploadBlob( Blob fileBody, Integer intFileLength, String strFileType, String strFileName)
{
    Boolean isUploaded= false;
    // 新增:单独存储原始文件名用于签名,编码后的文件名仅用于请求端点
    String rawFileName = strFileName;
    String encodedFileName = EncodingUtil.urlEncode(strFileName, 'UTF-8');
    this.fileType = strFileType;
    this.storageName = 'STORAGE_ACCOUNT';
    this.storageContainer = 'CONTAINER_NAME';
    this.storageKey = 'ACCESS_KEY';
    this.storageUrl ='https://STORAGE_ACCOUNT.blob.core.windows.net';

    // 签名用的blobName使用原始未编码文件名
    this.blobName = '/'+storageName+'/'+storageContainer+'/'+rawFileName;
    System.debug('blobName--->'+blobName);
    // 请求端点使用编码后的文件名
    this.requestURL = storageUrl+'/'+storageContainer+'/'+encodedFileName;
    System.debug('requestURL--->'+requestURL);

    this.fileLength = String.valueof(intFileLength);
    String strSharedKey = getBlobSharedKey();
    try
    {
        this.uploadBlob(fileBody, strSharedKey);
        isUploaded = true;
    }catch(Exception exp)
    {
        System.debug('Exception occur while uploading the Blob--->'+exp.getMessage());
        isUploaded = false;
    }
    return isUploaded;
}

2. 修改getBlobSharedKey方法内的日期格式化和签名字符串构造逻辑

public String getBlobSharedKey()
{
    System.debug('getBlobSharedKey--->Start');
    String sharedKey;
    String signature;
    Datetime dt = Datetime.now();
    // 新增:指定Locale为en_US,确保日期格式为英文缩写
    this.formattedDate = dt.formatGMT(DATEFORMAT, 'en_US');
    // 调整:Content-Type后由7个换行改为6个换行,匹配Azure签名规则
    String stringToSign = 'PUT\n\n\n'+fileLength+'\n\n'+fileType+'\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:'+formattedDate+'\nx-ms-version:2015-12-11\n'+blobName;
    System.debug('stringToSign--->'+stringToSign);
    Blob unicodeKey = EncodingUtil.base64Decode(storageKey);
    Blob data = Crypto.generateMac('hmacSHA256', Blob.valueOf(stringToSign), unicodeKey);
    signature = EncodingUtil.base64Encode(data);
    sharedKey = 'SharedKey '+storageName+':' + signature;
    return sharedKey;
}

校验提示

如果修改后仍存在签名错误,可直接提取Azure错误响应中给出的String to sign参考值,和你本地生成的stringToSign逐字符对比,即可快速定位剩余差异。

内容的提问来源于stack exchange,提问作者hansaliyad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:09:03