以下是缩写版本:
我有一个在 IIS 下运行的 dot net 应用程序。当我执行File.Move(local file, remote share file)
Move 时,它不会发生,并且会出现 SMB 错误“Security Blob: <MISSING> NO DATA”错误。
File.Move() 没有返回(它挂起了),我不得不使用 Wireshark 获取错误。
我用运行从 dotnet 执行的 ROBOCOPY 的 .bat 脚本替换了 File.Move()。它也挂了。但我可以在命令行上运行 bat 脚本,它会复制文件。
我使用whoami
bat 脚本来确认完全相同的用户正在执行它,而不管启动了 .bat 脚本的是什么。
我确信 IIS 为 fileio 添加了一个“秘密”安全层。我想知道如何克服这个问题。
我有一个从不在域内的服务器(192.168.2.1)共享的文件夹。
我们就称之为\\\192.168.2.1\PropDocsLib
。
我想从域中另一台服务器(newwebserver)上的 IIS 下运行的 dot.net 程序访问该共享文件夹。
如果我使用 NewWebServer 中的 Windows 资源管理器,我可以访问该共享,但当我使用IIS时,共享中的文件不可见。我在代码中使用了各种不同的调用(File.Exists()
、、),但文件不可见。FileSystem.Rename()
File.Move()
每个调用都会挂起,好像正在等待凭证。
我还编写了一个 .bat 脚本来执行 ROBOCOPY。如果我在命令行上运行该脚本,它可以正常工作,但如果在 IIS 下执行它,它会挂在 ROBOCOPY 上。
我现在正尝试使用 IIS 中的 VirtualDirectories 来让我能够从 IIS 访问共享。这段简介似乎暗示这是可能的:
当我尝试配置 VD 时,我看到以下内容:
如何输入另一台机器的凭据(它不在域内)?
当我尝试 192.168.2.1\Administrator 时,我输入了错误的密码。
关于此屏幕上的设置还有其他提示吗?我找不到有关每个功能的文件:
[编辑] 我可以使用 Windows 资源管理器Webserver\Administrator
和密码连接到共享,但是当尝试使用虚拟目录连接到它时,我得到了以下信息:
[编辑] 我们尝试以 .\Administrator 身份运行池,并将驱动器 (X:、Y: 和 Z:) 映射到我们尝试使用的共享。我们可以在以 .\Administrator 身份登录时使用 Windows 资源管理器访问这些驱动器。但 IIS 不允许我们访问它们。
[编辑] 我们使用 Wireshark 查看尝试访问共享时引发的确切错误:
其中重要的部分是“安全 Blob::无数据”。
这指引我们:扩展安全认证。
我将添加 SMB 标签并希望有人能看到它。
答案1
这有点像是瞎猜,但有一点可能性,即应用程序池内的文件操作在通过网络读取时出于某种原因需要本地用户配置文件。在应用程序池高级设置中,尝试设置 Load User Profile = true。这会增加对所有特殊文件夹的访问权限,这些文件夹可能需要帮助传输数据,例如 %appdata%,等等。网络协议在传输数据时可能需要这样做,也许这就是为什么它可以通过 Windows 资源管理器工作,但不能通过 IIS 应用程序池工作的原因。
答案2
确保您使用的是最新版本的 SAMBA。
创建虚拟目录时,您可以使用“连接为...”按钮来设置“直通身份验证”。
按下该按钮可以将“路径凭证”设置为以下两个选项之一:
- 特定用户:指定的本地帐户
- 应用程序用户(传递身份验证):使用应用程序池身份
第二个选项是默认选项,但可能无法通过网络工作。您需要使用第一个选项并指定一个有权通过网络访问指定远程共享的帐户。
您还可以将应用程序池标识更改为可以访问网络的应用程序池标识。
请小心使用仅对真正需要使用的文件夹具有本地权限的帐户。
为了使用 RunAs 另一个帐户运行 robocopy 等命令,避免需要交互地输入密码,一种解决方案是使用 运行方式 您可以使用它来调用需要密码的程序,其中密码和其他详细信息由 RunAsSpc 保存在加密数据库中。RunAsSpc 可免费供个人使用。
有关使用它的更多详细信息,请参阅文章 使用 RunAsSpc 将密码传递给 Runas。
在 IIS 中编程访问外部计算机时,您可以暂时将 IIS 使用的用户帐户更改为有权访问网络的帐户,然后恢复为 IIS 的原始 IUSR 帐户。
对于我来说,这个解决方案总是完美无缺的。它最大的缺点是需要在 IIS 中使用纯文本形式的用户名和密码,可以通过以加密格式存储它们来避免这种情况,仅在使用时解密。
使用 C 或任何可以调用 Windows API 函数的语言,您可以使用 ImpersonateLoggedOnUser 函数 更改附加到当前 IIS 实例的帐户令牌,并将其恢复。