网站资源加载出现401错误
背景
开发出来的three.js网页部署到客户机后,不能加载obj模型。打开开发工具,除了找不到的模型报错404外,还有一些模型报错401,查看了下IIS下的日志,看到这些报401错误的模型,详细的错误码为401 3 5 0;也就是说报错为401.3 。
根据 IIS 日志中的 401 3 5 0
,关键信息是子状态码 401.3
,表示 访问资源的权限被 ACL(访问控制列表)拒绝。
然,愚已经将网站的文件夹中所有用户设置为了完全控制,但是在某些部署的电脑(单机部署到本地IIS)还是有此问题。
开发环境
win11
vscode
可能原因
移到网站目录下的文件权限可能没有正常继承到网站原始文件夹的相关权限和属性。
之所以怀疑是此问题,因为对网站所在的根目录wwwroot勾选“使用可从此对象继承的权限项目替换所有子对象的权限项目”并应用后,所有资源即可在网页端进行正常加载。
基于上述原因,怀疑很可能是程序运行时移入到网站目录下的文件夹,存在没有将根目录的权限正常继承下来。
于是将移入文件夹同样进行 勾选“使用可从此对象继承的权限项目替换所有子对象的权限项目”并应用 ,测试同样能解决问题。也就验证了之前的猜想。
产生原因
由于当文件/文件夹被 移动(非复制)到NTFS分区 时,默认会 保留原有权限,而不会继承新位置的权限。
也就是说,在C#中使用File.Move移动文件到新的目录时,移入的文件并不会自动继承新目录的权限。
解决办法
既然File.Move移动文件会保留原有权限,文件的移动也许可以通过File.Copy的方式来实现,copy到目标目录后,然后再将原文件删除。
这是因为:复制的新文件会 自动继承目标文件夹的权限,而移动(Move)会保留原权限。
当然,也可以采用Move的方式,只是Move到目标位置后,需要设置一下文件需要继承一下父文件夹的相应权限(此可能需要管理员权限)。
public static class FilePermissionHelper {// 移动文件并继承目标目录权限public static void MoveWithInheritance(string sourcePath, string targetPath){// 1. 移动文件(保留原权限)File.Move(sourcePath, targetPath);// 2. 重置权限继承var targetDir = Path.GetDirectoryName(targetPath);var targetDirAcl = Directory.GetAccessControl(targetDir);// 获取目标目录的权限规则var inheritanceFlags = InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit;var propagationFlags = PropagationFlags.InheritOnly;// 3. 应用继承规则到文件var fileAcl = File.GetAccessControl(targetPath);fileAcl.SetAccessRuleProtection(false, true); // 关闭保护,启用继承File.SetAccessControl(targetPath, fileAcl);}// 备用方法:调用icacls命令(适用于复杂场景)public static void ResetPermissionWithIcacls(string filePath){Process.Start("icacls", $"\"{filePath}\" /reset /t /c").WaitForExit();} }