Azure Blob 存储 SAS 令牌生成及签名错误排查指南

azure blob 存储 sas 令牌生成及签名错误排查指南

本文旨在帮助开发者理解如何使用 JavaScript 生成 Azure Blob 存储的共享访问签名 (SAS) 令牌,并解决常见的签名不匹配错误。通过本文,你将了解 SAS 令牌的构成、签名字符串的生成方法,以及如何避免常见的错误配置,从而成功生成可用的 SAS URL。

理解 Azure Blob 存储 SAS 令牌

共享访问签名 (SAS) 令牌是一种安全地授予对 Azure 存储资源的有限访问权限的机制。它允许你控制谁可以访问你的数据,以及他们可以访问多长时间。SAS 令牌包含所有必要的信息,以便授权请求,而无需共享你的帐户密钥。

SAS 令牌主要用于以下场景:

允许客户端直接上传文件到 Blob 存储,而无需通过你的服务器。授予对 Blob 存储中特定文件的只读访问权限。限制对存储资源的访问,仅在特定时间段内有效。

生成 SAS 令牌的关键步骤

生成 SAS 令牌主要涉及以下几个步骤:

构建签名字符串: 这是最关键的一步,它将用于生成签名。签名字符串包含有关请求的信息,例如权限、开始时间和结束时间、规范化资源等。使用存储帐户密钥对签名字符串进行哈希处理: 使用 HMAC-SHA256 算法和你的存储帐户密钥对签名字符串进行哈希处理。对哈希值进行 Base64 编码: 将哈希结果进行 Base64 编码,得到签名。构建 SAS 令牌: 将签名以及其他参数(例如版本、权限、资源类型等)添加到 URL 中。

解决 “Signature did not match” 错误

“Signature did not match” 错误表明生成的签名与 Azure 存储服务计算出的签名不匹配。这通常是由于签名字符串构建不正确引起的。以下是一些常见的导致签名不匹配的原因以及解决方法

规范化资源字符串错误: 确保规范化资源字符串以服务类型(blob)开头,并包含帐户名称和容器/Blob 的完整路径。

正确的格式应为:/blob//ainer_name>/

错误示例:/ACCOUNTNAME/CONTAINERNAME/PATH_TO_FILE

正确示例:/blob/ACCOUNTNAME/CONTAINERNAME/PATH_TO_FILE

资源类型 (sr) 参数不正确: sr 参数指定了签名资源的类型。对于 Blob 容器,应设置为 c。对于单个 Blob,应设置为 b。确保根据你的使用场景设置正确的 sr 值。

// 对于 Blob 容器var sr = 'c';// 对于单个 Blob// var sr = 'b';

签名字符串的换行符: 签名字符串中的换行符必须是 n。

时间格式不正确: 开始时间 (st) 和结束时间 (se) 必须采用 ISO 8601 UTC 格式。

编码问题: 确保对签名进行 URL 编码。

示例代码(JavaScript)

以下是一个使用 JavaScript 和 crypto-js 库生成 SAS 令牌的示例代码:

var CryptoJS = require("crypto-js");var blobAccount = 'YOUR_ACCOUNT_NAME';var blobContainer = 'YOUR_CONTAINER_NAME/YOUR_BLOB_PATH';var storageAccountKey = 'YOUR_STORAGE_ACCOUNT_KEY';// 计算过期时间var currentDate = new Date();var expiration = new Date(currentDate.getTime() + (100 * 365 * 24 * 60 * 60 * 1000));var st = currentDate.toISOString().slice(0,19)+'Z';var se = expiration.toISOString().slice(0,19)+'Z';var sv = '2018-11-09';var sp = 'r'; // 读权限var sr = 'c'; // 资源类型:容器var canonicalizedResource = "/blob/"+blobAccount+"/"+blobContainer;var stringToSign = sp+'n'+st+'n'+se+'n'+canonicalizedResource+'n'+sv+'n'+sr+'n'+'n'+'n'+'n'+'n'+'n'+'n'+'n';var signature = CryptoJS.HmacSHA256(stringToSign, CryptoJS.enc.Base64.parse(storageAccountKey)).toString(CryptoJS.enc.Base64);var sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv="+sv+"&sp="+sp+"&sr="+sr;var url = "https://"+blobAccount+".blob.core.windows.net/"+blobContainer+"?"+"sig="+sasToken;console.log(sasToken);console.log(url);

注意事项:

替换代码中的 YOUR_ACCOUNT_NAME、YOUR_CONTAINER_NAME/YOUR_BLOB_PATH 和 YOUR_STORAGE_ACCOUNT_KEY 为你的实际值。根据你的需求修改权限 (sp) 和资源类型 (sr)。建议使用环境变量或配置文件安全地存储你的存储帐户密钥,而不是直接在代码中硬编码。请注意 sv(服务版本)参数,确保与你的 Azure 存储帐户兼容。

