How to Upload a File to Network File Share with Credentials using C# (.NET Core)

Jun 27, 2024ยท

2 min read

Sometimes, we need to write a file to a Windows shared network path from a C# web application so others can use it. In my case, the shared file will be used by a PowerBI report. Using the WindowsIdentity.RunImpersonated method, the following code opens the network shared path using the given credentials and copy the file.

Complete source code to copy files to network file share in windows:

using System.Runtime.InteropServices;
using System.Security.Principal;

var sourceFilePath = "";
var destinationFilePath = "";
var username = "";
var domain = "";
var password = "";

try
{
    Console.WriteLine("File uploaded started at {0}.",DateTime.Now);
    ImpersonateAndCopyFile(domain, username, password, sourceFilePath, destinationFilePath);
    Console.WriteLine("File uploaded completed successfully at {0}.",DateTime.Now);
}
catch (Exception ex)
{
    Console.WriteLine($"An error occurred: {ex.Message}");
}

static void ImpersonateAndCopyFile(string domain, string username, string password, string sourceFilePath,
    string destinationFilePath)
{
    var userToken = IntPtr.Zero;

    try
    {
        var isSuccess = LogonUser(username, domain, password, 2, 0, ref userToken);
        if (!isSuccess)
        {
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        }

        using WindowsIdentity identity = new WindowsIdentity(userToken);
        WindowsIdentity.RunImpersonated(identity.AccessToken, () =>
        {
            File.Copy(sourceFilePath, destinationFilePath, true);
        });
    }
    finally
    {
        if (userToken != IntPtr.Zero)
        {
            CloseHandle(userToken);
        }
    }
}

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool LogonUser(
    string lpszUsername,
    string lpszDomain,
    string lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool CloseHandle(IntPtr handle);

What the above code is doing?

  1. LogonUser: A P/Invoke call to the LogonUser function to log a user onto the local computer. This function is used to obtain a user token.

  2. CloseHandle: A P/Invoke call to the CloseHandle function to close the user token handle.

  3. ImpersonateAndCopyFile Method:

    • Uses LogonUser to obtain a user token with the specified credentials.

    • Creates a WindowsIdentity object with the obtained token.

    • Uses WindowsIdentity.RunImpersonated to run the file copy operation under the context of the impersonated user.

    • Ensures the user token is closed after use.

  4. Main Method:

    • Calls ImpersonateAndCopyFile with the domain, username, password, source file path, and destination file path.

    • Catches and prints any exceptions.

Important notes:

  • This approach relies on LogonUser and WindowsIdentity to perform user impersonation, which is required to access network shares with different credentials.

  • This code works only on Windows systems and requires appropriate permissions to perform impersonation and access the network share.