Quantcast
Channel: Entwicklung – HanseVision Blog
Viewing all articles
Browse latest Browse all 46

Aus der Praxis – Erstellung eines WCF Web Service für den Zugriff auf SharePoint 2013 – Schritt für Schritt

$
0
0

Mit der Einführung von SharePoint 2013 hat sich an vielen Stellen das beste Vorgehen (“best practice”) für die Entwicklung verändert. In SharePoint 2013 ist so z.B. die Bereitstellung von eigenen Web Services nicht mehr ganz so trivial wie in SharePoint 2010. In der 2010er Version war die Standard-Vorgehensweise, dass eine *.svc bzw. *.asmx Datei per WSP in den SharePoint Ordner “ISAPI” hochgeladen wurde. In einer referenzierten Klasse in einer DLL war die Logik untergebracht. Der Service war dann in jeder Site mit der Url http://yoursite/_vti_bin/hv/yourservice.svc verfügbar.

Das geht zwar technisch auch in SP2013, ist aber nicht mehr Stand der Technik. Viel mehr sollen Eigenentwicklungen aus dem SharePoint herausgehalten werden (soweit möglich). Dazu passend existiert nun der “App”-Ansatz, oder wie Microsoft es nennt: “Think the app way”.

Eine kurze Übersicht zu dem Thema ist hier zu finden:

http://msdn.microsoft.com/en-us/library/jj163114.aspx

In unserem Fall bedeutet dies nun also, dass der Service selbst nicht mehr in SharePoint deployed werden soll. Die Alternative heißt, dass der Service in einer eigenständigen IIS Anwendung gehostet werden muss. Dabei treten nun einige Fragen auf, die in SharePoint 2010 gar nicht berücksichtigt werden mussten, weil sie von SharePoint behandelt wurden:

  • Authentifizierung / Berechtigung
    • welche Authentifizierungsmethode(n) sind nötig?
    • welche Benutzer haben Zugriff?
  • Load Balancing / DNS
    • der neue Service soll natürlich ausfallsicher und einfach aufrufbar sein

Das soll als kleiner Umriss um die Rahmenbedingungen und die Infrastruktur genug sein. Nachfolgend ist ein Beispiel aufgeführt, wie so ein WCF Web Service umgesetzt sein kann.

1. Entwicklung des WCF Service

In Visual Studio 2012 wird eine WCF Service Application erstellt. Darin wird die SharePoint API genutzt, um Informationen aus SharePoint abzurufen. Ein einfacher Code-Schnipsel könnte wie folgt aussehen:

[ServiceContract]
public interface ISP2013Service
{
    [OperationContract]
    string GetSiteTitle();
}

public class SP2013Service : ISP2013Service
{
    public string GetSiteTitle()
    {
        string callingUser = GetIdentity();
        string spAccessUser;
        string title;

        using (SPSite site = new SPSite("https://sharepoint.hansevis05b.dev.hansevision.de"))
        {
            spAccessUser = site.RootWeb.CurrentUser.LoginName;
            title = site.RootWeb.Title;
        }
        return string.Format("{0} {1} {2}", callingUser, spAccessUser, title);
    }
}

Mit diesem Code soll neben dem Title der Root Site auch der Name des Aufrufers der Web Service sowie der beim Zugriff auf SharePoint genutzte Benutzer ausgegeben werden.

Hinweis: An dieser Stelle ein kurzer Hinweis darauf, dass der obige (vereinfachte) Code natürlich wesentlich besser mit dem Client Object Model umgesetzt wäre. Damit ist eine komplette Trennung vom SharePoint möglich. Leider bietet das Client Object Model nicht alle Möglichkeiten, die das Server Object Model bietet. Dieses Umsetzung dient als Beispiel für genau solche Szenarien.

Etwas unschön an dieser Stelle ist nun, dass man den Code nicht einfach aus Visual Studio mit dem Tool “WCFTestClient” testen kann. Grund hierfür ist, dass der WCFTestClient aus Visual Studio heraus nur mit 32 Bit gestartet und auch der Web Service nur als 32 Bit Version gehostet wird. Auf die SharePoint API kann man aber nur aus einer x64 Anwendung zugreifen. Daher muss der Webservice veröffentlicht werden in die in Punkt 2 erstellte Webanwendung.

