Question

Je travaille sur un projet ASP.NET qui va enregistrer les fichiers téléchargés sur un partage réseau. J'ai pensé que je pouvais utiliser un répertoire virtuel et que tout allait bien, mais je me débattais avec les autorisations pour Directory.CreateDirectory.

J'ai pu télécharger des fichiers. J'ai donc décidé de modifier mon code afin de tout placer dans un seul répertoire. Toutefois, je dois utiliser File.Exists pour éviter d'écraser les doublons.

Maintenant que tout mon code a été mis à jour, j'ai découvert que quoi que je fasse, File.Exists renvoie toujours false (le fichier existe définitivement) lorsque je teste le partage réseau.

Des idées? J'arrive au bout de ma corde avec des partages réseau.

Était-ce utile?

La solution

Je viens de travailler sur un projet très similaire dans lequel je sauvegarde des fichiers sur un partage réseau. Les deux ordinateurs sont sur le même sous-réseau, mais ne sont pas contrôlés par le contrôleur de domaine. Chaque ordinateur a donc ses propres utilisateurs.

J'ai créé un utilisateur avec le même nom d'utilisateur et le même mot de passe sur les deux ordinateurs. Ensuite, j'ai créé un partage réseau et défini les autorisations de dossier / partage pour permettre la lecture-écriture à l'utilisateur.

J'ai ensuite créé la classe suivante pour gérer l'emprunt d'identité:

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();
        }
    }
}

Dans la page ASP.NET, j’ai fait ce qui suit:

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();

Autres conseils

File.Exist ne vérifie pas réellement l'existence d'un fichier. Au lieu de cela, il vérifie l'existence de fichiers auxquels vous avez accès. Si vous savez que le fichier existe, le problème est probablement que vous n'y avez pas accès.

Votre code en cours d'exécution (code serveur ASP.NET) s'exécute peut-être en tant qu'utilisateur (par exemple, l'utilisateur IIS) qui n'est pas autorisé à accéder à ce partage réseau.

Je pense qu'IIS n'est pas censé être exécuté en tant qu'utilisateur hautement privilégié, qui dispose par défaut de l'autorisation d'afficher les partages sur d'autres machines.

J'ai utilisé à peu près le même code, mais ma classe a implémenté l'interface IDisposable et ajouté l'Undo () à la méthode Dispose (). Ce code fonctionne bien, si vous êtes le seul développeur à l’utiliser et que vous ferez toujours les choses de la bonne manière, non?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top