跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

C# Azure Blob SAS令牌 C#如何生成用于访问Blob存储的共享访问签名

生成 Blob SAS 令牌必须使用 StorageSharedKeyCredential,不可仅用含 SAS 的连接字符串;UserDelegationKey 需账户密钥参与签名,且 BlobSasBuilder 的 Resource 必须设为 Blob 或 Container,时间需严格 UTC 校准并匹配 key 有效期。 生成 Blob SAS 令牌必须用
StorageSharedKeyCredential
,不能只靠连接字符串 直接用连接字符串初始化
BlobServiceClient
后调用
GetUserDelegationKeyAsync
会失败——因为用户委托密钥需要账户级密钥参与签名。连接字符串里如果只含 SAS 或仅含 endpoint,就缺这个关键凭证。 正确做法:先用账户名 + 账户密钥构造
StorageSharedKeyCredential
,再传给
BlobServiceClient
错误现象:
InvalidOperationException: Cannot create user delegation key with connection string containing only SAS token
注意:Azure AD 凭据(如
DefaultAzureCredential
)也不能替代
StorageSharedKeyCredential
生成用户委托 SAS;它只适用于资源访问,不参与密钥签发
BlobSasBuilder
的
Resource
参数必须设为
BlobSasResource.Blob
或
BlobSasResource.Container
,不能填错 这个枚举值决定 SAS 的作用范围,填错会导致生成的令牌在实际请求时返回
403 Server failed to authenticate the request
或
404 The specified resource does not exist
。
BlobSasResource.Blob
→ 令牌只能访问单个 blob(需同时指定
BlobContainerName
和
BlobName
)
BlobSasResource.Container
→ 令牌可列出容器内 blob、读写新 blob(但不能删已有 blob,除非加
Permissions
中的
d
) 常见误配:
Resource = BlobSasResource.Service
是无效值,编译过不去;
Resource = BlobSasResource.Account
属于 Account SAS,得用
AccountSasBuilder
,和这里无关 时间参数必须严格校准:开始时间不能晚于当前 UTC,过期时间不能超过 7 天(用户委托 SAS)或 24 小时(账户密钥 SAS) 本地时钟偏移、未用
DateTimeOffset.UtcNow
、手动加减小时数却忽略夏令时,都会让 SAS 立即失效或提前过期。 C知道 CSDN推出的一款AI技术问答工具 下载 必须用
DateTimeOffset
,且全部基于 UTC:
startsOn = DateTimeOffset.UtcNow
,
expiresOn = DateTimeOffset.UtcNow.AddHours(1)
用户委托 SAS(推荐)最大有效期是 7 天,超时会抛
ArgumentException: Expiry time must be within 7 days
账户密钥 SAS 最大有效期是 24 小时,超时同样报错;但它不需要用户委托密钥,适合简单场景 如果服务端时间比客户端快 5 分钟,而你设了
startsOn = DateTimeOffset.Now
(本地时间),令牌可能还没生效就被拒 用户委托 SAS 需要两步:先取
UserDelegationKey
,再用它构建签名——跳过任一环节都拿不到有效令牌 这是最容易漏掉的链路。很多人以为调一次
GetUserDelegationKeyAsync
就能复用很久,其实它的有效期默认只有 7 天,而且每次构建 SAS 都要传入最新 key。 第一步:
var key = await client.GetUserDelegationKeyAsync(startTime, expiryTime)
(注意 start/expires 必须覆盖你要签的 SAS 时间范围) 第二步:把
key
塞进
BlobSasBuilder
的
SetUserDelegationKey
方法,再调
ToString()
性能提示:key 可缓存复用(比如存到内存或 Redis),但别缓存超过其自身
ExpiresOn
;每次生成 SAS 前检查是否过期 示例片段:
var sas = new BlobSasBuilder { BlobContainerName = "mycontainer", BlobName = "myfile.txt", Resource = BlobSasResource.Blob, StartsOn = DateTimeOffset.UtcNow, ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(60), Permissions = "r" }; sas.SetUserDelegationKey(key, accountName); // accountName 是存储账户名,不是连接字符串里的全路径
实际用起来最麻烦的不是语法,是时间对齐、凭证类型匹配、还有那个必须显式传进去的
accountName
字符串——它得和你初始化
StorageSharedKeyCredential
时用的完全一致,大小写敏感,少一个字符都不行。

相关文章