Azure Blob Storage SAS提前过期:ASP.NET Core v1.1应用异常求助
排查ASP.NET Core应用中SAS提前过期的问题
嘿,我来帮你拆解这个SAS提前过期的问题,咱们从最可能的原因开始排查,再对应给出解决方案:
1. 时间计算与缓存配置的错误
这是最常见的诱因,尤其是时区偏差或者缓存参数设置不对:
- SAS有效期的时区问题:Azure Blob Storage的SAS完全基于UTC时间计算,如果你的代码里用了本地时间(比如
DateTime.Now)来生成过期时间,一旦服务器时区和UTC有偏差,就会导致SAS实际有效期缩短。比如服务器用北京时间,DateTime.Now.AddHours(36)会比UTC时间早8小时,SAS实际有效期就变成了28小时,而你缓存18小时后,剩下的有效时间就只剩10小时,很容易出现用户访问时过期。
修复代码:强制用UTC时间生成SAS:var sasPolicy = new SharedAccessBlobPolicy { Permissions = SharedAccessBlobPermissions.Read, SharedAccessExpiryTime = DateTime.UtcNow.AddHours(36) // 必须用UTC时间 }; - 缓存参数配置错误:检查你的内存缓存设置,确认滑动过期是6小时、绝对过期是18小时。比如:
这里要注意:绝对过期18小时意味着缓存的SAS最多存18小时,而SAS本身有36小时有效期,理论上缓存的SAS至少还有18小时有效时间,除非缓存提前被清理。cache.Set(sasKey, sasToken, new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromHours(6), AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(18) });
2. 进程内缓存被意外清空
ASP.NET Core的内存缓存是进程内的,如果应用程序池回收、进程重启(比如部署更新、服务器内存不足被系统杀掉),缓存的SAS就会全部丢失。这时候如果用户的浏览器缓存了旧的带SAS的URL,就会出现“提前过期”的报错。
- 排查方法:查看应用的日志(比如IIS应用池回收日志、ASP.NET Core启动日志),确认有没有频繁重启的情况。
- 解决方案:
- 换成分布式缓存(比如Azure Redis Cache),这样即使应用重启,缓存的SAS依然保留。
- 在生成的图片URL中加入SAS的过期时间戳或者版本号,避免浏览器缓存旧的URL。比如:
https://yourblob.blob.core.windows.net/container/image.jpg?sasToken=xxx&expires=202405201200
3. 滑动过期的触发逻辑问题
滑动过期是指如果6小时内没有访问缓存的SAS,条目就会过期。如果某个SAS缓存长时间没被访问,过期后重新生成是正常的,但如果用户请求刚好赶上缓存过期的瞬间,可能会拿到无效的SAS(不过这种情况应该是偶发的)。
- 修复代码:使用
GetOrCreate方法确保线程安全的缓存获取与生成,避免多个请求同时生成SAS,也确保缓存失效时立即生成新的:var sasToken = cache.GetOrCreate(sasKey, entry => { entry.SlidingExpiration = TimeSpan.FromHours(6); entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(18); // 调用你的SAS生成逻辑 return GenerateSasTokenForBlob(); });
4. 系统时间偏差
如果应用服务器的系统时间和Azure的服务器时间偏差过大(比如慢了几个小时),生成的SAS过期时间会比实际预期早。
- 排查方法:检查服务器的系统时间是否和UTC时间同步,可通过
date -u(Linux)或者w32tm /query /status(Windows)命令查看。 - 解决方案:开启服务器的自动时间同步,确保和UTC时间一致。
5. 额外排查点:SAS资源匹配问题
有时候看起来是过期,实际是SAS的资源路径不匹配(比如容器名、Blob文件名大小写错误,Azure Blob Storage文件名区分大小写),或者权限不足。可以尝试手动生成一个SAS测试,看是否能正常访问图片,排除这类问题。
内容的提问来源于stack exchange,提问作者Steve B
相关产品推荐
相关产品推荐

