- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我们遇到了一个需要解决的有趣情况,但我的搜索没有结果。因此,我向 SO 社区寻求帮助。
问题是这样的:我们需要通过远程文件共享/UNC 以编程方式访问不在我们域中且不在受信任外部域中的共享文件。自然地,我们需要向远程机器提供凭据。
通常,可以通过以下两种方式之一解决此问题:
NET USE
命令或复制 NET USE
的 Win32 函数来完成的。 出于各种各样的原因,我们的安全/网络架构师拒绝了前两种方法。第二种方法显然是一个安全漏洞;如果远程计算机受到威胁,则本地计算机现在也处于危险之中。第一种方法并不令人满意,因为新挂载的驱动器是本地计算机上其他程序在程序访问文件时可用的共享资源。尽管很有可能将此临时化,但在他们看来这仍然是一个漏洞。
他们对第三种选择持开放态度,但远程网络管理员坚持使用 SFTP 而不是 FTPS,而 FtpWebRequest 仅支持 FTPS。 SFTP 是对防火墙更友好的选项,我可以使用几个库来实现这种方法,但如果可以的话,我更愿意减少依赖性。
我在 MSDN 上搜索了使用远程文件共享的托管方式或 win32 方式,但我没有找到任何有用的东西。
所以我问:还有别的办法吗?我错过了一个 super secret 的 win32 函数吗?还是我必须追求选项 3 的某种变体?
最佳答案
解决问题的方法是使用名为 WNetUseConnection 的 Win32 API .
使用此函数通过身份验证连接到 UNC 路径,而不是映射驱动器。
这将允许您连接到远程机器,即使它不在同一个域中,即使它具有不同的用户名和密码。
使用 WNetUseConnection 后,您将能够通过 UNC 路径访问该文件,就好像您在同一域中一样。最好的方法可能是通过管理内置共享。
示例:\\计算机名\c$\program files\Folder\file.txt
下面是一些使用 WNetUseConnection 的示例 C# 代码。
请注意,对于 NetResource,您应该为 lpLocalName 和 lpProvider 传递 null。 dwType 应该是 RESOURCETYPE_DISK。 lpRemoteName 应该是\\ComputerName。
using System;
using System.Runtime.InteropServices ;
using System.Threading;
namespace ExtremeMirror
{
public class PinvokeWindowsNetworking
{
#region Consts
const int RESOURCE_CONNECTED = 0x00000001;
const int RESOURCE_GLOBALNET = 0x00000002;
const int RESOURCE_REMEMBERED = 0x00000003;
const int RESOURCETYPE_ANY = 0x00000000;
const int RESOURCETYPE_DISK = 0x00000001;
const int RESOURCETYPE_PRINT = 0x00000002;
const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000;
const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001;
const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002;
const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003;
const int RESOURCEDISPLAYTYPE_FILE = 0x00000004;
const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005;
const int RESOURCEUSAGE_CONNECTABLE = 0x00000001;
const int RESOURCEUSAGE_CONTAINER = 0x00000002;
const int CONNECT_INTERACTIVE = 0x00000008;
const int CONNECT_PROMPT = 0x00000010;
const int CONNECT_REDIRECT = 0x00000080;
const int CONNECT_UPDATE_PROFILE = 0x00000001;
const int CONNECT_COMMANDLINE = 0x00000800;
const int CONNECT_CMD_SAVECRED = 0x00001000;
const int CONNECT_LOCALDRIVE = 0x00000100;
#endregion
#region Errors
const int NO_ERROR = 0;
const int ERROR_ACCESS_DENIED = 5;
const int ERROR_ALREADY_ASSIGNED = 85;
const int ERROR_BAD_DEVICE = 1200;
const int ERROR_BAD_NET_NAME = 67;
const int ERROR_BAD_PROVIDER = 1204;
const int ERROR_CANCELLED = 1223;
const int ERROR_EXTENDED_ERROR = 1208;
const int ERROR_INVALID_ADDRESS = 487;
const int ERROR_INVALID_PARAMETER = 87;
const int ERROR_INVALID_PASSWORD = 1216;
const int ERROR_MORE_DATA = 234;
const int ERROR_NO_MORE_ITEMS = 259;
const int ERROR_NO_NET_OR_BAD_PATH = 1203;
const int ERROR_NO_NETWORK = 1222;
const int ERROR_BAD_PROFILE = 1206;
const int ERROR_CANNOT_OPEN_PROFILE = 1205;
const int ERROR_DEVICE_IN_USE = 2404;
const int ERROR_NOT_CONNECTED = 2250;
const int ERROR_OPEN_FILES = 2401;
private struct ErrorClass
{
public int num;
public string message;
public ErrorClass(int num, string message)
{
this.num = num;
this.message = message;
}
}
// Created with excel formula:
// ="new ErrorClass("&A1&", """&PROPER(SUBSTITUTE(MID(A1,7,LEN(A1)-6), "_", " "))&"""), "
private static ErrorClass[] ERROR_LIST = new ErrorClass[] {
new ErrorClass(ERROR_ACCESS_DENIED, "Error: Access Denied"),
new ErrorClass(ERROR_ALREADY_ASSIGNED, "Error: Already Assigned"),
new ErrorClass(ERROR_BAD_DEVICE, "Error: Bad Device"),
new ErrorClass(ERROR_BAD_NET_NAME, "Error: Bad Net Name"),
new ErrorClass(ERROR_BAD_PROVIDER, "Error: Bad Provider"),
new ErrorClass(ERROR_CANCELLED, "Error: Cancelled"),
new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"),
new ErrorClass(ERROR_INVALID_ADDRESS, "Error: Invalid Address"),
new ErrorClass(ERROR_INVALID_PARAMETER, "Error: Invalid Parameter"),
new ErrorClass(ERROR_INVALID_PASSWORD, "Error: Invalid Password"),
new ErrorClass(ERROR_MORE_DATA, "Error: More Data"),
new ErrorClass(ERROR_NO_MORE_ITEMS, "Error: No More Items"),
new ErrorClass(ERROR_NO_NET_OR_BAD_PATH, "Error: No Net Or Bad Path"),
new ErrorClass(ERROR_NO_NETWORK, "Error: No Network"),
new ErrorClass(ERROR_BAD_PROFILE, "Error: Bad Profile"),
new ErrorClass(ERROR_CANNOT_OPEN_PROFILE, "Error: Cannot Open Profile"),
new ErrorClass(ERROR_DEVICE_IN_USE, "Error: Device In Use"),
new ErrorClass(ERROR_EXTENDED_ERROR, "Error: Extended Error"),
new ErrorClass(ERROR_NOT_CONNECTED, "Error: Not Connected"),
new ErrorClass(ERROR_OPEN_FILES, "Error: Open Files"),
};
private static string getErrorForNumber(int errNum)
{
foreach (ErrorClass er in ERROR_LIST)
{
if (er.num == errNum) return er.message;
}
return "Error: Unknown, " + errNum;
}
#endregion
[DllImport("Mpr.dll")] private static extern int WNetUseConnection(
IntPtr hwndOwner,
NETRESOURCE lpNetResource,
string lpPassword,
string lpUserID,
int dwFlags,
string lpAccessName,
string lpBufferSize,
string lpResult
);
[DllImport("Mpr.dll")] private static extern int WNetCancelConnection2(
string lpName,
int dwFlags,
bool fForce
);
[StructLayout(LayoutKind.Sequential)] private class NETRESOURCE
{
public int dwScope = 0;
public int dwType = 0;
public int dwDisplayType = 0;
public int dwUsage = 0;
public string lpLocalName = "";
public string lpRemoteName = "";
public string lpComment = "";
public string lpProvider = "";
}
public static string connectToRemote(string remoteUNC, string username, string password)
{
return connectToRemote(remoteUNC, username, password, false);
}
public static string connectToRemote(string remoteUNC, string username, string password, bool promptUser)
{
NETRESOURCE nr = new NETRESOURCE();
nr.dwType = RESOURCETYPE_DISK;
nr.lpRemoteName = remoteUNC;
// nr.lpLocalName = "F:";
int ret;
if (promptUser)
ret = WNetUseConnection(IntPtr.Zero, nr, "", "", CONNECT_INTERACTIVE | CONNECT_PROMPT, null, null, null);
else
ret = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null);
if (ret == NO_ERROR) return null;
return getErrorForNumber(ret);
}
public static string disconnectRemote(string remoteUNC)
{
int ret = WNetCancelConnection2(remoteUNC, CONNECT_UPDATE_PROFILE, false);
if (ret == NO_ERROR) return null;
return getErrorForNumber(ret);
}
}
}
关于c# - 使用凭据从远程、不受信任的域访问共享文件 (UNC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/659013/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!