C# 使用凭据从 azure 函数访问本地网络共享
C# Accessing on-premise network shares from azure functions using credentials
一些背景:
目前,我们在托管合作伙伴托管的 FTP 服务器上接收来自多个数据供应商的文件。作为新项目的一部分,我们正在设置 Azure Functions。此功能在我们的托管合作伙伴为 VPN/private 网络访问设置的资源组中运行。此函数是将 Excel/VBA 中的多个遗留程序替换为 Azure 函数的过程的第一步。
我们需要将文件从 FTP 服务器移动到另一个内部(文件)服务器(以支持一些遗留程序)。 FTP 服务器位于 DMZ 中,因此不像文件服务器那样属于域的一部分。
现在我已经用谷歌搜索了几个小时来寻找解决方案,并且相信我已经使用 and
找到了它
public sealed class NetworkConnection : IDisposable
{
private string _uncShare;
public NetworkConnection(string uncShare, NetworkCredential credentials)
{
var nr = new Native.NETRESOURCE
{
dwType = Native.RESOURCETYPE_DISK,
lpRemoteName = uncShare
};
var userName = string.IsNullOrEmpty(credentials.Domain) ? credentials.UserName : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);
int result = Native.WNetUseConnection(IntPtr.Zero, nr, credentials.Password, userName, 0, null, null, null);
if (result != Native.NO_ERROR)
{
throw new Win32Exception(result);
}
_uncShare = uncShare;
}
public void Dispose()
{
if (!string.IsNullOrEmpty(_uncShare))
{
Native.WNetCancelConnection2(_uncShare, Native.CONNECT_UPDATE_PROFILE, false);
_uncShare = null;
}
}
private class Native
{
public const int RESOURCETYPE_DISK = 0x00000001;
public const int CONNECT_UPDATE_PROFILE = 0x00000001;
public const int NO_ERROR = 0;
[DllImport("mpr.dll")]
public static extern int WNetUseConnection(IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID,
int dwFlags, string lpAccessName, string lpBufferSize, string lpResult);
[DllImport("mpr.dll")]
public static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce);
[StructLayout(LayoutKind.Sequential)]
public 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 = "";
}
}
}
用法:
using (new NetworkConnection(ftpServerSettings.UNCPath, new NetworkCredential(ftpServerSettings.UserName, ftpServerSettings.Password, ftpServerSettings.Domain)))
{
using (new NetworkConnection(fileServerSettings.UNCPath, new NetworkCredential(fileServerSettings.UserName, fileServerSettings.Password, fileServerSettings.Domain)))
{
handler.HandleFolders(bankDataRepository.GetFolderSettings());
}
}
当 运行 这在本地工作正常时,但是 运行 从 Azure 我得到一个 System.ComponentModel.Win32Exception 消息 "Access denied".
我不确定 Azure Functions 是否允许 DllImport,我是否需要 FullTrust(我在某处看到了一些关于这个的信息)或者问题是否出在服务器的权限上。
谁能赐教吗?
经过大量谷歌搜索,我发现了这个:
链接到 https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#restricted-outgoing-ports
它指出:
Restricted Outgoing Ports
Regardless of address, applications cannot connect to anywhere using ports 445, 137, 138, and 139. In other words, even if connecting to a non-private IP address or the address of a virtual network, connections to ports 445, 137, 138, and 139 are not permitted.
所以我们尝试做的事情是不可能的,并且与 DllImport 等无关。如果不尝试使用 SMB,我想它工作得很好。
尝试不在'Isolated'定价层
中的应用服务或功能应用
一些背景: 目前,我们在托管合作伙伴托管的 FTP 服务器上接收来自多个数据供应商的文件。作为新项目的一部分,我们正在设置 Azure Functions。此功能在我们的托管合作伙伴为 VPN/private 网络访问设置的资源组中运行。此函数是将 Excel/VBA 中的多个遗留程序替换为 Azure 函数的过程的第一步。
我们需要将文件从 FTP 服务器移动到另一个内部(文件)服务器(以支持一些遗留程序)。 FTP 服务器位于 DMZ 中,因此不像文件服务器那样属于域的一部分。
现在我已经用谷歌搜索了几个小时来寻找解决方案,并且相信我已经使用 and
找到了它public sealed class NetworkConnection : IDisposable
{
private string _uncShare;
public NetworkConnection(string uncShare, NetworkCredential credentials)
{
var nr = new Native.NETRESOURCE
{
dwType = Native.RESOURCETYPE_DISK,
lpRemoteName = uncShare
};
var userName = string.IsNullOrEmpty(credentials.Domain) ? credentials.UserName : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);
int result = Native.WNetUseConnection(IntPtr.Zero, nr, credentials.Password, userName, 0, null, null, null);
if (result != Native.NO_ERROR)
{
throw new Win32Exception(result);
}
_uncShare = uncShare;
}
public void Dispose()
{
if (!string.IsNullOrEmpty(_uncShare))
{
Native.WNetCancelConnection2(_uncShare, Native.CONNECT_UPDATE_PROFILE, false);
_uncShare = null;
}
}
private class Native
{
public const int RESOURCETYPE_DISK = 0x00000001;
public const int CONNECT_UPDATE_PROFILE = 0x00000001;
public const int NO_ERROR = 0;
[DllImport("mpr.dll")]
public static extern int WNetUseConnection(IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID,
int dwFlags, string lpAccessName, string lpBufferSize, string lpResult);
[DllImport("mpr.dll")]
public static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce);
[StructLayout(LayoutKind.Sequential)]
public 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 = "";
}
}
}
用法:
using (new NetworkConnection(ftpServerSettings.UNCPath, new NetworkCredential(ftpServerSettings.UserName, ftpServerSettings.Password, ftpServerSettings.Domain)))
{
using (new NetworkConnection(fileServerSettings.UNCPath, new NetworkCredential(fileServerSettings.UserName, fileServerSettings.Password, fileServerSettings.Domain)))
{
handler.HandleFolders(bankDataRepository.GetFolderSettings());
}
}
当 运行 这在本地工作正常时,但是 运行 从 Azure 我得到一个 System.ComponentModel.Win32Exception 消息 "Access denied".
我不确定 Azure Functions 是否允许 DllImport,我是否需要 FullTrust(我在某处看到了一些关于这个的信息)或者问题是否出在服务器的权限上。
谁能赐教吗?
经过大量谷歌搜索,我发现了这个:
它指出:
Restricted Outgoing Ports Regardless of address, applications cannot connect to anywhere using ports 445, 137, 138, and 139. In other words, even if connecting to a non-private IP address or the address of a virtual network, connections to ports 445, 137, 138, and 139 are not permitted.
所以我们尝试做的事情是不可能的,并且与 DllImport 等无关。如果不尝试使用 SMB,我想它工作得很好。
尝试不在'Isolated'定价层
中的应用服务或功能应用