Manipulation de Directory et File sur un server distant
-
vendredi 29 juin 2012 11:36
Bonjour,
Je suis en train d'adapter un service windows. cet outils réalise des traitements mais aussi des flux de fichiers.
Mon client ayant changé son architecture système. Un des serveur avec lequel le service communique est en dehors du domaine.
Un VPN permanent a été mis en place. J'ai créé les partage sur les répertoires de travail sur le serveur distant.
Le service est installé sur un des serveur du domaine de mon client. quand j'essaie d'atteindre les répertoires partagés du serveur distant via l'explorateur, il me demande une authentification.
Ceci est la source de mon problème puisque toutes les fonctions de manipulation de répertoire et de fichier que j'utilise dans mon service n'implémente pas l'authentification.
Du coup, Directory.Exists par exemple me retourne donc toujours faux.
Ma question est existe t'il des fonctions dans le framework 4 qui permettent des manipulations de fichier/répertoire sur des répertoires distant nécessitant une authentification?
Merci
FB
Toutes les réponses
-
vendredi 29 juin 2012 12:18Modérateur
Bonjour,
Il suffit d'utiliser l'emprunt d'identité (c'est à dire de faire en sorte que le bout de code qui accède à votre répertoire fonctionne sur un compte qui dispose des droits).
Pour cela utilisez la méthode WindowsIdentity.Impersonate(). Voici un article qui explique comment emprunter l'identiter d'un utilisateur dans une application .NET :
Cordialement
Gilles TOURREAU - MVP C#
Architecte logiciel/Consultant/Formateur Freelance
Blog : http://gilles.tourreau.fr
- MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
- MCITP : SQL Server 2008 Developper
- MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 -
vendredi 29 juin 2012 13:13
Dim p As New Process() p.StartInfo.RedirectStandardOutput = False p.StartInfo.FileName = "net" p.StartInfo.Arguments = "use \\10.10.10.10\SharedFolder /USER:Domaine\User Password /PERSISTENT:YES" p.StartInfo.UseShellExecute = True Dim rtn As Boolean = p.Start() If Not rtn Then Throw New Exception("Mappage plante") End If If Directory.Exists("\\10.10.10.10\SharedFolder") Then Log(EventLog_S_CatWeb, "Mappage fait!") Else Log(EventLog_S_CatWeb, "Mappage Marche po!!!") End IfJ'ai essayé ça, tout fonctionne sous winform,
Mais dans le service windows, le process ne plante pas pourtant Directory.Exists retourne encore faux
Je vais voir votre solution
FB
- Modifié FrançoisBOSSANT vendredi 29 juin 2012 13:14
- Modifié FrançoisBOSSANT vendredi 29 juin 2012 13:42
- Modifié FrançoisBOSSANT vendredi 29 juin 2012 13:42
- Modifié FrançoisBOSSANT vendredi 29 juin 2012 13:43
-
vendredi 29 juin 2012 13:41
Il y a quelque chose que je n'arrive pas à comprendre dans votre solution
Instancier une nouvelle "impersonation" revient à changer d'utilisateur courant?
Apres le dispose, revient-on dans le contexte initial? ou doit on se reloguer compte systeme local?
FB
-
vendredi 29 juin 2012 15:39
Imports System.Runtime.InteropServices Imports System.Security.Principal Public Class Impersonation Implements IDisposable <DllImport("advapi32.dll", SetLastError:=True)> _ Private Shared Function LogonUser(lpszUsername As String, lpszDomain As String, lpszPassword As String, dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean End Function Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0 Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2 Public Event Erreur(ByVal MsgErreur As String) Private _impersonationContext As WindowsImpersonationContext Public Sub New(domain As String, login As String, password As String) Try Dim tokenHdle As IntPtr = IntPtr.Zero Dim ret As Boolean = LogonUser(login, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHdle) Dim newIdentity As New WindowsIdentity(tokenHdle) _impersonationContext = newIdentity.Impersonate() Catch e As Exception RaiseEvent Erreur(e.Message) End Try End Sub #Region "IDisposable Membres" Public Overloads Sub Dispose() Implements IDisposable.Dispose _impersonationContext.Undo() End Sub #End Region End ClassBonjour,
A priori, la solution ne fonctionne pas...
au retour de LogonUser, tokenHdle reste à zero et de toute façon ret est à false
FB
- Modifié FrançoisBOSSANT vendredi 29 juin 2012 15:43
-
vendredi 29 juin 2012 15:50Auteur de réponse
Bonjour,
Le lien suivant pourrait vous être utile : http://msdn.microsoft.com/fr-fr/library/b80a7e92.aspx
-
vendredi 29 juin 2012 15:53
Désolé non :)
je l'avais vu, le problème vient de LogonUser
Je n'ai pas positionner les paramètres comme il faut je pense mais l'aide associée ne m'aide pas beaucoup
Dim imp As New Impersonation("", "user@Domaine", "pwd") ... imp.Dispose()FB
-
vendredi 29 juin 2012 16:00Auteur de réponse
Le code suivant pourrait aussi vous être utile :
protected void LogonUser() { IntPtr token = IntPtr.Zero; WindowsImpersonationContext impersonatedUser = null; try { // Create a token for DomainName\Bob // Note: Credentials should be encrypted in configuration file bool result = LogonUser("Bob", "DomainName", "P@ssw0rd", LogonSessionType.Network, LogonProvider.Default, out token); if (result) { WindowsIdentity id = new WindowsIdentity(token); // Begin impersonation impersonatedUser = id.Impersonate(); // Log the new identity Response.Write(String.Format( "</p>Identity after impersonation: {0}<br>", WindowsIdentity.GetCurrent().Name)); // Resource access here uses the impersonated identity } else { Response.Write("</p>LogonUser failed: " + Marshal.GetLastWin32Error().ToString()); } } catch { // Prevent any exceptions that occur while the thread is // impersonating from propagating } finally { // Stop impersonation and revert to the process identity if (impersonatedUser != null) impersonatedUser.Undo(); // Free the token if (token != IntPtr.Zero) CloseHandle(token); }
Cordialement.
-
vendredi 29 juin 2012 16:34
Je ne comprends pas.
LogonUser récursive avec un nombre d'argument différent?
LogonSessionType.Network et LogonProvider.Default sont déclarés comment?
FB
-
vendredi 29 juin 2012 17:28
Voici la classe que j'ai implémentée :
Imports System.Runtime.InteropServices Imports System.Security.Principal Public Class Impersonation Implements IDisposable <DllImport("advapi32.dll", SetLastError:=True)> _ Private Shared Function LogonUser(principal As String, authority As String, password As String, logonType As UInteger, logonProvider As UInteger, ByRef token As IntPtr) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True)> _ Private Shared Function CloseHandle(handle As IntPtr) As Boolean End Function Public Event Erreur(ByVal MsgErreur As String) Private _impersonationContext As WindowsImpersonationContext Public Sub New(domain As String, login As String, password As String) Dim tokenHdle As IntPtr = IntPtr.Zero Try Dim ret As Boolean = LogonUser(login, domain, password, 9, 3, tokenHdle) If ret Then Dim newIdentity As New WindowsIdentity(tokenHdle) _impersonationContext = newIdentity.Impersonate() Else Throw New Exception("Authentification échouée (" & login & ") : " & Marshal.GetLastWin32Error().ToString) End If Catch e As Exception RaiseEvent Erreur(e.Message) Finally If (tokenHdle <> IntPtr.Zero) Then CloseHandle(tokenHdle) End Try End Sub #Region "IDisposable Membres" Public Overloads Sub Dispose() Implements IDisposable.Dispose _impersonationContext.Undo() End Sub #End Region End ClassJe l'exploite ainsi :
Dim imp As New Impersonation(ipserveur, user@domaine, password) If Directory.Exists("\\ipserveur") Then Log(EventLog_S_CatWeb, "Mappage fait!") Else Log(EventLog_S_CatWeb, "Mappage Marche po!!!") End If imp.Dispose()Directory.Exists me retourne false...FB
-
vendredi 29 juin 2012 17:59
Cette fonction ne fonctionne pas dans mon context.
Voici ce que j'ai essayé :
Dim imp As New Impersonation(ipserveur, user@domaine, password) If Directory.Exists("\\ipserveur") Then Log(EventLog_S_CatWeb, "Mappage fait!") Else Log(EventLog_S_CatWeb, "Mappage Marche po!!!") End If imp.Dispose()Et voici ma classe Impersonation :
Imports System.Runtime.InteropServices Imports System.Security.Principal Public Class Impersonation Implements IDisposable <DllImport("advapi32.dll", SetLastError:=True)> _ Private Shared Function LogonUser(principal As String, authority As String, password As String, logonType As UInteger, logonProvider As UInteger, ByRef token As IntPtr) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True)> _ Private Shared Function CloseHandle(handle As IntPtr) As Boolean End Function Public Event Erreur(ByVal MsgErreur As String) Private _impersonationContext As WindowsImpersonationContext Public Sub New(domain As String, login As String, password As String) Dim tokenHdle As IntPtr = IntPtr.Zero Try Dim ret As Boolean = LogonUser(login, domain, password, 9, 3, tokenHdle) If ret Then Dim newIdentity As New WindowsIdentity(tokenHdle) _impersonationContext = newIdentity.Impersonate() Else Throw New Exception("Authentification échouée (" & login & ") : " & Marshal.GetLastWin32Error().ToString) End If Catch e As Exception RaiseEvent Erreur(e.Message) Finally If (tokenHdle <> IntPtr.Zero) Then CloseHandle(tokenHdle) End Try End Sub #Region "IDisposable Membres" Public Overloads Sub Dispose() Implements IDisposable.Dispose _impersonationContext.Undo() End Sub #End Region End ClassLa solution présentée au début avec Net use donnait de meilleur résultat. Au moins elle fonctionnait sous Winform...
FB
-
samedi 7 juillet 2012 13:56
Je n'ai JAMAIS réussi à mettre en place cette solution, je suis repassé à un flux FTPFB
- Marqué comme réponse FrançoisBOSSANT samedi 7 juillet 2012 13:56

