Verwenden von Secure Store Service in einem benutzerdefinierten Anspruchsanbieter mit SharePoint 2010
Kürzlich habe ich bei der Verwendung von Secure Store Service (SSS) in einem benutzerdefinierten Anspruchsanbieter einen ungewöhnlichen Trick entdeckt. Hierbei handelt es sich um ein interessantes Szenario, da ich – wie viele Benutzer – eine benutzerdefinierte Anspruchserweiterung ausführte. Ich musste eine Verbindung mit einer Remotedatenquelle herstellen, um zusätzliche Informationen zu jedem Benutzer abzufragen und anhand dieser Informationen dann zu entscheiden, welche Ansprüche erweitert werden sollen.
Für die Verwendung von Datenquellen in benutzerdefinierten Anspruchsanbietern sollten Sie unbedingt die allgemeine Richtlinie beachten, dass die benutzerdefinierte Anspruchsanbieterassembly vom SharePoint-STS-Prozess im Arbeitsspeicher beibehalten wird. Das Abrufen von „Informationen“ wird dadurch wesentlich einfacher, unabhängig davon, ob es sich um ein Dataset, einen Satz von Anmeldeinformationen usw. handelt, indem diese in einer Variablen auf Klassenebene gespeichert werden und dann bis zum nächsten IISRESET verfügbar sind. Hierbei gilt jedoch die elementare Einschränkung, dass möglicherweise nicht alle SharePoint-Farmressourcen verfügbar sind, wenn die Klasse für den benutzerdefinierten Anspruchsanbieter instanziiert wird. Und das ist die Moral der heutigen Geschichte.
In diesem speziellen Fall wollte ich Daten aus SSS im Konstruktor für meinen benutzerdefinierten Anspruchsanbieter abrufen und anschließend anderweitig verwenden. Ich erstellte eine WindowsIdentity-Variable von einer Domäne über eine unidirektionale Vertrauensstellung, um damit einen Identitätswechselkontext mit Berechtigungen zum Abfragen der Active Directory-Remoteinstanz einzurichten. Bei Verwendung meines Verweises auf den SSS im Konstruktor trat dann IMMER ein Timeout auf. Es spielte keine Rolle, welche Methode im SSS aufgerufen wurde, nach 60 Sekunden wurde stets ein Timeoutfehler gemeldet.
Um dieses Problem zu beheben, musste der Code einfach aus dem Konstruktor verlagert werden. Derselbe Code funktioniert einwandfrei, wenn er über die Überschreibung der FillClaimsForEntity-Methode aufgerufen wurde. Diese Lösung hatte ich einfach per Zufall und durch Ausprobieren herausgefunden und wollte sie an andere Benutzer weitergeben.
Da wir gerade dabei sind (Anmelden bei einer Remotedomäne und Identitätswechsel), möchte ich noch auf ein Phänomen und einen Tipp dazu hinweisen.
Da die Assembly wie oben beschrieben beim STS-Prozess geladen bleibt, können die Variablen auf Klassenebene beibehalten werden. Da ich mich zum Abfragen nicht wiederholt bei der Remotedomäne anmelden wollte, erstellte ich für WindowsIdentity eine Variable auf Klassenebene. Dazu führte ich die folgenden Schritte aus:
- Überprüfen, ob ich bereits die SSS-Anmeldeinformationen abgerufen habe
- Andernfalls den Code ausführen, der Folgendes bewirkt:
- Abrufen der Anmeldeinformationen aus SSS
- Anmelden in der LogonUser-API bei der Remotedomäne mithilfe der von SSS erhaltenen Anmeldeinformationen
- Instanziieren der WindowsIdentity-Variablen, damit die Anmeldeinformationen des Remotebenutzers vorhanden sind
- Andernfalls den Code ausführen, der Folgendes bewirkt:
- Überprüfen, ob die WindowsIdentity-Variable gleich NULL ist
- Andernfalls den Code ausführen, der Folgendes bewirkt:
- Erstellen einer neuen WindowsImpersonationContext-Instanz von WindowsIdentity.Impersonate()
- Abrufen der Remotedomäne
- Aufrufen von Undo für WindowsImpersonationContext
- Andernfalls den Code ausführen, der Folgendes bewirkt:
Diese Vorgehensweise scheint gut zu funktionieren, mehr Optimierung war jedenfalls bisher nicht möglich. Und hier der Tipp: Rufen Sie Impersonate() NICHT für die WindowsIdentity-Instanz auf, und rufen Sie anschließend NICHT Undo für WindowsImpersonationContext auf. Wenn Sie den Identitätswechsel nicht rückgängig machen, wird die Website meiner Erfahrung nach nicht mehr gerendert. Fügen Sie den Aufruf von Undo wieder hinzu, und alles funktioniert wieder einwandfrei.
Es handelt sich hierbei um einen übersetzten Blogbeitrag. Sie finden den Originalartikel unter Using Secure Store Service in a Custom Claims Provider with SharePoint 2010.