Identitätswechsel für Ordner-Berechtigungen

  • VB.NET
  • .NET (FX) 4.5–4.8

    Identitätswechsel für Ordner-Berechtigungen

    Hallo ^^
    Seit einigen Tagen sitze ich an einem Problem, wo mir scheinbar nur noch eine Kleinigkeit fehlt :/ :

    Mein Wunsch ist es, mein Programm mit einem normalen Benutzer (Benutzer A) ohne Administratorrechte zu starten. Im späteren Verlauf soll eine PDF-Datei in den PDF-Viewer eingebunden werden. Den Windows-Pfad habe ich jedoch nur für einen speziellen Benutzer (Benutzer Z) freigegeben. Der Sinn dahinter ist, dass somit der Benutzer (A) nicht über den Windows-Explorer in diesen Ordner navigieren kann und keine Dateien daraus öffnen, bearbeiten, [...] kann, sondern lediglich auf die Verwaltung der Anwendung angewiesen ist, welche mit den Rechten des extra angelegten Benutzers (Z) auf die Dateien zugreifen kann. Ein "runas" - Skript oder das allgemeine "Ausführen als..." würde mir Probleme machen, da ich die Anwendung bereits über das Kontextmenü ansprechen kann, wodurch Parameter übergeben werden, welche dann verloren gehen würden.

    Bislang habe ich verschiedene Methoden der "Impersonation" versucht, jedoch ohne großen Erfolg. Das Problem ist, dass der Anwendung unter der Benutzung von Benutzer (A) weiterhin der Zugriff verweigert wird.
    Ich lasse mir an verschiedenen Stellen (vor, während und nach) der Impersonation den "aktuellen" Benutzer des Programms ausgeben, welches mir auch bestätigt, dass der Benutzerwechsel normalerweise funktionieren sollte.

    Gibt es da irgendwelche Grenzen bei einer Impersonation oder woran könnte es noch liegen?

    Meine "Impersonation" Class sieht wiefolgt aus:

    VB.NET-Quellcode

    1. Public Class Impersonation
    2. Implements IDisposable
    3. Public Sub New(userName As String, domainName As String, password As String)
    4. 'ImpersonateValidUser(domainName, userName, password)
    5. ImpersonateValidUser(userName, domainName, password)
    6. End Sub
    7. Public Sub Dispose() Implements IDisposable.Dispose
    8. UndoImpersonation()
    9. End Sub
    10. <DllImport("advapi32.dll", SetLastError:=True)> _
    11. Private Shared Function LogonUser(lpszUserName As String, lpszDomain As String, lpszPassword As String, dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As IntPtr) As Integer
    12. End Function
    13. <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    14. Private Shared Function DuplicateToken(hToken As IntPtr, impersonationLevel As Integer, ByRef hNewToken As IntPtr) As Integer
    15. End Function
    16. <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    17. Private Shared Function RevertToSelf() As Boolean
    18. End Function
    19. <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
    20. Private Shared Function CloseHandle(handle As IntPtr) As Boolean
    21. End Function
    22. Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2 'LOGON32_LOGON_INTERACTIVE
    23. Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0
    24. Private Sub ImpersonateValidUser(userName As String, domain As String, password As String)
    25. Dim tempWindowsIdentity As WindowsIdentity = Nothing
    26. Dim token As IntPtr = IntPtr.Zero
    27. Dim tokenDuplicate As IntPtr = IntPtr.Zero
    28. Try
    29. If RevertToSelf() Then
    30. If LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
    31. If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
    32. tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
    33. impersonationContext = tempWindowsIdentity.Impersonate()
    34. Else
    35. Throw New Win32Exception(Marshal.GetLastWin32Error())
    36. End If
    37. Else
    38. Throw New Win32Exception(Marshal.GetLastWin32Error())
    39. End If
    40. Else
    41. Throw New Win32Exception(Marshal.GetLastWin32Error())
    42. End If
    43. Finally
    44. If token <> IntPtr.Zero Then
    45. CloseHandle(token)
    46. End If
    47. If tokenDuplicate <> IntPtr.Zero Then
    48. CloseHandle(tokenDuplicate)
    49. End If
    50. End Try
    51. End Sub
    52. Private Sub UndoImpersonation()
    53. If impersonationContext IsNot Nothing Then
    54. impersonationContext.Undo()
    55. End If
    56. End Sub
    57. Private impersonationContext As WindowsImpersonationContext = Nothing
    58. End Class


    Welche ich über ein simples "Using" anspreche.

    Ich bedanke mich bereits im Voraus für jegliche weitere Anregung und Hilfe :rolleyes: