问题
Some background: We currently receive files from multiple data-vendors on a FTP server hosted by our hosting partner. As part of a new project we are setting up an Azure Function. This function runs in a ressource-group that our hosting partner has set up for VPN/private network access. This function is the first step in a process of replacing multiple legacy programs in Excel/VBA with Azure functions.
What we need is to move files from the FTP server to another internal (file-)server (to support some of the legacy programs). The FTP server is in DMZ and therefore not part of the domain like the file-server.
Now I have googled around for hours finding a solution and believe I have found it using https://stackoverflow.com/a/295703/998791 and https://stackoverflow.com/a/1197430/998791
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 = "";
}
}
}
Usage:
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());
}
}
When running this locally it works fine, but running from Azure I get a System.ComponentModel.Win32Exception with the message "Access denied".
I'm not sure wether DllImport is allowed in Azure Functions, if I need FullTrust (I saw something about this somwhere) or if the problem is with the permissions on the server.
Can someone please enlighten me?
回答1:
So a lot of googling resulted in me finding this: Accessing Azure File Storage from Azure Function linking to https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#restricted-outgoing-ports
It states that:
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.
So what we're trying to do is not possible and has nothing to do with DllImport etc. which I guess works just fine if not trying to use SMB.
回答2:
try an App Service or Function App that is not in an 'Isolated' Pricing Tier
来源:https://stackoverflow.com/questions/53008248/c-sharp-accessing-on-premise-network-shares-from-azure-functions-using-credentia