WCF LiveID Authentication einer Windows 8 Store App – Teil 5

30. Januar 2013

div class=”articleAbstract”>Im letzten Teil der Artikelserie wird der transportgesicherte und authentifizierte Service in Windows Azure gehostet. Das nachfolgende Bild ist somit vollständig umgesetzt.

image

Überblick zur Artikelserie

Teil 1 gibt eine Übersicht über die eingesetzten Technologien und Portale
Teil 2 beschäftigt sich mit der Erzeugung und Konfiguration der Windows 8 Store App mit Live Anmeldung
Teil 3 erzeugt den WCF Service und sichert diesen über SSL ab
Teil 4 autorisiert den angemeldeten Live-Benutzer an den WCF Services
Teil 5 hosted den Service in Windows Azure

Teil 5 – Hosting des WCF Services in Windows Azure

Die nachfolgende Beschreibung basiert auf den Ergebnissen von Teil 1-4 der Artikelserie.
Der bisher nur lokal verfügbare Service wird in Windows Azure gehostet. Das hosten in Windows Azure stellt per se kein Problem dar, der Umgang mit den SSL Zertifikaten erfordert jedoch einige Sorgfalt. Die gute Nachricht ist, dass die bisherige Implementierung ohne Änderung eingesetzt werden kann.
Für das Hosting wird einfach ein neues Cloud Projekt der bestehenden Solution hinzugefügt. Ein Cloud-Projekt selber enthält keinerlei Implementierung, sondern beschreibt die angeforderte Systemkonfiguration für Windows Azure. Los geht`s mit Add New Project => Cloud

image

Das Hosting-Projekt wird zuerst ohne eigene Rolle definiert, es wird keine Rolle ausgewählt.

image

Im Nachgang fügen wir das existierende WCF-Projekt als neue Web Role dem Hosting-Projekt hinzu.
Rechte-Maus auf Roles => Add => Web Role Project in Solution => Auswahl von „WcfService“. Der Service ist somit als WebRole verfügbar.

image

Der WCF-Service kann nun in 2 Varianten gestartet werden. Wird der WCFService direkt gestartet, so hostet weiterhin der IIS-Express den Service. Wird das AzureHosting-Projekt gestartet, so hostet der Windows Azure Emulator den Service in seiner WebRole.
Für die Azure-WebRole muss der Endpoint auf https umgestellt werden. Der Windows Azure Emulator nutzt standardmäßig die URL „127.0.0.1“, sowie das zugehörige Zertifikat mit dem gleichen Namen. Unser bisher für die Entwicklung verwendetes Zertifikat „localhost“ für den IIS-Express wird somit nicht genutzt.

image

Hinweis: Das Zertifikat „127.0.0.1“ könnte man an dieser Stelle analog Teil 3 sowohl im Zertifikatsspeicher der Root-Authority als auch im Client-Manifest eintragen. Damit wäre der SSL-Endpunkt 127.0.0.1 wieder durch den Client erreichbar. Im nachfolgenden wird jedoch alternativ gleich mit einem eigenen Zertifikat gearbeitet.

Zertifikat für Azure bereitstellen

Für Windows Azure wird ein neues Zertifikat benötigt, dessen Name der URL des Dienstes entspricht.
Hierzu sind folgende Schritte durchzuführen

  • Reservierung einer Windows Azure URL
  • Erzeugung des Zertifikats
  • Bereitstellung des Schlüssels (Public und Private) in Windows Azure
  • Bereitstellung des Schlüssels (Private) in der Store App

Die URL wird bei der Reservierung des Cloud-Dienstes angegeben und endet mit „.cloudapp.net“.

image

Dementsprechend muss auch der Name des Zertifikats lauten. In den nachfolgenden Beispielen wird die URL „win8securewcf“ verwendet. Der Name must jeweils durch den gewählten Namen ersetzt werden.
Im ersten Schritte wird ein SelfSigned-Zertifikat auf den Namen der gewählten URL erzeugt. Dabei wird ein Passwort vergeben:

makecert -r -pe -n "CN=win8securewcf.cloudapp.net" -sky 1 "win8securewcf.cloudapp.net.cer" -sv "win8securewcf.cloudapp.net.pvk" -ss My

Das neu generierte Zertifikat wird nun für die SSL Kommunikation genutzt. In den Eigenschaften der Azure Role wird das Zertifikat mit „Add Certificate“ hinzugefügt und kann dabei aus dem Zertifikatsspeicher gewählt werden. Der Name kann wiederrum frei vergeben werden, sollte aber der Einfachheit halber dem gewählten Hostname („win8securewcf“) entsprechen.

image

Jetzt wird dem Endpoint die Nutzung dieses Zertifikats zugewiesen.

image

Im nächsten Schritt muss das Zertifikat selber in der Windows Azure Umgebung hochgeladen werden. Aus dem erzeugten Schlüssel wird ein PFX mit Public und Private Key erzeugt.

pvk2pfx -pvk "win8securewcf.cloudapp.net.pvk" -spc "win8securewcf.cloudapp.net.cer" -pfx "win8securewcf.cloudapp.net.pfx" -pi YourPassword

Im Management Portal wird der Schlüssel zum Cloud-Dienst hinzugefügt. Der Menüpunkt „Zertifikate“ im Portal ermöglicht den Upload der PFX-Datei zu Windows Azure.

Zertifikat dem Client zur Verfügung stellen

Zu guter Letzt wird der Public-Anteil des Zertifikats wieder dem Client zur Verfügung gestellt (siehe Teil 3). Das .cer wird hierfür unter Assets abgelegt und in das App-Projekt eingebunden. Das Zertifikat wird zudem im Manifest als Root-Authority eingetragen.

Nutzung des Azure-Zertifikats im Emulator

Prinzipiell ist die Anwendung fertig und lauffähig. Trotzdem bevorzuge ich immer eine Überprüfung der Konfiguration im lokalen Emulator bevor das Anwendungspaket in die Cloud deployed wird. Die Client-Anwendung kann sich jedoch nicht mit einem lokalen SSL gesicherten Service verbinden, der ein cloudapp.net Zertifikat herausgibt. Mit einem kleinen Trick funktioniert das trotzdem:
Trägt man in der etc/hosts den FQN-Domainnamen als 127.0.0.1 ein, kann die Anwendung lokal mit den generierten Zertifikaten getestet werden.

# Eintrag in der etc/hosts
127.0.0.1 win8securewcf.cloudapp.net

Der WCF Service kann im Azure Emulator unter https://win8securewcf.cloudapp.net:Port ohne Zertifikatsfehler aufgerufen werden. Die Nutzung der neuen Adresse wird für den Client konfiguriert, indem ein neuer Endpunkt dem WCF-Serviceaufruf hinzugefügt wird.

   1: private async void CallWCFButton_Click(object sender, RoutedEventArgs e)

   2: {

   3:     SayHelloServiceClient helloClient = new SayHelloServiceClient(

   4:         SayHelloServiceClient.EndpointConfiguration.SayHelloService);

   5:  

   6:     // Endpunkt für IIS Express (Portnummer bitte anpassen)

   7:     //EndpointAddress ea = new EndpointAddress("https://localhost:44303/SayHelloService.svc");

   8:  

   9:     // Alternativer Endpunkt für Azure (Rechnername und Portnummer bitte anpassen)

  10:     EndpointAddress ea = new EndpointAddress("https://win8securewcf.cloudapp.net:443/SayHelloService.svc");

  11:  

  12:     helloClient.Endpoint.Address = ea;

  13:     if (! String.IsNullOrEmpty(AuthToken))

  14:     {

  15:         JsonWebTokenMin jwt = new JsonWebTokenMin(AuthToken);

  16:         helloClient.ClientCredentials.UserName.UserName = jwt.Claims.UserId;

  17:         helloClient.ClientCredentials.UserName.Password = AuthToken;

  18:     }

  19:     WcfOutput = await helloClient.SayHelloAsync("lieber Benutzer");

  20: }

Finale

Die Azure Anwendung kann nun deployed werden. Für die Nutzung der produktiven Services muss der Eintrag in den etc/hosts wieder entfernt werden, so dass der Name wieder real aufgelöst wird.

Zu guter guter Letzt habe ich mein Ziel erreicht. Ein WCF-Service der in Azure gehostet wird kann sicher durch eine Windows Store App aufgerufen werden. Der Service kann darauf vertrauen, mit einer unmanipulierten Live-UserID zu arbeiten.

Als Entwickler steht man nicht nur vor der Herausforderung die „richtige Implementierung“ zu liefern, sondern man ist auch gezwungen die verschiedensten Portale und Zertifikate korrekt zu konfigurieren. Trotzdem blicke ich mit viel Spaß auf meine wohl längste Hello-World-Implementierung zurück.