使用Proxy访问Blob时出现403错误的解决方法
Azure Digital Twins 3D场景嵌入React应用时Blob访问403错误
问题背景
尝试将Azure Digital Twins 3D场景嵌入React应用,基于指定仓库实现,通过msal完成Azure租户认证,已按文档创建全部基础设施,但运行应用时访问Blob资源出现403权限错误。添加host条目后问题仍未解决。
错误信息
GET http://localhost:3000/proxy/blob/3ds/3DScenesConfiguration.json?cachebust=1762260419270 403 (This request is not authorized to perform this operation using this permission.)
当前Proxy配置代码
const blobProxy = createProxyMiddleware({ changeOrigin: true, headers: { connection: 'keep-alive' }, secure: true, target: '/', onProxyReq: (proxyReq) => { // Remove all unnecessary headers const newHeaderMap = {}; validHeaders.forEach((header) => { const headerValue = proxyReq.getHeader(header); // eslint-disable-next-line no-undefined if (headerValue !== undefined) { newHeaderMap[header] = headerValue; console.log(headerValue); } }); Object.keys(proxyReq.getHeaders()).forEach((header) => { proxyReq.removeHeader(header); }); Object.keys(newHeaderMap).forEach((header) => { proxyReq.setHeader(header, newHeaderMap[header]); }); }, onProxyRes: (proxyRes) => { Object.keys(proxyResponseHeaders).forEach((header) => { proxyRes.headers[header] = proxyResponseHeaders[header]; }); }, pathRewrite: { '/proxy/blob': '' }, router: (req) => { const blobHost = req.headers['x-blob-host']; const blobHostUrl = `https://${blobHost}/`; const blobHostUrlObject = new URL(blobHostUrl); if ( validBlobHostSuffixes.some((suffix) => blobHostUrlObject.host.endsWith(suffix) ) ) { return blobHostUrl; } throw new Error('Invalid Blob URL'); }, onError: (err, req, res) => { const code = err.code; if (code == 'ECONNRESET') { if ( !req.currentRetryAttempt || req.currentRetryAttempt <= retryNumber ) { req.currentRetryAttempt = req.currentRetryAttempt ? req.currentRetryAttempt++ : 1; console.log( 'Proxy server retry request attempt number: ' + req.currentRetryAttempt ); blobProxy.call(blobProxy, req, res); // resend the original request to proxy middleware again } else { console.log( 'All proxy server retry attempts failed, returning error...' ); res.status(504); res.send(err.message); } } else { switch (code) { case 'ENOTFOUND': case 'ECONNREFUSED': res.status(504); break; default: res.status(500); } res.send(err.message); } } }); app.use('/proxy/blob', (req, res, next) => blobProxy.call(blobProxy, req, res, next) );
排查与解决建议
- 检查Blob存储权限:确认当前认证用户或服务主体拥有
Storage Blob Data Reader角色权限,且已正确分配到目标存储账户或容器级别。 - 验证代理请求头:检查
validHeaders列表是否包含Authorization头,当前代理仅保留该列表内的头,若缺失认证头,转发请求将无权限信息导致403。可打印validHeaders内容确认。 - 确认容器访问级别:若未用Azure AD认证,需检查Blob容器的公共访问级别是否允许读取(生产环境不推荐此方式)。
- 校验
x-blob-host头:在代理router函数中打印blobHost值,确认其为正确的存储账户域名,未被篡改或丢失。 - 检查CORS配置:确认Blob存储账户的CORS规则允许
http://localhost:3000的请求,允许的HTTP方法包含GET,允许的头包含x-blob-host等自定义头。
内容的提问来源于stack exchange,提问作者Ayesh Nipun
相关产品推荐
相关产品推荐

