Share via


Toolkit für die Integration von Forderungen, Azure und SharePoint - Teil 2

Toolkit für die Integration von Forderungen, Azure und SharePoint - Teil 2

Dies ist Teil 2 einer fünfteiligen Serie zum CASI Kit (Claims, Azure and SharePoint Integration, Integration von Forderungen, Azure und SharePoint). Teil 1 ist eine einführende Übersicht über das gesamte Framework und die Lösung. Es wird erläutert, welche Themen in der Serie behandelt und abgedeckt werden. Der Schwerpunkt in diesem Beitrag liegt auf dem Muster für diesen Ansatz:

1. Verwenden einer benutzerdefinierten WCF-Anwendung als Front-End für Daten und Inhalt

2. Festlegen der Unterstützung für Forderungen

3. Vornehmen weiterer Änderungen zum Verschieben der Anwendung in die Windows Azure-Cloud

Verwenden von WCF

Die oberste Prämisse des CASI Kit-Frameworks besteht darin, dass von allen Anwendungsdaten eine WCF-Anwendung als Front-End verwendet wird. Wie alle benutzerdefinierten Anwendungen handelt es sich hierbei um ein Element, das von Ihnen als Entwickler erstellt werden muss. Es sind praktisch keine SharePoint-spezifischen Kenntnisse für diesen Teil des Projekts erforderlich. Jeder .NET-Entwickler, der Visual Studio zum Erstellen einer WCF-Anwendung verwenden kann, kann diese Aufgabe ausführen. Wenn Sie diesen WCF-Dienst schließlich in Windows Azure hosten möchten, dann empfehle ich Ihnen die Verwendung des Windows Azure Development Kits zum Herunterladen der Vorlagen, mit denen Azure-Anwendungen erstellt werden können. So können Sie von Anfang an eine Azure-WCF-Anwendung erstellen. Es gibt jedoch eine wichtige Einschränkung in der aktuellen Version des CASI Kits, die Ihnen bekannt sein sollte und daher hier erwähnt wird. Das CASI Kit unterstützt nur das Senden der gängigen .NET-Datentypen als Parameter an WCF-Methoden. Daher können Werte vom Datentyp string, bool, int und date problemlos verwendet werden. Es gibt jedoch keine Methode für das Übergeben einer benutzerdefinierten Klasse als Parameter. Wenn Sie jedoch genau dies tun müssen, empfehle ich Ihnen das Erstellen des Parameters als Zeichenfolge und das Deserialisieren des Parameters zu XML, bevor Sie die WCF-Methode aufrufen. Anschließend können Sie den Parameter dann wieder in eine Objektinstanz im WCF-Code serialisieren. Neben diesem Aspekt sind mir bisher jedoch keine weiteren wichtigen Einschränkungen aufgefallen. Aber ich bin mir sicher, dass sich schon bald eine Liste mit Wünschen bilden wird, wenn dieser Ansatz weiter verbreitet ist und öfter verwendet wird. Als kurze Randnotiz sei erwähnt, dass das aktuelle Kit tatsächlich nur meine Version 1.0-Ideen zu der Frage darstellt, wie diese ganzen Elemente zusammengefügt werden können. Dabei sollen die gängigen Szenarien behandelt werden, die mir eingefallen sind und die ich für wichtig halte. Ich hege keinen Zweifel daran, dass es noch viel Raum für Verbesserungen gibt, wenn die Leute das Kit erst einmal verwenden.

Festlegen der Unterstützung für Forderungen

