- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
随着Azure Storage support for Azure Active Directory based access control的发布,是否可以仅通过URI在Web浏览器中提供Blob(特定文件)?
我要简化的用例是使一些人可以访问blob上的文件,而无需将SAS令牌附加到URI。相反,当尝试在其Web浏览器中打开普通URI时启动典型的OAuth流程将是很不错的选择。
就我而言,我们希望授予用户通过基于Microsoft Bot框架构建的支持bot上载到blob存储的文件的权限。支持代理应该在他们选择的Web浏览器中访问我们支持系统中的链接。
是本公告支持的该用例,还是仅适用于编码的OAuth流,这意味着我们仍然必须实现一些代码?
如果是这样,是否有一个很好的示例说明如何从Azure Function应用启动OAuth流程并使用生成的令牌下载文件(通过Azure Storage REST终结点)?
最佳答案
尽管this answer在技术上是正确的,但这并不是对我最初的问题的直接回答。
我一直在寻找一种向业务用户提供任何Blob的直接uri的方法,因此他们可以简单地在任何Web浏览器中打开它并查看文件。
就我而言,我们希望允许用户通过基于Microsoft Bot框架构建的支持bot访问用户上传到blob存储的文件。例如。将附件作为我们支持系统中的链接,以供支持代理访问。
深入研究之后,我可以回答自己的问题:
随着宣布Azure存储支持基于Azure Active Directory的访问控制,是否可以仅通过URI通过Web浏览器提供Blob(特定文件)?
不,这是不可能的。更具体地说,仅将直接uri打开到浏览器中的blob不会触发OAuth流。相反,除非您提供SAS查询令牌或将Blob设置为public,否则它将始终为您提供ResourceNotFound
响应。从安全的角度来看,这两种解决方案都是不好的(当涉及普通用户时),UX显然很差。
解
寻找一种完全实现我想要的方法的方法,我想到了通过将fileName
作为url参数并使用路由模板构造路径的,将Azure服务提供给任何业务用户的附件的功能。
考虑到安全性和访问令牌的需求,您可以通过平台身份验证(也称为easyAuth)来保护功能应用程序。
但是,这还不够,并且无法直接配置解决方案的所有部分。这就是为什么我要分享它。
TL; DR高级步骤:
创建一个新的功能应用程序(建议使用v2)
为authentication(easyAuth)启用功能App
为功能应用程序创建服务主体(也称为应用程序注册)(在步骤2中隐含)
在应用程序注册上添加其他允许的令牌受众https://storage.microsoft.com
编辑应用程序注册的清单以包括Azure Storage API权限(请参阅下面的特殊说明)
在Azure资源资源管理器中修改authSettings以包括additionalLoginParams
用于令牌响应和resourceId
至少将blob上的Storage Blob Data Reader权限授予所有访问文件的用户
部署功能应用程序,调用它,访问用户令牌,调用Blob存储并将结果呈现给用户(请参见下面的代码示例)
关于Azure存储API权限和访问令牌的备注(步骤5和6)
如最新的documentation中所述,用于azure存储上的AAD身份验证支持,该应用程序必须对resourceId user_impersonation
授予https://storage.azure.com/
许可范围。不幸的是,文档未说明如何设置此API权限,因为它在门户中不可见(至少我没有找到它)。
因此,唯一的方法是通过直接在azure门户中编辑应用程序注册清单,通过其全局GUID(可在Internet上找到)进行设置。
更新:
事实证明,在门户网站中找不到正确的权限是一个错误。请参阅我的答案here。手动修改清单会产生相同的结果,但是直接在门户网站中进行修改要方便得多。
"requiredResourceAccess": [
{
"resourceAppId": "e406a681-f3d4-42a8-90b6-c2b029497af1",
"resourceAccess": [
{
"id": "03e0da56-190b-40ad-a80c-ea378c433f7f",
"type": "Scope"
}
]
},
{
"resourceAppId": "00000002-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
"type": "Scope"
}
]
}
]
user_impersonation
范围,第二个是
User.Read
的图形权限,在大多数情况下这是有帮助或需要的。
resource=https://storage.azure.com/
来静态地请求这些权限。
response_type=code id_token
作为附加登录参数。
additionalLoginParams
。
"additionalLoginParams": [
"response_type=code id_token",
"resource=https://storage.azure.com/"
]
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
namespace Controller.Api.v1.Org
{
public static class GetAttachment
{
private const string defaultContentType = "application/octet-stream";
[FunctionName("GetAttachment")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "v1/attachments")] HttpRequest req,
ILogger log)
{
if (!req.Query.ContainsKey("fileName"))
return new BadRequestResult();
// Set the file name from query parameter
string fileName = req.Query["fileName"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
fileName = fileName ?? data?.name;
// Construct the final uri. In this sample we have a applicaiton setting BLOB_URL
// set on the function app to store the target blob
var blobUri = Environment.GetEnvironmentVariable("BLOB_URL") + $"/{fileName}";
// The access token is provided as this special header by easyAuth.
var accessToken = req.Headers.FirstOrDefault(p => p.Key.Equals("x-ms-token-aad-access-token", StringComparison.OrdinalIgnoreCase));
// Construct the call against azure storage and pass the user token we got from easyAuth as bearer
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Value.FirstOrDefault());
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept", "*/*");
client.DefaultRequestHeaders.Add("x-ms-version", "2017-11-09");
// Serve the response directly in users browser. This code works against any browser, e.g. chrome, edge or even internet explorer
var response = await client.GetAsync(blobUri);
var contentType = response.Content.Headers.FirstOrDefault(p => p.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase));
var byteArray = await response.Content.ReadAsByteArrayAsync();
var result = new FileContentResult(byteArray, contentType.Value.Any() ? contentType.Value.First() : defaultContentType);
return result;
}
}
}
}
关于azure - 使用新的基于AAD的访问控制通过Web浏览器通过URI访问Blob文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55352689/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!