2. Einrichtung der IIS Webanwendung

Zuerst wird ein eigener Applikationspool eingerichtet, der unter einer Service Dienst Konto läuft. Dieses Konto benötigt Zugriff auf die SharePoint Datenbanken, damit mit Hilfe der SharePoint API auf Inhalte zugegriffen werden kann.

image

Danach wird eine IIS Website erstellt, die auf einen lokalen Ordner gemappt ist.

Dorthin wird der Dienst aus Visual Studio veröffentlicht. Beim Veröffentlichen unbedingt diese Einstellungen berücksichtigen, sonst ist ein Debugging nicht möglich:

image

 

3. Erster Test

Zum Testen des Web Service eignet sich wcftestclient.exe. Einfach über den Visual Studio Command Prompt aufrufen und mit einem neuen Service verbinden.

image

Nach anhängen des Debuggers an den W3WP Prozess (darunter läuft der Web Service) und einem Klick auf den Invoke Button kommt eine “Access is denied” Fehlermeldung:

image

Dies liegt daran, dass bisher in der Web Anwendung der anonyme Zugriff aktiviert ist. Zur Kontrolle des aktuelle angemeldeten Benutzers lässt sich diese Methode hervorragen verwenden:

private const string IdentityClaimType = @"http://schemas.microsoft.com/sharepoint/2009/08/claims/userid";
private static string GetIdentity()
{
    string identityName = String.Empty;
    IClaimsIdentity claimsIdentity = System.Threading.Thread.CurrentPrincipal.Identity as IClaimsIdentity;
    if (claimsIdentity != null)
    {
        // claim
        foreach (Claim claim in claimsIdentity.Claims)
        {
            if (String.Equals(IdentityClaimType, claim.ClaimType, StringComparison.OrdinalIgnoreCase))
            {
                identityName = claim.Value;
                break;
            }
        }
    }
    else
    {
        identityName = System.Threading.Thread.CurrentPrincipal.Identity.Name;
    }

    return identityName;
}

Die Methode liefert in diesem Fall einen leeren String zurück. Das bedeutet, dass kein Nutzen authentifiziert ist- > daher die Fehlermeldung von SharePoint.

Nach der Umstellung auf Windows Authentifizierung kommt man einen Schritt weiter.

image

Beim nächsten Aufruf des Web Service mit dem WCFTestClient wartet aber schon die nächste Fehlermeldung:

image

In der web.config des WCF Service muss nun die Authentifizierungsmethode kontrolliert bzw. angepasst werden:

Standardmäßig sind folgenden Zeilen nicht (oder anders) in der web.config einer WCF Anwendung enthalten, die frisch mit Visual Studio erzeugt wurde. Dieses Beispiel gilt nur für einen http Web Service, nicht für die Verwendung von https.

  <system.serviceModel>
    <services>
      <service behaviorConfiguration="Behavior_HanseVision" name="SP2013Service.SP2013Service">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="Binding_HanseVision" contract="SP2013Service.ISP2013Service">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Behavior_HanseVision">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="Binding_HanseVision">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>

Vor einem erneuten Ausführung des WCFTestClient muss die Service-Verbindung aktualisiert werden, damit die neue Authentifizierungsmethode erkannt wird. Nach dem nächsten Aufruf sollte als Ergebnis der Title der Root Site aus SharePoint zurückgegeben werden (in meinem Beispiel “Zusammenarbeit”). Der aufrufende Benutzer bin ich, der Zugriff auf SharePoint erfolgt aber im Kontext des Application Pool Kontos.

image

 

Als Fazit kann man festhalten, dass durch neuen Ansatz in SharePoint 2013 einige Baustellen für den Entwickler dazukommen, um die man sich unter SharePoint 2010 nicht unbedingt Gedanken machen musste.

 

Im nächsten Artikel wird es darum gehen, den gerade erstellen Web Service aus SharePoint heraus aufzurufen. So können dann bspw. Daten über Webanwendungsgrenzen (oder Farm-Grenzen) hinweg abgerufen werden.


Viewing all articles
Browse latest Browse all 46