Wenn die WCF-Anwendung erstellt worden ist, muss im nächsten Schritt die Unterstützung für Forderungen festgelegt werden. Für diesen Schritt gilt der Dank nicht mir: ich verweise da nur auf den exzellenten vierteiligen Blogbeitrag, den Eric White vom Office-Team verfasst hat, um die Integration von Forderungen aus SharePoint in eine WCF-Anwendung zu beschreiben. Wenn Sie den WCF-Dienst bereits erstellt haben, sollten Sie mit Teil 2 von Erics Blogserie beginnen: https://blogs.msdn.com/b/ericwhite/archive/2010/05/13/determining-caller-identity-within-a-wcf-web-service.aspx. Darüber hinaus MÜSSEN Sie auch die Schritte ausführen, die in Teil 3 erläutert werden: https://blogs.msdn.com/b/ericwhite/archive/2010/06/18/establishing-trust-between-a-wcf-web-service-and-the-sharepoint-2010-security-token-service.aspx Starten Sie im Abschnitt mit dem Titel Procedure: Establish Trust between the Web Service and the SharePoint Server. Von da an müssen Sie alle weiteren Schritte ausführen, d. h. Sie kopieren den Fingerabdruck des SharePoint-STS-Tokensignaturzertifikats und kopieren ihn zusammen mit einigen anderen Informationen in die Datei web.config der WCF-Anwendung. Ich empfehle nicht die Ausführung aller SSL-Schritte in Teil 3, da die Verwendung eines selbstsignierten Zertifikats nicht wirklich Sinn macht, wenn die Anwendung in Windows Azure gehostet wird. Falls Ihnen kein anderes Zertifikat zur Verfügung steht, müssen Sie diese Schritte ausführen. Im Allgemeinen sollten Sie jedoch ein ordnungsgemäßes SSL-Zertifikat von einer entsprechenden Zertifizierungsstelle für die WCF-Anwendung in Windows Azure erwerben. HINWEIS: Sie müssen die Schritte in Teil 4 von Erics Block NICHT ausführen. Wenn Sie nun die oben beschriebenen Schritte ausgeführt haben, besitzen Sie eine funktionsfähige WCF-Anwendung, die SharePoint-Forderungen unterstützt. Im letzten Teil dieses Beitrags führe ich Sie durch weitere Schritte, die Sie ausführen müssen, um die Anwendung in Windows Azure zu verschieben.

Vorbereiten auf die Verwendung in Windows Azure

Nachdem Sie nun über eine funktionsfähige WCF-Azure-Anwendung verfügen, müssen noch einige andere Aufgaben erfüllt werden, damit die Anwendung die forderungsbasierte Authentifizierung und Token über das Windows Identity Framework (WIF) unterstützt und sie in der Windows Azure-Cloud gehostet werden kann. Hier ist die Liste der Aufgaben:

1. Konfigurieren Sie das WebRole-Projekt (d. h. das WCF-Projekt) zur Verwendung eines lokalen virtuellen Verzeichnisses für das Debuggen. Ich finde, dass die Arbeit hiermit viel einfacher ist als mit dem VS.NET-Entwicklungsserver, was Aufgaben wie die Verwendung von Zertifikaten betrifft. Diese Aufgaben werden Sie gewiss ausführen. Wenn Sie dies ändern möchten, doppelklicken Sie auf die Eigenschaften des WebRole-Projekts, und klicken Sie dann auf die Registerkarte Web. Wählen Sie die Optionsschaltfläche zur Verwendung des lokalen IIS-Webservers aus, und klicken Sie dann auf die Schaltfläche zum Erstellen eines virtuellen Verzeichnisses. Wenn das virtuelle Verzeichnis erstellt wurde, können Sie die Projekteigenschaften schließen.

2. Fügen Sie dem WebRole-Projekt einen Verweis auf Microsoft.Identity hinzu. Sie MÜSSEN den Verweis auf Copy Local = true und Specific Version = false ändern. Dies ist erforderlich, um die WIF-Assembly zusammen mit dem Anwendungspaket in die Cloud zu kopieren.

3. Rufen Sie dieses WCF-Hotfix ab: https://code.msdn.microsoft.com/KB981002/Release/ProjectReleases.aspx?ReleaseId=4009 für Win2k8 R2, https://code.msdn.microsoft.com/KB971842/Release/ProjectReleases.aspx?ReleaseId=3228 für Win2k8.

4. Sie MÜSSEN dieses Attribut der WCF-Klasse hinzufügen: [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)] . Die Klasse sieht dann beispielsweise wie folgt aus:

namespace CustomersWCF_WebRole

{

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

    public class Customers : ICustomers

    {

5. Sie MÜSSEN die folgenden Konfigurationsdaten in das vom Dienst verwendete behavior-Element einschließen. Dadurch werden Probleme gelöst, die mit der Zuweisung zufälliger Portnummern in der Azure-Umgebung auftreten können. Für einen lokalen Test benötigen Sie das unter 3. beschriebene Hotfix:

      <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

Es folgt ein Beispiel im Kontext der Datei web.config für den WCF-Dienst:

