Laden...

Impersonate() und Datenbankzugriff über Enterprise Library

Erstellt von tkrasinger vor 14 Jahren Letzter Beitrag vor 13 Jahren 3.003 Views
T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 14 Jahren
Impersonate() und Datenbankzugriff über Enterprise Library

Ich hab derzeit große Schwierigkeiten bei einem Windows Service das WCF Services hosted:

Wenn ich das Service starte, was wiederum die WCF Services startet und dann einen Aufruf an eine WCF-Methode mache, welche Daten aus der DB holt, bekomme ich den Fehler dass sich der User {DomainName}{MachineName}$ nicht am (remoten) Datenbank-Server anmelden kann.
Ich geh stark davon aus, das Service versucht mit dem lokalen System Konto (mit dem der Dienst gestartet wurde) gegen die DB zu gehen, was natürlich auf einen Remote-DB-Server nicht mehr geht.

Also mach ich um den Datenbank-Call eine Impersonierung:

using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
{ 
    //DB-call
}

In WindowsIdentity.Name steht mein Username.

Bei der Impersonierung habe ich nun festgestellt, dass ich in diesem Abschnitt über keinerlei Rechte mehr verfüge. Ich kann keine Dateien lesen, schreiben oder sonst irgendwas. Was auch dazuführt, dass ich in diesem Abschnitt keine Assemblies mehr nachladen kann, weil ich eben keinen Zugriff auf die Platte habe.

Beim Aufruf meiner Stored Procedure krieg ich nun folgende Exception:

System.TypeInitializationException: The type initializer for 'System.Data.SqlClient.SqlConnection' threw an exception.
-> System.TypeInitializationException: The type initializer for 'System.Data.SqlClient.SqlConnectionFactory' threw an exception.
-> System.TypeInitializationException: The type initializer for 'System.Data.SqlClient.SqlPerformanceCounters' threw an exception.
-> System.Security.SecurityException: Requested registry access is not allowed.
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name)
at System.Diagnostics.PerformanceCounterLib.FindCustomCategory(String category, PerformanceCounterCategoryType& categoryType)
at System.Diagnostics.PerformanceCounterLib.IsCustomCategory(String machine, String category)
at System.Diagnostics.PerformanceCounter.Initialize()
at System.Diagnostics.PerformanceCounter.set_RawValue(Int64 value)
at System.Data.ProviderBase.DbConnectionPoolCounters.Counter..ctor(String categoryName, String instanceName, String counterName, PerformanceCounterType counterType)
at System.Data.ProviderBase.DbConnectionPoolCounters..ctor(String categoryName, String categoryHelp)
at System.Data.SqlClient.SqlPerformanceCounters..ctor()
at System.Data.SqlClient.SqlPerformanceCounters..cctor()
The Zone of the assembly that failed was:
MyComputer
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlConnectionFactory..cctor()
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlConnection..cctor()
--- End of inner exception stack trace ---

Ich denke, dass ich beim Impersonieren irgendwas falsch mache. Mir kommt das irgendwie spanisch vor, dass ich, wenn ich mich mit meinem User impersoniere, gar keine Rechte mehr habe etwas zu tun. Mein Problem ist leider auch, dass ich nach der Impersonierung nicht mehr feststellen kann, welcher User nun tatsächlich aktiv ist, weil ich einfach keine Möglichkeit finde, irgendwie etwas zu loggen (da ich ja keine Rechte auf die Platte habe) oder irgendwie mit der Umwelt zu kommunizieren.

Kann mir hier bitte jemand erklären, was ich falsch mache oder was ich machen muss, damit ich zur DB komme?

Danke

J
1.114 Beiträge seit 2007
vor 14 Jahren

Du hast noch 2 Alternativen:*Du kannst den Dienst unter einem anderen Konto laufen lassen *Du kannst du User/Password Anmeldung am SQL Server nutzen, statt dich auf Windows Identies zu berufen. Da der Serverprozess ja normalerweise auf einer Kiste läuft, auf der die User keinen Zugriff haben, sehe ich keine Bedenken, den Usernamen und Passort dort in einer Config abzulegen. Es ist bei dir ja scheinbar so, dass WCF Service und SQL Server auf dem gleichen Rechner laufen, oder?

T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 14 Jahren

Leider kann ich keiner der Alternativen zustimmen. Ich brauche die Impersonierung da sich jeder Benutzer mit seiner WindowsIdentity am Dienst -> WCFService -> DB anmelden soll, damit ich in der DB dann auch die Benutzernamen ermitteln kann (z.b. für Spalte ChangedBy).

Daher kann ich weder den Dienst unter einem bestimmen Konto laufen lassen, noch irgendwelche User in die Configs eintragen.

Der Dienst/WCF Service laufen natürlich nicht am selben Rechner.

3.511 Beiträge seit 2005
vor 13 Jahren

Hallo,

ich grab den Thread mal aus, da ich gerade genau vor dem selben Problem stehe. Hast du damals noch eine Lösung gefunden?

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 13 Jahren

Für dieses Konkrete Problem der Impersonierung nicht. Aber mein Ziel mit den WCF-Services habe ich mittlerweile über die Attribute
[OperationBehavior(Impersonation = ImpersonationOption.Required)]

bzw. dem Gegenstück am Client:

....ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

erreicht, damit wird die aktuelle Identity vom Client über das Service bis zur Datenbank getragen.