总结

生成 Azure Blob 存储的 SAS 令牌需要仔细构建签名字符串并正确设置参数。通过理解 SAS 令牌的构成,并遵循本文提供的步骤,你可以避免常见的错误,并成功生成可用的 SAS URL。在遇到 “Signature did not match” 错误时,请仔细检查规范化资源字符串、资源类型参数和时间格式,以确保它们正确无误。 通过示例代码,你可以快速上手,并根据你的实际需求进行调整。

以上就是Azure Blob 存储 SAS 令牌生成及签名错误排查指南的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1511579.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 06:39:20
下一篇 2025年12月20日 06:39:27

相关推荐

  • 使用 jQuery 和 Select2 获取选中的值

    摘要:本文介绍了如何使用 jQuery 和 Select2 插件获取多选下拉菜单中选中的值。通过简单的代码示例,演示了如何初始化 Select2 插件,并利用 .val() 方法获取选中的值数组,同时展示了如何监听 change 事件,在选项发生改变时动态获取选中的值。 Select2 是一个强大的…

    2025年12月20日
    000
  • 使用 jQuery 和 Select2 获取选中值

    本文旨在提供一个清晰简洁的指南,介绍如何使用 jQuery 和 Select2 插件来获取多选下拉列表中用户选中的值。我们将通过示例代码演示如何初始化 Select2 插件,并监听 change 事件来获取选中的值数组,以便在你的 Web 应用中使用。 初始化 Select2 首先,确保你已经正确引…

    2025年12月20日
    000
  • JS如何实现筛选功能

    JavaScript筛选功能的核心是根据条件过滤数据并更新页面展示。首先从数据源(如数组)出发,监听用户输入或选择操作,利用filter()方法按条件(如名称、分类)筛选数据,最后通过DOM操作渲染结果。支持多条件组合时,应基于原始数据依次应用各条件,确保逻辑清晰。为提升性能,可使用防抖减少高频触发…

    2025年12月20日
    000
  • js 怎么用partial实现函数部分应用

    javascript中实现函数部分应用的核心方法是使用function.prototype.bind或自定义partial函数。1. 使用bind可预设参数并固定this上下文,例如add.bind(null, 10)创建新函数addwithten;2. 自定义partial函数利用闭包和apply…

    2025年12月20日
    000
  • JS如何实现Diff算法?Diff的优化

    diff算法的核心思想是通过比较新旧虚拟dom树的差异,尽可能复用现有节点,仅更新变化部分以减少对真实dom的操作。它从根节点开始逐层遍历新旧树,比较同一位置的节点类型与属性,记录节点的增删改移等差异,并生成最小化更新指令应用于真实dom。使用key属性是关键优化手段,能准确识别节点身份,避免误判移…

    2025年12月20日
    000
  • js如何创建自定义事件

    创建自定义事件需使用new event()或new customevent()构造函数,2. 通过dispatchevent()方法触发事件,3. 使用addeventlistener()监听事件,4. customevent可通过detail属性传递数据,5. 设置bubbles为true使事件冒…

    2025年12月20日 好文分享
    000
  • JS如何实现发布订阅?事件总线的原理

    发布订阅模式通过事件总线实现组件间解耦,核心是发布者与订阅者不直接通信,而是通过中心化的调度器传递消息,提升代码模块化与可维护性。 JavaScript中实现发布订阅(Publish-Subscribe)模式,或者说事件总线(Event Bus),核心在于构建一个中心化的调度器。这个调度器不直接连接…

    2025年12月20日
    000
  • javascript闭包怎样实现回调注册表

    闭包是实现回调注册表的理想选择,因为它通过封装私有变量(如callbacks对象)并暴露公共方法(on、off、emit),确保了数据的私密性与完整性,同时维持状态的持久性,使每个事件发射器拥有独立且安全的回调管理机制。1. 使用闭包将callbacks对象隐藏在createeventemitter…

    2025年12月20日 好文分享
    000
  • javascript闭包怎样实现回调队列

    闭包在回调队列中扮演核心角色,因为它能捕获并持久化外部作用域的变量,确保回调函数在异步或延迟执行时仍可访问创建时的上下文。1. 闭包是函数与其词法环境的组合,使内部函数能“记住”外部变量,即使外部函数已执行完毕;2. 回调队列依赖闭包维护状态,避免因异步执行时机导致的变量丢失或污染,尤其在循环中为每…

    2025年12月20日 好文分享
    000
  • JavaScript Canvas绘制复杂图形:路径、模块化与可配置实践

    本教程深入探讨使用JavaScript Canvas API绘制复杂图形的方法。通过一个绘制水壶的实例,详细讲解如何运用quadraticCurveTo和bezierCurveTo等路径方法,并强调了将绘图逻辑封装为可复用函数的最佳实践。文章涵盖了坐标系管理、参数化定制以及Canvas绘图中的关键注…

    2025年12月20日
    000
  • 什么是状态机?有限状态机的实现

    有限状态机常见实现方式有:基于枚举和switch/case语句,适合简单场景但难以维护;状态模式通过封装状态类提升扩展性但类数量增多;状态转换表以表格形式清晰表达转换规则但规模大时复杂;基于框架或库如Spring Statemachine可支持高级功能。选择方式需根据复杂度和需求权衡。 状态机,简单…

    2025年12月20日
    000
  • JS如何替换字符串

    replace()默认只替换第一个匹配项,需用正则加g标志实现全局替换;replaceAll()则直接替换所有匹配项,语法更简洁,但不支持正则表达式,且兼容性较差。 在JavaScript中,替换字符串主要依赖于String对象的 replace() 方法,它能让你用新的内容替换掉字符串中匹配到的部…

    2025年12月20日
    000
  • js 怎样处理鼠标滚轮事件

    最推荐的方式是监听wheel事件。它提供deltaY、deltaX和deltaMode属性,能精确获取滚动方向与幅度,通过preventDefault()阻止默认行为并结合{passive: false}实现自定义滚动,现代浏览器支持良好,优于旧的mousewheel和DOMMouseScroll事…

    2025年12月20日
    000
  • js 怎么检测滚动位置

    javascript中获取滚动位置的核心属性有三个:1. window.scrolly 和 window.scrollx,用于获取整个页面在垂直和水平方向的滚动距离,是现代浏览器推荐的标准属性;2. document.documentelement.scrolltop 和 document.docu…

    2025年12月20日
    000
  • 什么是解释器模式?解释器的实现

    解释器模式通过定义语言文法并构建表达式树来解释执行特定语句,适用于SQL解析、正则表达式、编译器、规则引擎、数学表达式计算及游戏脚本解析等场景;其核心组件包括抽象表达式、终结符表达式、非终结符表达式和上下文,优点是扩展性好、实现灵活,但存在类数量多、性能较低、维护困难等缺点,适合文法简单且需动态解析…

    2025年12月20日
    000
  • js 如何用merge合并多个对象数组

    首先使用map以指定键(如id)为唯一标识存储对象;2. 遍历所有数组,若map中已存在相同键则进行浅合并(新属性覆盖旧属性),否则直接添加;3. 最后将map的值转换为数组返回,实现基于关键字段的多个对象数组的深度合并,最终得到一个属性完整且唯一标识的对象数组。 Okay,关于JavaScript…

    2025年12月20日
    000
  • Promise与setTimeout的执行顺序

    promise的回调(微任务)总是在同一个事件循环周期内优先于settimeout的回调(宏任务)执行。javascript是单线程语言,通过事件循环机制处理异步操作,同步代码在调用栈中按顺序执行,遇到异步任务时,promise的.then()、.catch()、.finally()回调被放入微任务…

    2025年12月20日 好文分享
    000
  • js 怎么发送AJAX请求

    最现代且推荐的ajax请求方式是使用fetch api,1. 它基于promise,语法简洁,支持async/await,2. 可通过配置对象发送get/post请求并自定义请求头,3. 需手动检查response.ok处理http错误,4. 使用abortcontroller结合promise.r…

    2025年12月20日
    000
  • 哈希查找是什么?哈希冲突解决方法

    哈希查找通过哈希函数将键映射到哈希表的索引位置以实现快速访问,其核心优势在于接近常数时间的查找效率,但因键的数量远超表的槽位数,哈希冲突不可避免,这是由鸽巢原理和哈希函数的压缩特性决定的,而非设计缺陷;为应对冲突,链地址法采用每个槽位存储链表或树的结构,冲突时将数据插入对应链表,实现简单且对哈希函数…

    2025年12月20日
    100
  • 什么是命令模式?命令模式的封装

    命令模式通过将请求封装为对象,实现了请求发送者与接收者的解耦,使操作可参数化、存储、传递及撤销;它解决了复杂操作中高耦合和扩展难的问题,支持撤销/重做、宏命令、任务队列等场景;典型应用包括gui按钮菜单、图像处理宏、异步任务队列和游戏行为控制;但其缺点是会增加类的数量,可能导致过度抽象,且撤销逻辑实…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信