对我来说,'webClient.UseDefaultCredentials = true;'仅在本地解决它,而不是在连接到另一台服务器的服务器上的 Web 应用程序中解决。我无法以用户身份将所需的凭据添加到 Windows 中,但后来我发现了一些编程方式——我不会对其进行测试,因为我已经制作了自己的解决方案。而且我也不想mangle with the web server's registry,即使我拥有所需的管理员权限。所有这些问题都是由于 Windows 内部处理 NTLM 身份验证(“Windows 域”)以及基于此构建的所有库和框架(例如 .NET)。
所以对我来说,解决方案的想法非常简单 - 使用多平台 NTLM 库在多平台技术中创建代理应用程序,其中 NTLM 通信是根据公共规范手动创建的,而不是通过运行内置代码视窗。我自己选择了 Node.js 和 the httpntlm library,因为它只有一个只有几行的源文件,并从 .NET 作为返回下载文件的程序调用它(我更喜欢通过标准输出传输它而不是创建一个临时文件)文件)。
Node.js 程序作为代理下载 NTLM 身份验证后的文件:
var httpntlm = require('httpntlm'); // https://github.com/SamDecrock/node-http-ntlm
//var fs = require('fs');
var login = 'User';
var password = 'Password';
var domain = 'Domain';
var file = process.argv.slice(2); // file to download as a parameter
httpntlm.get({
url: 'https://server/folder/proxypage.aspx?filename=' + file,
username: login,
password: password,
workstation: '',
domain: domain,
binary: true // don't forget for binary files
}, function (err, res/*ponse*/) {
if (err) {
console.log(err);
} else {
if (res.headers.location) { // in my case, the server redirects to a similar URL,
httpntlm.get({ // now containing the session ID
url: 'https://server' + res.headers.location,
username: login,
password: password,
workstation: '',
domain: domain,
binary: true // don't forget for binary files
}, function (err, res) {
if (err) {
console.log(err);
} else {
//console.log(res.headers);
/*fs.writeFile("434980.png", res.body, function (err) { // test write
if (err) // to binary file
return console.log("Error writing file");
console.log("434980.png saved");
});*/
console.log(res.body.toString('base64')); // didn't find a way to output
} // binary file, toString('binary')
}); // is not enough (docs say it's
// just 'latin1')...
} else { // if there's no redirect
//console.log(res.headers); // ...so I output base64 and
console.log(res.body.toString('base64')); // convert it back in the caller
} // code
}
});
.NET 调用者代码(网络应用从另一台服务器上的网络应用下载文件)
public static string ReadAllText(string path)
{
if (path.StartsWith("http"))
return System.Text.Encoding.Default.GetString(ReadAllBytes(path));
else
return System.IO.File.ReadAllText(path);
}
public static byte[] ReadAllBytes(string path)
{
if (path.StartsWith("http"))
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "node.exe"; // Node.js installs into the PATH
psi.Arguments = "MyProxyDownladProgram.js " +
path.Replace("the base URL before the file name", "");
psi.WorkingDirectory = "C:\\Folder\\With My\\Proxy Download Program";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
Process p = Process.Start(psi);
byte[] output;
try
{
byte[] buffer = new byte[65536];
using (var ms = new MemoryStream())
{
while (true)
{
int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
ms.Write(buffer, 0, read);
}
output = ms.ToArray();
}
p.StandardOutput.Close();
p.WaitForExit(60 * 60 * 1000); // wait up to 60 minutes
if (p.ExitCode != 0)
throw new Exception("Exit code: " + p.ExitCode);
}
finally
{
p.Close();
p.Dispose();
}
// convert the outputted base64-encoded string to binary data
return System.Convert.FromBase64String(System.Text.Encoding.Default.GetString(output));
}
else
{
return System.IO.File.ReadAllBytes(path);
}
}