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

如何授权Azure B2C用户读取Azure Storage Blob及生成用户委托SAS令牌

方案一:用户委派SAS令牌实现(推荐通过后端API代理)

由于SPA直接在前端生成用户委派SAS会暴露敏感操作逻辑,建议通过Next.js的API路由作为中间层完成,步骤如下:

1. 获取用户的Azure Storage访问令牌

用户通过NextAuth登录后,需获取针对Azure Blob Storage的访问令牌(而非ID令牌):

  • 在[...nextauth].js的AAD B2C Provider配置中,添加存储服务的权限scope:
providers: [
  AzureADB2CProvider({
    clientId: process.env.AZURE_AD_B2C_CLIENT_ID,
    clientSecret: process.env.AZURE_AD_B2C_CLIENT_SECRET,
    tenantId: process.env.AZURE_AD_B2C_TENANT_ID,
    scope: 'openid offline_access https://storage.azure.com/user_impersonation',
    // 其他B2C相关配置
  })
]
  • 登录后,可通过useSession钩子或API路由的req.session获取用户的accessToken,需确认该令牌的受众为Azure Storage服务。

2. 后端API路由生成用户委派密钥与SAS

创建Next.js API路由(如pages/api/generate-sas.js),完成以下操作:

  • 验证用户会话(通过getServerSession确保只有已登录用户可访问)
  • 使用用户的访问令牌获取用户委派密钥
  • 基于密钥生成用户委派SAS令牌
    示例代码:
import { BlobServiceClient, generateUserDelegationSAS } from '@azure/storage-blob';
import { getServerSession } from 'next-auth/next';
import { authOptions } from './auth/[...nextauth]';

export default async function handler(req, res) {
  const session = await getServerSession(req, res, authOptions);
  if (!session) return res.status(401).json({ error: 'Unauthorized' });

  const { containerName, blobName } = req.body;
  const accessToken = session.user.accessToken;

  // 初始化Blob服务客户端
  const blobServiceClient = new BlobServiceClient(
    `https://${process.env.STORAGE_ACCOUNT_NAME}.blob.core.windows.net`,
    new TokenCredential(accessToken)
  );

  // 获取用户委派密钥(有效期1小时)
  const userDelegationKey = await blobServiceClient.getUserDelegationKey(
    new Date(),
    new Date(Date.now() + 3600 * 1000)
  );

  // 生成只读权限的用户委派SAS
  const sasToken = generateUserDelegationSAS({
    containerName,
    blobName,
    userDelegationKey,
    startsOn: new Date(),
    expiresOn: new Date(Date.now() + 3600 * 1000),
    permissions: 'r',
    protocol: 'https'
  });

  res.status(200).json({ sasToken });
}

3. 前端使用SAS访问Blob

前端拿到SAS令牌后,拼接成Blob的完整访问URL:
https://{storage-account-name}.blob.core.windows.net/{container}/{blob}?{sasToken}
直接请求该URL即可读取文件,Azure Storage会自动验证SAS对应的RBAC权限。


方案二:替代方案——后端代理Blob请求(更安全)

若用户委派SAS流程过于繁琐,可采用后端代理的方式,完全屏蔽存储资源的直接访问:

  • 前端请求Next.js API路由,传入目标Blob的容器名和文件名
  • API路由验证用户会话后,用用户的访问令牌直接访问Blob并返回内容
    示例代码:
import { BlobServiceClient } from '@azure/storage-blob';
import { getServerSession } from 'next-auth/next';
import { authOptions } from './auth/[...nextauth]';

export default async function handler(req, res) {
  const session = await getServerSession(req, res, authOptions);
  if (!session) return res.status(401).json({ error: 'Unauthorized' });

  const { containerName, blobName } = req.query;
  const accessToken = session.user.accessToken;

  const blobServiceClient = new BlobServiceClient(
    `https://${process.env.STORAGE_ACCOUNT_NAME}.blob.core.windows.net`,
    new TokenCredential(accessToken)
  );

  const containerClient = blobServiceClient.getContainerClient(containerName);
  const blobClient = containerClient.getBlobClient(blobName);

  // 获取Blob流并返回给前端
  const downloadResponse = await blobClient.download();
  res.setHeader('Content-Type', downloadResponse.contentType);
  downloadResponse.readableStreamBody.pipe(res);
}

这种方式下,Azure Storage会直接通过用户的访问令牌验证RBAC权限,无需手动处理SAS逻辑,且存储资源的URL不会暴露给前端。


关键注意事项
  • RBAC权限配置:确保用户所属的AAD组被分配了对应的存储角色,如Storage Blob Data Reader(只读权限),这是所有授权逻辑的基础。
  • 令牌刷新:用户的访问令牌存在有效期,NextAuth通常会自动处理刷新令牌流程,需确保配置正确。
  • 安全约束:所有涉及令牌、密钥的操作必须在后端完成,绝对不能在前端处理敏感逻辑,避免信息泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:00:59