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

Java生成Azure SAS token出现Signature Fields Not Well Formed错误求助

Azure存储SAS生成报"signature fields not well formed"错误的常见原因与修复方案

核心前提

你需要生成的是Azure存储服务的SAS令牌,不能混用事件中心的SAS生成逻辑,两类服务的签名串拼接规则完全不同,混用是触发该报错的高频原因。

常见遗漏/错误点

  • 签名串拼接顺序错误/缺空行
    存储账户SAS的签名串必须严格按照固定顺序拼接,未用到的可选字段必须保留空行,不能直接省略。标准拼接顺序如下:

    存储账户名
    授权服务类型(blob/file/queue/table对应首字母)
    授权资源类型(服务/容器/对象对应s/c/o的组合)
    授权权限(读/写/列等对应r/w/l等的组合)
    授权起始时间(UTC时区ISO 8601格式,建议比当前时间早5分钟避免时钟偏移)
    授权过期时间(UTC时区ISO 8601格式)
    授权IP范围(无则留空行)
    授权协议(https/https,http,无则留空行)
    存储服务API版本号
    5个连续空行(对应存储服务可选的专属扩展字段,无配置必须全部保留空行)

  • 密钥处理逻辑错误
    存储账户的访问密钥本身是Base64编码的字符串,计算HMAC-SHA256签名前需要先做Base64解码,不能直接将密钥字符串转字节数组参与计算。
  • 编码格式错误
    签名计算完成后,签名值以及所有SAS参数都需要做URL编码,+、/、=等特殊字符必须转义,否则会触发签名校验失败。
  • API版本不匹配
    生成SAS时指定的存储服务API版本号,必须和实际发起文件请求时携带的API版本号一致,否则会校验失败。

正确Java代码示例

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class StorageSasGenerator {
    public static String generateAccountSas(String accountName, String accountKey) throws Exception {
        // 按实际需求配置SAS参数
        String signedService = "f"; // f对应File存储,用Blob则填b
        String signedResourceType = "sco"; // 授权服务、容器、对象级资源
        String signedPermission = "rl"; // 授予读、列权限
        String signedStart = OffsetDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(DateTimeFormatter.ISO_INSTANT);
        String signedExpiry = OffsetDateTime.now(ZoneOffset.UTC).plusHours(2).format(DateTimeFormatter.ISO_INSTANT);
        String signedProtocol = "https";
        String signedVersion = "2021-06-08"; // 建议用你实际调用的存储API版本

        // 严格按规则拼接签名字符串
        String stringToSign = String.join("\n",
            accountName,
            signedService,
            signedResourceType,
            signedPermission,
            signedStart,
            signedExpiry,
            "", // 无IP限制留空
            signedProtocol,
            signedVersion,
            "", // 以下5个扩展字段无配置全部留空
            "",
            "",
            "",
            ""
        );

        // 计算HMAC-SHA256签名
        Mac sha256Hmac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
        sha256Hmac.init(secretKey);
        String signature = Base64.getEncoder().encodeToString(sha256Hmac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)));

        // 拼接最终SAS令牌,所有参数值做URL编码
        return String.format("?sv=%s&ss=%s&srt=%s&sp=%s&st=%s&se=%s&spr=%s&sig=%s",
            URLEncoder.encode(signedVersion, StandardCharsets.UTF_8),
            URLEncoder.encode(signedService, StandardCharsets.UTF_8),
            URLEncoder.encode(signedResourceType, StandardCharsets.UTF_8),
            URLEncoder.encode(signedPermission, StandardCharsets.UTF_8),
            URLEncoder.encode(signedStart, StandardCharsets.UTF_8),
            URLEncoder.encode(signedExpiry, StandardCharsets.UTF_8),
            URLEncoder.encode(signedProtocol, StandardCharsets.UTF_8),
            URLEncoder.encode(signature, StandardCharsets.UTF_8)
        );
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:03