    <behaviors>

      <serviceBehaviors>

        <behavior name="CustomersWCF_WebRole.CustomersBehavior">

          <federatedServiceHostConfiguration name="CustomersWCF_WebRole.Customers"/>

          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

          <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

        </behavior>

      </serviceBehaviors>

    </behaviors>

6. Laden Sie zunächst das SSL-Zertifikat, das Sie für die WCF-Anwendung verwenden, in das Azure-Entwicklerportal hoch. HINWEIS: Die CASI Kit-Basisklasse ist so programmiert, dass SSL verwendet wird, sodass Sie in der WCF-Windows Azure-Anwendung die Unterstützung für SSL implementieren MÜSSEN. Dies sollte eine erwartete Anforderung an das Weitergeben von potenziell vertraulichen Daten zwischen einem Clouddienst und der SharePoint-Farm sein. Fügen Sie dann das Zertifikat den Azure-Rolleneigenschaften in Visual Studio hinzu, indem Sie auf den Namen des WebRole-Projekts (im Roles-Ordner) doppelklicken. Ich habe die Erfahrung gemacht, dass die Verwendung eines Platzhalterzertifikats problemlos funktioniert. Sie benötigen jedoch ein PFX-Zertifikat, und stellen Sie sicher, dass Sie alle Zertifikate in der Kette exportieren, wenn Sie die PFX-Datei erstellen. Alle Zertifikate werden beim Laden der Datei in das Entwicklerportal von Azure erweitert.

7. Das SSL-Zertifikat sollte für someName.yourDnsName.com gelten, auch wenn alle Azure-Anwendungen unter cloudapp.net gehostet werden. Bei meinem SSL-Zertifikat handelt es sich beispielsweise um ein Platzhalterzertifikat für *.vbtoys.com. In DNS habe ich einen neuen CNAME-Datensatz mit dem Namen azurewcf.vbtoys.com erstellt, und er enthielt einen Verweis auf myAzureApp.cloudapp.net. Wenn ich also eine Verbindung mit https://azurewcf.vbtoys.com herstelle, funktioniert mein Zertifikat, da meine Anforderung und das SSL-Zertifikat für *.vbtoys.com gelten, meine Anforderung wird jedoch von DNS auf der Grundlage des CNAME-Datensatzes umgeleitet, und der lautet myAzureApp.cloudapp.net.

8. Doppelklicken Sie im Azure-Projekt auf den Namen des WebRole-Projekts (im Roles-Ordner), und legen Sie diese Eigenschaften wie folgt fest:

a. Registerkarte Configuration: Deaktivieren Sie den Launch-Browser für: HTTP- und HTTPS-Endpunkt

b. Registerkarte Certificates: Fügen Sie das Zertifikat hinzu, das Sie für SSL mit dem Dienst verwenden möchten. In meiner Testumgebung verwende ich beispielsweise ein Platzhalterzertifikat, das von meiner Domäne für alle meine Webserver ausgegeben wird, also habe ich an dieser Stelle mein Platzhalterzertifikat hinzugefügt.

c. Registerkarte Endpoints: Aktivieren Sie das Feld sowohl für HTTP als auch für HTTPS (die Namen sollten entsprechend HttpIn und HttpsIn lauten). Im HTTPS-Abschnitt sollte das Dropdownmenü für den SSL-Zertifikatnamen nun das von Ihnen in Schritt b hinzugefügte SSL-Zertifikat enthalten.

9. Falls Sie eine WCF-Methode verwenden, die ein Skript zurückgibt, muss das Skripttag das DEFER-Attribut enthalten, damit es ordnungsgemäß verwendet werden kann, wenn das im CASI Kit enthaltene Webpart verwendet wird bzw. wenn Ihre eigene JavaScript-Funktion es zum innerHTML-Teil eines Tags hinzufügt. Das Skripttag sollte beispielsweise wie folgt aussehen: <script defer language='javascript'>

10. Falls Sie eine WCF-Methode verwenden, die Inhalt mit anderen Formatierungstags zurückgibt, z. B. <style> , müssen Sie diese in ein <pre> -Tag einschließen, sonst werden sie nicht ordnungsgemäß verarbeitet, wenn das im CASI Kit enthaltene Webpart verwendet wird bzw. wenn Ihre eigene JavaScript-Funktion es zum innerHTML-Teil eines Tags hinzufügt. Der Inhalt, den Sie mit einem style-Tag zurückgeben, könnte z. B. so aussehen: <pre><style>.foo {font-size:8pt;}</style></pre>

Dies sind die Schritte, die zum Konfigurieren der WCF-Anwendung erforderlich sind, damit diese in Azure gehostet werden kann. Es folgen einige weitere Tipps, die hilfreich oder abhängig von Ihrer Implementierung erforderlich sein können:

1. Verwenden Sie den vollqualifizierten Namen beim Erstellen der Endpunktadresse, die den Dienst verwendet. Ein Beispiel ist machineName.foo.com anstelle von machineName. Dies wird sauberer in das abschließende auf Windows Azure gehostete Format übersetzt. Zudem können dadurch Fehler vermieden werden, die auftreten können, wenn das SSL-Zertifikat für die Verwendung eines vollqualifizierten Domänennamens entworfen wurde.

2. MÖGLICHERWEISE möchten Sie dieses Attribut: httpsGetEnabled="true" diesem Element hinzufügen: <serviceMetadata httpGetEnabled="true" /> , wenn Sie WSDL über SSL abrufen möchten. Es gibt jedoch zurzeit einen Programmfehler in SharePoint Designer, durch den die Verwendung von SSL für WSDL verhindert wird.

3. Weitere Tipps zum Debuggen und zu Datenverbindungen finden Sie in meinem Beitrag unter https://blogs.technet.com/b/speschka/archive/2010/09/19/azure-development-tips-for-debugging-and-connection-strings.aspx.

4. In den meisten Fällen können Sie voraussetzen, dass der WCF-Dienstnamespace https://tempuri.org lauten wird. Anweisungen zum Ändern dieser Einstellung finden Sie im Beitrag unter https://blogs.infosupport.com/blogs/edwinw/archive/2008/07/20/WCF_3A00_-namespaces-in-WSDL.aspx.

Der fertig gestellte WCF-Dienst

Falls Sie alle oben genannten Konfigurationsschritte ausgeführt und die WCF-Anwendung in Windows Azure bereitgestellt haben, erhalten Sie, wenn ein Benutzer diesen WCF-Dienst über eine SharePoint-Website aufruft, das gesamte Benutzertoken des Benutzers mit allen zugeordneten Forderungen. Beachten Sie darüber hinaus, dass nach Durchführung dieser Änderungen der WCF-Dienst vor Ort funktioniert. Sie können ihn also auf einfache Art und Weise testen, wenn Sie einige inkrementelle Änderungen testen möchten, bevor die Anwendung in die Cloud hochgeladen wird. Wenn Sie diesen Benutzertoken besitzen, können Sie einige sehr interessante Dinge im WCF-Dienst anstellen. Sie können beispielsweise innerhalb des WCF-Diensts alle Benutzerforderungen aufzählen und auf dieser Grundlage Entscheidungen zu einer weiteren Differenzierung der Berechtigungen treffen. Es folgt ein Beispiel für die Verwendung von LINQ für eine Gruppe von Benutzerforderungen, wodurch bestimmt wird, ob der aktuelle Benutzer ein Administrator ist. Wenn dies der Fall ist, wird eine zusätzliche Ebene mit Daten in der Anforderung zurückgegeben:

//look for the claims identity

IClaimsIdentity ci =

System.Threading.Thread.CurrentPrincipal.Identity as IClaimsIdentity;

if (ci != null)

{

//see if there are claims present before running through this

       if (ci.Claims.Count > 0)

       {

       //look for a group claim of domain admin

var eClaim = from Microsoft.IdentityModel.Claims.Claim c in ci.Claims

              where c.ClaimType ==

"https://schemas.microsoft.com/ws/2008/06/identity/claims/role" &&

                     c.Value == "Domain Admins"

                     select c;

              //see if we got a match

              if (eClaim.Count() > 0)

              //there’s a match so this user has the Domain Admins claim

                     //do something here

}

}

Genauso cool ist, dass Sie Berechtigungsanforderungen direkt in den WCF-Methoden festlegen können. Angenommen, Sie besitzen eine WCF-Methode, die einen Datenspeicher abfragt und eine Liste der Kunden-CEOs zurückgibt. Diese Informationen sollen nicht für alle Mitarbeiter verfügbar sein, sondern nur für die Manager des Vertriebs. Eine sehr elegante und einfache Möglichkeit, dies zu implementieren, besteht darin, eine PrincipalPermission-Anforderung in der Methode wie folgt festzulegen:

//the customer CEO list should not be shared with everyone,

//so only show it to people in the Sales Manager role

[PrincipalPermission(SecurityAction.Demand, Role = "Sales Managers")]

public string GetCustomerCEOs()

{

//your code goes here

}

Wenn nun ein Benutzer diese Methode aufrufen möchte und keine Forderung für Sales Managers besitzt, dann wird der Zugriff verweigert, falls Code ausgeführt wird, der diese Methode aufzurufen versucht. Sehr cool!

Beachten Sie, dass hier kein Spoofing möglich ist. Sie können z. B. eine eigene Domäne in einer Testumgebung erstellen, ihr ein Konto hinzufügen und eine Rolle Sales Manager erstellen, der Sie dieses Konto hinzufügen. Der Grund dafür, dass dies nicht funktioniert, liegt in den zurückliegenden Schritten, die Sie bei Verwendung des Blogs von Eric White ausgeführt haben (im Abschnitt oben mit dem Titel „Festlegen der Unterstützung für Forderungen“). Erinnern wir uns, dass Sie den Fingerabdruck des von SharePoint-STS verwendeten Tokensignaturzertifikats hinzugefügt haben. Dies bedeutet, dass beim Auftreten einer Forderung in der WCF-Anwendung danach gesucht wird, ob das Token vom öffentlichen Schlüssel von SharePoint-STS signiert ist. Nur SharePoint-STS kann es mit diesem öffentlichen Schlüssel signieren, da dies die einzige Entität ist, die den privaten Schlüssel für dieses Tokensignaturzertifikat besitzt. Dadurch wird sichergestellt, dass nur ein Benutzer, der in dieser SharePoint-Farm authentifiziert wurde, den WCF-Dienst verwenden kann. Und Benutzer besitzen nur die Forderungen, die ihnen zum Zeitpunkt der Anmeldung erteilt wurden. Ebenfalls interessant ist hierbei, dass nicht nur Forderungen eingeschlossen sind, die den Benutzern bei der Authentifizierung in ihrem Benutzerverzeichnis erteilt wurden, sondern AUCH alle zusätzlichen Forderungen, die über die Forderungserweiterung in SharePoint mit benutzerdefinierten Forderungsanbietern erteilt wurden. Es handelt sich also um eine tatsächlich durchgängig integrierte Lösung.

Nächste Schritte

Im nächsten Beitrag beginne ich mit der Beschreibung der benutzerdefinierten Basisklasse und des Webparts, das im CASI Kit enthalten ist und Ihnen das rasche und einfache Herstellen einer Verbindung mit Ihrer neuen Azure-WCF-Anwendung ermöglicht. Von da an werde ich einen WCF-Dienst verwenden, den ich für das CASI Kit geschrieben habe, um die Funktionalität zu demonstrieren. Ich füge dem Beitrag die CS-Datei an, die ich für diesen Dienst verwendet habe. Die Datei ist für Sie nicht sofort einsetzbar, ich habe sie jedoch hinzugefügt, um die verschiedenen Methoden zu zeigen, die darin enthalten sind. Auch möchte ich den darin enthaltenen Typ von Daten zeigen und vorführen, wie bestimmte Features für dieses Kit implementiert wurden. Hauptsächlich sehen Sie in den folgenden Beiträgen, wie ich die Methoden a) GetAllCustomersHtml, b) GetCustomerCEOs und c) GetAllCustomers verwende. Diese sind interessant, da sie a) HTML zurückgeben (das de facto der bevorzugte Rückgabetyp für die Anzeige von Daten in Webparts ist), b) eine PrincipalPermission-Anforderung verwenden und c) zeigen, wie Sie einen benutzerdefinierten Klassentyp aus der WCF-Anwendung zurückgeben und denselben umfassenden Klassentyp verwenden können, nachdem diese Daten mit dem CASI Kit wieder zurück zu SharePoint gegeben wurden.

Es handelt sich hierbei um einen übersetzten Blogbeitrag. Sie finden den Originalartikel unter The Claims, Azure and SharePoint Integration Toolkit Part 2