You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ClaimsPrincipal从Azure Function传递至BlobClient

实现用登录用户身份验证Blob权限并生成SAS令牌

核心思路是通过On-Behalf-Of(OBO)流程获取登录用户针对Azure Blob Storage的访问令牌,用该令牌验证用户对目标容器的ACL权限,验证通过后再生成符合权限范围的SAS令牌。

1. 配置AAD应用与权限

  • 给Azure Function对应的AAD注册应用添加委派权限:
    • 添加Azure Storage的user_impersonation权限,并完成管理员同意
    • 确保已添加Microsoft Graph的User.Read权限(用于OBO流程的基础身份验证)
  • 为Azure Function启用系统分配的托管标识(比客户端密钥更安全)

2. 在Azure Function中实现OBO流程获取用户Blob令牌

使用Microsoft.Identity.Web库简化OBO流程,以下是C#示例:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Identity.Web;
using Azure.Storage.Blobs;
using Azure.Storage.Sas;
using Azure.Core;

public class BlobSasGenerator
{
    private readonly ITokenAcquisition _tokenAcquisition;

    public BlobSasGenerator(ITokenAcquisition tokenAcquisition)
    {
        _tokenAcquisition = tokenAcquisition;
    }

    [FunctionName("GetBlobSas")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req)
    {
        // 通过OBO流程获取用户的Blob Storage访问令牌
        string blobToken = await _tokenAcquisition.GetAccessTokenForUserAsync(
            new[] { "https://storage.azure.com/user_impersonation" });

        // 用用户令牌初始化Blob服务客户端
        BlobServiceClient blobServiceClient = new BlobServiceClient(
            new Uri("https://<你的存储账户名>.blob.core.windows.net"),
            new TokenCredential(blobToken));

        string containerName = req.Query["containerName"];
        string blobName = req.Query["blobName"];

        try
        {
            // 验证用户对容器的访问权限(无权限会抛出403异常)
            BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
            await containerClient.GetPropertiesAsync();

            // 可选:验证用户对目标Blob的访问权限
            BlobClient blobClient = containerClient.GetBlobClient(blobName);
            await blobClient.GetPropertiesAsync();

            // 生成SAS令牌,权限与用户ACL匹配(示例为只读)
            BlobSasBuilder sasBuilder = new BlobSasBuilder()
            {
                BlobContainerName = containerName,
                BlobName = blobName,
                Resource = "b", // b=Blob,c=容器
                ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
            };
            sasBuilder.SetPermissions(BlobSasPermissions.Read);

            // 用存储账户密钥生成SAS(若用托管身份,可生成用户委派SAS)
            string sasToken = sasBuilder.ToSasQueryParameters(
                new StorageSharedKeyCredential("<存储账户名>", "<存储账户密钥>")).ToString();
            string sasUrl = $"{blobClient.Uri}?{sasToken}";

            return new OkObjectResult(new { SasUrl = sasUrl });
        }
        catch (RequestFailedException ex) when (ex.Status == 403)
        {
            // 用户无权限,返回禁止访问
            return new ForbidResult();
        }
        catch (Exception ex)
        {
            return new BadRequestObjectResult($"错误:{ex.Message}");
        }
    }
}

3. 配置Blob容器的ACL权限

在Azure Portal的Blob容器页面,进入访问控制(IAM),为AAD用户/组分配对应角色:

  • 只读权限:分配存储Blob数据读取者角色(容器级别)
  • 更细粒度权限:可使用自定义RBAC角色或Blob级ACL(RBAC权限优先级更高)

关键注意事项

  • 用户委派SAS(可选):若需严格基于用户身份生成SAS,可使用用户委派SAS,需用用户的Blob令牌生成,但要求存储账户启用分层命名空间(ADLS Gen2)
  • 权限最小化:生成SAS时仅赋予用户所需权限(如只读),并设置合理的过期时间
  • 错误拦截:必须捕获403异常,确保无权限用户无法获取SAS令牌

内容的提问来源于stack exchange,提问作者TJ_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:25:13