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

如何修复Azure文件上传中的‘RestError: 请求认证失败’错误

问题

我用Hono、NeDB和TypeScript搭建后端实现文件上传功能,前端选择文件后发送请求:

const res = await axios.post(
    `${import.meta.env.VITE_BACKEND_URL}/files/sas?file=${encodeURIComponent(
        file.name
    )}&permission=${permission}&container=${blobStorageSettings.containerName}&timerange=${timerange}`,
{
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + window.localStorage.getItem('jwt').replace(/"/g, '')
    }
}
)

后端对应端点代码:

files.post("/sas", async (c: Context) => {
  try {
...
        const fileName = c.req.query('file') || 'nonamefile';
        const permissions = c.req.query('permission') || 'w';
        const timerange = parseInt(c.req.query('timerange') || '10'); // 默认10分钟
        const containerName = blobStorageDetails.containerName || 'anonymous';
        
        const sasUrl = await generateSASUrl(
          blobStorageDetails.serviceName,
          blobStorageDetails.serviceKey,
          containerName,
          fileName,
          permissions,
          timerange
        );
...

generateSASUrl函数代码:

export const generateSASUrl = async (
    serviceName: string,
    serviceKey: string,
    containerName: string,
    fileName: string, // 文件夹层级和文件名: 'folder1/folder2/filename.ext'
    permissions = 'r', // 默认只读
    timerange = 1 // 默认1分钟
): Promise<string> => {
    if (!serviceName || !serviceKey || !fileName || !containerName) {
        return 'Generate SAS function missing parameters';
    }

    const blobServiceClient = getBlobServiceClient(serviceName, serviceKey);
    const containerClient = await createContainer(
        containerName,
        blobServiceClient
    );
    const blockBlobClient = await containerClient.getBlockBlobClient(fileName);

    // 最佳实践:设置时间限制
    const SIXTY_MINUTES = timerange * 60 * 1000;
    const NOW = new Date();

    // 创建SAS URL
    const accountSasTokenUrl = await blockBlobClient.generateSasUrl({
        startsOn: NOW,
        expiresOn: new Date(new Date().valueOf() + SIXTY_MINUTES),
        permissions: BlobSASPermissions.parse(permissions), // Blob只读权限
        protocol: SASProtocol.Https // 仅允许HTTPS访问Blob
    });

    return accountSasTokenUrl;
};

我认为错误出在调用createContainer创建容器的环节:

async function createContainer(
    containerName: string,
    blobServiceClient: BlobServiceClient
): Promise<ContainerClient> {
    const containerClient = blobServiceClient.getContainerClient(containerName);
    console.log("containerClient", containerClient);
    await containerClient.createIfNotExists();
    console.log("Container created");

    return containerClient;
}

containerClient已创建,但执行await containerClient.createIfNotExists()时出现错误:

Error: RestError: Server failed to authenticate the request. Please refer to the information in the www-authenticate header.

www-authenticate头信息:

"www-authenticate": "Bearer authorization_uri=https://login.microsoftonline.com/75df096c-8b72-48e4-9b91-cbf79d87ee3a/oauth2/authorize resource_id=https://storage.azure.com",

我参考了微软官方文件上传教程,尝试跳过containerClient.createIfNotExists()但问题仍存在,请问怎么修复这个认证错误?

解决方案
  • 核对存储账户密钥与名称
    确认serviceName是Azure存储账户的完整名称(不含后缀),serviceKey是存储账户的主/次访问密钥(可在Azure门户存储账户的「访问密钥」页面获取),检查是否有复制错误(比如多余空格、特殊字符缺失)。不要使用SAS令牌或Azure AD密钥替代账户访问密钥。

  • 检查存储账户的认证策略
    如果你的存储账户启用了Azure AD强制认证(即禁用了账户密钥访问),使用账户密钥生成SAS会直接失败。此时有两种方案:

    1. 在Azure门户存储账户的「配置」页面,开启「允许使用账户密钥进行访问」;
    2. 改用Azure AD身份验证生成SAS:比如使用服务主体、托管身份获取令牌,再调用生成SAS的接口。
  • 验证容器名称合法性
    Azure存储容器名称必须符合规则:全部小写,只能包含字母、数字、短横线,且短横线不能作为开头或结尾,长度在3-63字符之间。如果containerName不符合规则,可能会触发看似认证错误的异常。

  • 同步服务器时间
    Azure Storage对请求的时间戳有严格要求,若后端服务器时间与UTC时间偏差超过15分钟,会直接拒绝请求并返回认证错误。检查服务器系统时间是否正确,必要时开启自动时间同步。

  • 确认权限参数有效性
    确保permissions参数是BlobSASPermissions支持的字符(比如r读、w写、d删除等),避免传入无效字符导致请求解析失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:58:18