Domanda

Ho lavorato su un progetto ASP.NET che sta per salvare i file caricati su una condivisione di rete. Ho pensato che avrei potuto semplicemente usare una directory virtuale e stare bene, ma ho avuto difficoltà con le autorizzazioni per Directory.CreateDirectory.

Sono stato in grado di caricare file, quindi ho deciso di modificare il mio codice per posizionare tutto in una singola directory, tuttavia questo mi richiede di utilizzare File.Exists per evitare di sovrascrivere i duplicati.

Ora che ho aggiornato tutto il mio codice, ho scoperto che, indipendentemente da ciò che faccio, File.Exists restituisce sempre false (il file esiste sicuramente) quando eseguo il test con la condivisione di rete.

Qualche idea? Sto arrivando alla fine della mia corda con condivisioni di rete.

È stato utile?

Soluzione

Di recente ho lavorato su un progetto molto simile in cui sto salvando i file su una condivisione di rete. I due computer si trovano sulla stessa sottorete, ma non sono controllati dal controller di dominio, quindi ogni computer ha i propri utenti.

Ho creato un utente con lo stesso nome utente e password su entrambi i computer. Quindi ho creato una condivisione di rete e impostato le autorizzazioni cartella / condivisione per consentire la lettura / scrittura per l'utente.

Ho quindi creato la seguente classe per gestire la rappresentazione:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Text;

namespace MyProject.Business.Web
{
    public class SecurityManager
    {
        #region DLL Imports
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

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

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
        #endregion

        public string Domain { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }

        private WindowsImpersonationContext m_CurrentImpersonationContext;

        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        public void StartImpersonation()
        {
            const int LOGON32_PROVIDER_DEFAULT = 0;
            const int LOGON32_LOGON_INTERACTIVE = 2;

            IntPtr tokenHandle = IntPtr.Zero;
            IntPtr dupeTokenHandle = IntPtr.Zero;

            // obtain a handle to an access token
            bool wasLogonSuccessful = LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);

            if (!wasLogonSuccessful)
                throw new Exception(String.Format("Logon failed with error number {0}", Marshal.GetLastWin32Error()));

            // use the token handle to impersonate the user
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            m_CurrentImpersonationContext = newId.Impersonate();

            // free the tokens
            if (tokenHandle != IntPtr.Zero)
                CloseHandle(tokenHandle);
        }
        public void EndImpersonation()
        {
            m_CurrentImpersonationContext.Undo();
        }
    }
}

Quindi nella pagina ASP.NET ho fatto quanto segue:

SecurityManager sm = new SecurityManager();
sm.UserName = ConfigurationManager.AppSettings["UserFileShareUsername"];
sm.Password = ConfigurationManager.AppSettings["UserFileSharePassword"];
sm.StartImpersonation();

if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);

File.Move(sourcePath, destinationPath);

sm.EndImpersonation();

Altri suggerimenti

File.Exist non controlla effettivamente l'esistenza di un file. Controlla invece l'esistenza di file a cui hai una certa misura di accesso. Se sai che il file esiste, il probabile problema è che non hai accesso ad esso.

Forse il tuo codice in esecuzione (ad esempio il codice del server ASP.NET) è in esecuzione come utente (ad esempio l'utente IIS) che non dispone dell'autorizzazione per accedere a quella condivisione di rete.

Penso che IIS non dovrebbe essere eseguito come utente altamente privilegiato, che per impostazione predefinita ha l'autorizzazione per visualizzare le condivisioni su altre macchine.

Ho usato più o meno lo stesso codice, ma la mia classe ha implementato l'interfaccia IDisposable e ho aggiunto Undo () al metodo Dispose (). Questo codice funziona bene, se sei l'unico sviluppatore che lo utilizza e farai sempre le cose nel modo giusto, giusto?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top