copy files with authentication in c#

前端 未结 4 1950
礼貌的吻别
礼貌的吻别 2020-12-01 09:03

I am trying to copy file from local drive to one of folder on server. name of the folder on server is \'DBFiles\'. No one has got access to this apart from username \'user\'

相关标签:
4条回答
  • 2020-12-01 09:09

    Another option is you can programmaticly access the NET USE api of windows and authenticate to the share like if you went to it in explorer and typed in the credientals.

    public static class NetworkShare
    {
        /// <summary>
        /// Connects to the remote share
        /// </summary>
        /// <returns>Null if successful, otherwise error message.</returns>
        public static string ConnectToShare(string uri, string username, string password)
        {
            //Create netresource and point it at the share
            NETRESOURCE nr = new NETRESOURCE();
            nr.dwType = RESOURCETYPE_DISK;
            nr.lpRemoteName = uri;
    
            //Create the share
            int ret = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null);
    
            //Check for errors
            if (ret == NO_ERROR)
                return null;
            else
                return GetError(ret);
        }
    
        /// <summary>
        /// Remove the share from cache.
        /// </summary>
        /// <returns>Null if successful, otherwise error message.</returns>
        public static string DisconnectFromShare(string uri, bool force)
        {
            //remove the share
            int ret = WNetCancelConnection(uri, force);
    
            //Check for errors
            if (ret == NO_ERROR)
                return null;
            else
                return GetError(ret);
        }
    
        #region P/Invoke Stuff
        [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 WNetCancelConnection(
            string lpName,
            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 = "";
        }
    
        #region Consts
        const int RESOURCETYPE_DISK = 0x00000001;
        const int CONNECT_UPDATE_PROFILE = 0x00000001;
        #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_SESSION_CREDENTIAL_CONFLICT = 1219;
    
        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;
            }
        }
    
        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"), 
            new ErrorClass(ERROR_SESSION_CREDENTIAL_CONFLICT, "Error: Credential Conflict"),
        };
    
        private static string GetError(int errNum)
        {
            foreach (ErrorClass er in ERROR_LIST)
            {
                if (er.num == errNum) return er.message;
            }
            return "Error: Unknown, " + errNum;
        }
        #endregion
    
        #endregion
    }
    

    You use it simply like

    DisconnectFromShare(@"\\server-a\DBFiles", true); //Disconnect in case we are currently connected with our credentials;
    
    ConnectToShare(@"\\server-a\DBFiles", username, password); //Connect with the new credentials
    
    if (!Directory.Exists(@"\\server-a\DBFiles\"))
        Directory.CreateDirectory(@"\\server-a\DBFiles\"+Test);   
    File.Copy("C:\Temp\abc.txt", @"\\server-a\DBFiles\");
    
    DisconnectFromShare(@"\\server-a\DBFiles", false); //Disconnect from the server.
    
    0 讨论(0)
  • 2020-12-01 09:13

    You can use impersonation to change the threads user context:

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
    ...
    LogonUser(userName, domainName, password,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);
    ...
    using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
                {
                    using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
                    {
    
                        // Check the identity.
                        Console.WriteLine("After impersonation: "
                            + WindowsIdentity.GetCurrent().Name);
                        //Do your coping here
                    }
                }
    

    MSDN Sample windowsimpersonationcontext

    0 讨论(0)
  • 2020-12-01 09:19

    I have done this file copy from remote server. please find the code.

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Net;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    namespace IMPolicy
    {
    public partial class ExtractData : System.Web.UI.Page
    {
        [DllImport("advapi32.DLL", SetLastError = true)]
        public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
        protected void Page_Load(object sender, EventArgs e)
        {            
    
            AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
    
            IntPtr token = default(IntPtr);
            if (LogonUser("UserName", "Domain", "Password", 2, 0, ref token) != 0)
            {
    
                WindowsIdentity identity = new WindowsIdentity(token);
                WindowsImpersonationContext context = identity.Impersonate();
    
                try
                {                
                    File.Copy(@"\\\\10.10.38.25\d$\\Sourav\\Draft Report ITC-LRBD_Online Booking Portal_12082016.pdf", @"d:\\Draft Report ITC-LRBD_Online Booking Portal_12082016.pdf", true);
                 }
                 finally
                 {
                     context.Undo();
                 }
            }
    
    
    
    
        }
    
    
      }
    }
    
    0 讨论(0)
  • 2020-12-01 09:25
    NetworkShare.DisconnectFromShare(@"\\server-a\DBFiles", true); //Remove this line
    NetworkShare.ConnectToShare(@"\\server-a\DBFiles", "user1", "password1!"); //Connect with the new credentials
    
    File.Copy(@"c:\temp\T1.txt", @"\\server-a\DBFiles\T1.txt");
    
    NetworkShare.DisconnectFromShare(@"\\server-a\DBFiles", false); //Remove this line also
    

    After 02 days search in Google finally the above worked for me. If you use 'NetworkShare.DisconnectFromShare' after the first login you will get an error as 'Access denied'. Then every time you need to restart the server or need to execute 'net use * /del' command to delete the saved credentials in windows.

    0 讨论(0)
提交回复
热议问题