跨网络访问服务器共享路径报Access to path denied错误
跨服务器图片压缩路径访问被拒绝问题排查
问题场景
- 同一内网部署2台独立服务器:服务器A存储全量文档,服务器B运行业务代码,需跨机访问服务器A的文档执行图片压缩操作
报错信息
Access to path denied(路径访问被拒绝)
访问路径:\\ServerName\E$\ClientFiles\SHAH\SHAH_103696_20220531160805_2600.jpg
前置情况
已为目标文件夹及子内容分配完全控制权限,添加Network Service账号并授予完全控制权限,仍触发报错,业务实现代码如下:
public void ImageCompressionStream(ShahImages fileImage) { try { using (WebClient webClient = new WebClient()) { byte[] data = webClient.DownloadData(fileImage.filePath); using (MemoryStream mem = new MemoryStream(data)) { using (var yourImage = Image.FromStream(mem)) { yourImage.Save(fileImage.filePath, ImageFormat.Jpeg); } } } } catch (Exception ex) { } }
核心原因
三个独立问题共同导致报错,和之前配置的文件夹NTFS权限无直接关联:
- 访问路径使用了
E$系统默认管理共享,这类共享的权限独立于磁盘上的NTFS权限配置,默认仅允许目标服务器本地管理员组的账号访问,哪怕给磁盘上的文件夹给了普通账号全权限,走管理共享访问会直接在共享层被拦截,根本到不了NTFS权限校验环节。 - 跨服务器访问时,服务器B上运行的
Network Service账号访问网络资源,默认使用的身份是服务器B的计算机账号(名称格式为服务器B主机名$,账号类型为计算机对象),在服务器A上添加的Network Service是服务器A本地的内置账号,和服务器B过来的访问身份SID完全不匹配,授权根本不生效。 - 代码逻辑存在缺陷:
WebClient下载完文件后没有及时释放持有的网络连接,直接对同一路径执行Save操作时,原文件可能被未释放的连接占用,也会抛出访问拒绝错误;空catch块吞掉了所有异常细节,无法定位具体错误点。
排查解决步骤
- 第一步:替换默认管理共享路径。不要使用
E$这类系统默认隐藏管理共享,在服务器A上单独为ClientFiles文件夹创建自定义命名共享(比如共享名设为ClientFiles),访问路径调整为\\ServerName\ClientFiles\SHAH\xxx.jpg。注意需要同时配置共享层面权限(不是只配置NTFS权限,最终有效权限是共享权限和NTFS权限的交集),给授权账号开读写、修改完全控制权限。 - 第二步:修正跨机访问授权。如果业务程序在服务器B上以
Network Service身份运行,需要在服务器A的共享权限、NTFS权限列表中,添加类型为“计算机”的服务器B机器账号(名称为服务器B主机名$),授予对应读写权限。如果嫌机器账号配置麻烦,可以创建一个两台服务器上用户名、密码完全一致的本地专用账号,或者使用域账号,将服务器B上的业务进程(IIS站点则修改对应应用程序池运行身份)改为该专用账号运行,再在服务器A上给这个账号授予共享和NTFS全权限,稳定性更高。 - 第三步:修复代码逻辑问题。
- 禁止空catch块吞异常,必须在catch中记录完整异常信息(包含错误码、内部异常),方便定位具体错误点
- 下载完文件后及时释放
WebClient持有的连接,避免文件被占用导致写入失败 - 压缩保存时先写入临时文件,写完后再替换原文件,避免写入中途异常导致原文件损坏
修正后参考代码:
public void ImageCompressionStream(ShahImages fileImage) { try { byte[] data; // 下载完成后主动释放WebClient连接 using (WebClient webClient = new WebClient()) { data = webClient.DownloadData(fileImage.filePath); } using (MemoryStream mem = new MemoryStream(data)) { using (var yourImage = Image.FromStream(mem)) { // 先写临时文件再替换,避免占用和文件损坏 string tempPath = fileImage.filePath + ".tmp"; yourImage.Save(tempPath, ImageFormat.Jpeg); if(File.Exists(fileImage.filePath)) File.Delete(fileImage.filePath); File.Move(tempPath, fileImage.filePath); } } } catch (Exception ex) { // 此处必须记录ex.ToString()全量错误日志,禁止留空吞异常 throw; } }
- 第四步:前置权限校验。在服务器B上用和业务进程完全一致的运行账号登录系统,直接在资源管理器输入目标UNC路径,测试是否能正常打开、修改、删除路径内的文件。如果手动操作都报权限错误,说明权限配置未生效,和代码无关;如果手动操作正常、代码运行报错,再排查进程身份匹配、文件占用类问题。
内容的提问来源于stack exchange,提问作者user2147447
相关产品推荐
相关产品推荐

