azure - Azure API 管理重命名文件
问题描述
目前,我们有前端将文件发送到 Azure 存储帐户到特定的 blob 容器中。前端通过一个人从存储帐户获取 SAS 并将其粘贴到前端代码中,手动将 SAS 令牌放入构建中,以便它可以读取和写入存储帐户。
我们想让前端向 APIM 发送一个带有文件的请求。然后,我们要散列该文件,使用该散列作为名称并将其存储在 azure blob 存储中。我是 Azure API 管理的新手,这可能吗?好像我无法获取上传的文件。
在 APIM 策略中,我目前拥有对存储帐户的授权,但我无法弄清楚如何Request.Files
像通常在 MVC 应用程序中那样获得。
我一直在查看https://docs.microsoft.com/以及https://techcommunity.microsoft.com/和 SO,我什至开始查看 Google 搜索结果的第二页。我找不到任何表明这可能与否的东西。
这是我目前的政策。它的工作原理是前端可以点击它并通过文件并保存该文件。但我们希望对文件进行哈希处理并将该哈希用作名称以避免 Azure 存储帐户 blob 容器中的名称冲突
<policies>
<inbound>
<base />
<set-variable name="UTCNow" value="@(DateTime.UtcNow.ToString("R"))" />
<set-variable name="Verb" value="@(context.Request.Method)" />
<set-variable name="documentstorage" value="{{documentstorage}}" />
<set-variable name="documentstoragekey" value="{{documentstorageaccesskey}}" />
<set-variable name="version" value="2019-12-12" />
<set-variable name="bodySize" value="@(context.Request.Headers["Content-Length"][0])" />
<set-variable name="contentType" value="@(context.Request.Headers["Content-Type"][0])" />
<set-header name="x-ms-version" exists-action="override">
<value>@((string)context.Variables["version"] )</value>
</set-header>
<set-header name="x-ms-blob-type" exists-action="override">
<value>BlockBlob</value>
</set-header>
<set-header name="date" exists-action="override">
<value>@((string)context.Variables["UTCNow"])</value>
</set-header>
<set-header name="Authorization" exists-action="override">
<value>@{
var account = (string)context.Variables["documentstorage"];
var key = (string)context.Variables["documentstoragekey"];
var verb = (string)context.Variables["Verb"];
var container = context.Request.MatchedParameters["container"];
var fileName = context.Request.MatchedParameters["fileName"];
var dateNow = (string)context.Variables["UTCNow"];
string contentType = (string)context.Variables["contentType"];//"application/pdf";
var contentLength = (string)context.Variables["bodySize"];
var stringToSign = string.Format("{0}\n\n\n{1}\n\n{2}\n{3}\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-version:{4}\n/{5}/{6}/{7}",
verb,
contentLength,
contentType,
(string)context.Variables["UTCNow"],
(string)context.Variables["version"],
account,
container,
fileName);
string signature = "";
var unicodeKey = Convert.FromBase64String(key);
using (var hmacSha256 = new HMACSHA256(unicodeKey))
{
var dataToHmac = Encoding.UTF8.GetBytes(stringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
var authorizationHeader = string.Format(
"{0} {1}:{2}",
"SharedKey",
account,
signature);
return authorizationHeader;
}</value>
</set-header>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
解决方案
我还没有尝试过,但听起来你可以获得请求正文(我假设你的文件在哪里):
var inBody = context.Request.Body.As<byte[]>(preserveContent: true);
基于此:https ://docs.microsoft.com/en-us/azure/api-management/api-management-policy-expressions#ref-imessagebody和这个https://docs.microsoft.com/en-us /azure/api-management/api-management-transformation-policies#SetBody
但是,如果您只想获得唯一的文件名,为什么不简单地生成一个 GUID?或者你的意思是你想确保每个文件只上传一次?(然后散列可能是有意义的)
推荐阅读
- php - 如何在php中检查zip文件
- python - Django Admin上的MultiSelectField不显示值
- rest - 基于变量值的不同 requestBody 的 API 设计
- javascript - 如何读取json文件并过滤结果
- javascript - Javascript 对象不存储来自 HTML 的数据
- kdb - 如何将结果链接到分区表 kdb 中的正确行
- migrate - Anthos Migrate 工作原理的详细信息
- java - SQL 随机特征
- ansible - 在 Ansible Tower 中将库存脚本的配置文件放在哪里?
- css - 有没有办法将相同的 css 类合并为一个?