Jürgen Gutsch: HSTS auf einer Azure Web App erzwingen

Das ist ein Nachtrag zu dem Beitrag HTTPS auf einer Azure Web App erzwingen.

Was ist HSTS?

Bei HSTS (HTTP Strict Transport Security) handelt es sich um eine Technik um einen Browser zu zwingen eine Web-Applikation / Website nur mir HTTPS aufzurufen.

Dabei wird ein weiterer HTTP Header vom Server an den Browser gesendet, der diesen Mitteilt, dass die aktuelle Domain (und ggf. Sub-Domains) für einen bestimmten Zeitraum nur per HTTPS aufgerufen werden soll und nicht per HTTP.

Das heißt, wenn ein User die URL ohne HTTPS eingibt, weiß der Browser dass er dennoch mit HTTPS aufrufen soll. Das gilt auch für Aufrufe aus den Bookmarks heraus. Das heißt, die angefragte Website muss in dem angegebenen Zeitraum zwingend mit HTTPS aufgerufen werden. Sollte das nicht der Fall sein (durch eine Man-in-the-Middle-Attake) soll der Browser eine Fehlermeldungen anzeigen und es darf nicht auf die Website zugegriffen werden.

Diese Technik wurde bereits Ende 2012 als RFC 6797 vom IETF veröffentlicht. Scheinbar stammen die ersten Ideen dazu allerdings schon von 2010, bzw. 2009. Allerdings wurde das Thema leider erst jetzt in den letzten Monaten aktuell und nach und nach in den Browsern verbaut.

Der HSTS-Header könnte wie folgt aussehen:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Mit zum Beispiel diesem Header wird der Cache für ein Jahr und für alle Subdomains vorgehalten. Allerdings ist ein Jahr wohl etwas zu lang und wenn man die Gültigkeit von Zertifikaten berücksichtigt und Konflikte vermeiden möchte, sollte man den Zeitraum wohl kürzer wählen. Genauso macht “includeSubDomains” nur Sinn, wenn es sich um ein WildCard-Zertifikat handelt, dass für alle Sub-Domains gültig ist.

Im Moment unterstützen alle neuen Browser HSTS, der IE erst ab Version 12. Microsoft Edge soll HSTS ebenfalls unterstützen. Browser die HSTS nicht unterstützen ignorieren den Header und fahren aber nicht unsicherer als mit bisherigen HTTPS Anfragen.

Wie einrichten?

Die OWASP nennt eine weitere Variante über ein Open Source IIS Module, die ich nicht getestet habe.

Wie auch im letzten Beitrag zum Thema HTTPS, kann die Einstellung auch in den Rewrite Rules in der Web.Config vorgenommen werden. Das heißt, auch diesmal ist es nicht nur für Azure sondern für alle IIS machbar:

<rewrite>
  <rules>
    <rule name="HTTPS_301_Redirect" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="^OFF$" />
        <add input="{SERVER_NAME}" matchType="Pattern" pattern="^localhost$" negate="true" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
    </rule>
  </rules>
  <outboundRules>
    <rule name="Add_HSTS_Header" preCondition="USING_HTTPS" patternSyntax="Wildcard">
      <match serverVariable="RESPONSE_Strict-Transport-Security" pattern="*" />
      <action type="Rewrite" value="max-age=31536000" />
    </rule>
    <preConditions>
      <preCondition name="USING_HTTPS">
        <add input="{HTTPS}" pattern="^ON$" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>

Hier wird wie im letzten Beitrag ein permanentes Redirect auf HTTPS gemacht und in den outboundRules wird der HSTS-Header gesetzt, wenn es sich um eine HTTPS Verbindung handelt.

Die OWASP beschreibt HATS auf folgender Seite: https://www.owasp.org/index.php/HTTP_Strict_Transport_Security

Fabian Deitelhoff: LEGO Mindstorms EV3: Ferienworkshop bei der VHS Unna

Letzte Woche, genauer gesagt vom 22. Juni bis 26. Juni, fand endlich der verschobene Ferienworkshop bei der VHS Unna statt. Ursprünglich geplant in den Osterferien, musste ich den Kurs leider aufgrund einer Erkältung verschieben. Jetzt konnte er endlich stattfinden und bot, täglich von circa 16:00 Uhr bis 19:15 Uhr, wieder eine Menge Action und Spaß rund um den LEGO Mindstorms EV3.

Wer sich bei der Auflistung und Beschreibung der Tage wundert, warum es nur vier sind: der Donnerstag war nicht eingeplant, da dieser Tag einfach zu sehr mit meinen Vorlesungen an der Fachhochschule Dortmund kollidiert.

Tag 1

Der erste Tag fing etwas langsamer und gemächlicher an. Zwei Teilnehmer haben zunächst ein größeres LEGO EV3 Modell gebaut, das sie in den nächsten Tagen verwenden wollten. Anschießend gab es von mir eine kleine Einführung, die aber tatsächlich sehr knapp ausfiel, da so gut wie alle Teilnehmer schon mal etwas mit dem EV3 gemacht hatten. Als erste Sensoren waren der Infrarot- und der Farbsensor an der Reihe. Letzterer für einen kurzen Test auch schon für eine Linienverfolgung.

Tag 2

Am zweiten Tag nahm die Geschwindigkeit zu. Ich habe zum ersten Mal in einem Kurs eine Vorlage auf DIN A1 für eine Linienverfolgung mitgebracht. Die kam auch gut an und hat viele herausgefordert. :) Zusätzlich sind mir bei den Tests viele Verbesserungen für weitere Vorlagen eingefallen. Im Grunde haben alle fleißig Linienfolger und weitere Ideen gebaut und programmiert. Ich selber konnte eine sehr einfache Version, eine einfache Version mit Mittelwert und einen P-Controller als Linienfolger implementieren und ausprobieren.

Tag 3

Am dritten Tag kam dann die NXT-Vorlage für Linien hinzu. Eine zweite Vorlage, die ich zum Druckdienstleister gegeben hatte, war leider noch noch nicht fertig. Jetzt konnte ich auch endlich einmal einen PID-Controller für die Linienverfolgung implementieren und testen. Auch alle anderen haben fleißig weitere Programme geschrieben. Besonders der Infrarot- und der Ultraschallsensor kamen viel zum Einsatz, um Wände und andere Hindernisse zu entdecken und rechtzeitig auszuweichen.

Auch der Geräuschsensor des NXT, den ein Teilnehmer mitgebracht hatte, konnte erfolgreich am EV3 getestet werden. Nebenbei konnte ich auch kurz Mono.Brick testen, was ebenfalls ohne Probleme funktionierte.

Tag 4

Am vierten und letzten Tag haben wir versucht die zweite Vorlage, die ich mitgebracht hatte, zu nutzen. Allerdings waren die Linien darauf etwas zu schmal beziehungsweise die Kurven einfach nicht groß genug. Alle Modelle hatten an bestimmten Stellen Probleme. Auch der PID-Controller hatte keine Chance. Eine weitere Möglichkeit wäre, den Farbsensor näher an die Achsen zu platzieren. Allerdings muss ich trotzdem die Vorlage etwas überarbeiten. In diesem Fall war sie DIN A0, was allerdings eine sehr gute Größe ist, weil sie viel Platz für weitere Ideen bietet. Nur der Rundkurs in Form einer schwarzen Linie muss etwas anders aussehen.

Um den Farbsensor noch etwas weiter auszutesten, wurden Roboter konstruiert, die nicht vom Tisch fallen durften, in dem sie das Ende des Tisches erkennen konnten.

Fazit

Ich hoffe, es hat allen viel Spaß bereitet. So wie ich das mitbekommen habe, was das wohl der Fall. Mir hat es, wie immer, absolut viel Spaß gemacht. Die Teilnehmer waren sehr gut drauf und haben wunderbar mitgemacht. Auch an eigenen Ideen hat es nicht gemangelt. Ganz im Gegenteil. Ich habe noch nie eine Gruppe erlebt, die so lebendig dabei war und eigene Ideen eingebracht und auch umgesetzt hat. Vielen Dank dafür an alle!

Die nächsten Kursen sind im September in Dortmund und im Oktober wieder in Unna.

codefest.at [MS]: Visual Studio 2015: Onlineevent zum Release

Save the date

Am 20. Juli um 17 Uhr 30 ist es soweit – wir feiern die Verfügbarkeit von Visual Studio 2015!

Um einen Einblick in die finale Version zu bekommen veranstalten wir einen Onlineevent der die neuen Funktionen, erweiterten Möglichkeiten und die neu gestaltete Produktfamilie vorstellt.

In Visual Studio 2015 hat sich viel getan:

  • Visual Studio 2015 ist die Entwicklungsumgebung für Windows 10 und Windows 10 Universal Apps
  • das neue Visual Studio 2015 Enterprise mit MSDN für Entwickler in Unternehmen (alle bisherigen aktiven Visual Studio Premium mit MSDN und Ultimate mit MSDN Benutzer können auf diese Edition kostenlos umsteigen)
  • Mobile x-Plattform Entwicklung neu definiert (nativ & Web)
  • Umsetzung von IoT Szenarien
  • Wir lieben Web-Entwickler (nutzen Sie Visual Studio wie Sie sind – mit Ihren Werkzeugen & Frameworks)
  • Entwicklung von Cloud-Apps
  • neues plattformübergreifendes Build-System (Visual Studio Online, Team Foundation Server 2015)
  • Application Insights (gewinnen Sie mehr Einblick in Ihre Applikationen) & IntelliTest (Unit-Tests automatisiert erstellen)
  • .. und vieles mehr

Sven Hubert: Das neue Azure Portal

Marco Scheel: Links for 2015-06-29 [del.icio.us]

Jürgen Gutsch: HTTP Sniffer Part 6: Der komplette Sniffer in der Übersicht

Inhalt

Der Sniffer in der Übersicht:

Folgende CodeMap zeigt die Abhängigkeiten der wichtigsten Komponenten:

Classes

Hier ist zu sehen, wie eine Komponente nach der anderen abgearbeitet wird. Die Komponenten rufen sich nacheinander auf. Den ganzen Weg über wird der ClientStream – der NetworkStream zwischen Browser und unserem Proxy – von einer Komponente zur nächsten mitgegeben, damit die letzte im der Kette die Daten vom RemoteStream – der NetworkStream zwischen Proxy und entfernten Server – direkt an den Browser gesendet werden können.

Folgendes Flussdiagram veranschaulicht die einfache Kommunikation im Falle einer HTTP-Verbindung:

HTTP

Wie bereits im letzten Teil beschrieben ist die Kommunikation im Falle einer HTTPS Verbindung etwas komplexer. Wir müssen zuerst eine saubere HTTPS-Verbindung mit dem Client aufbauen, damit es auf dem Browser nicht zu unschönen Meldungen kommt, außerdem verlangt der Browser nach einer sicheren Verbindung. Anschließend müssen die Antworten auch wieder verschlüsselt an den Client übertragen werden. Dafür müssen die entsprechenden Zertifikate erstellt und registriert werden:

 

HTTPS

Es ist nicht viel Code, der für einen einfachen Proxy wie diesen nötig ist. Allerdings enthält er außer Logging noch keine weiteren Funktionen, sondern gibt die Daten direkt weiter.

Um eine wirkungsvolle Kinderschutzsoftware mit diesem Proxy zu generieren, müssen einige konfigurierbare Filter implementiert werden, wie z. B: URL-Filter, Schlagwortfilter, eventuell Bilder- und Video-Filter.

Neue Standards wie HTTP/2, dessen Neuerungen, sowie HSTS sind ebenfalls noch nicht berücksichtigt. Ich kann mit vorstellen, das HTTP/2 und HSTS genau solche Szenarien erschweren soll. Dieser Proxy muss nun also noch kompatibel zu den neuen Standards gemacht werden.

Wer in den aktuelle Code schauen möchte kann das nun endlich unter https://github.com/JuergenGutsch/async-proxy tun. Der Proxy ist unter MIT Lizenz gestellt. Wer möchte darf sich an der Weiterentwicklung beteiligen. Ich freue mich über jeden PullRequest :) Das Ziel soll sein, eine freie Kinderschutzsoftware und/oder einen Sniffer für Entwicklungszwecke wie eben Fiddler zu erstellen.

Johnny Graber: MEAP: Wenn es einmal ganz lange dauert

MEAP - Manning Early Access Program

MEAP - Manning Early Access Program

Seit rund 6 Jahren bin ich ein regelmässiger Kunde des Early Access Program von Manning (kurz MEAP). Mit dieses Programm kann man Bücher lesen die noch in der Entstehung sind. Was komisch tönt macht gerade bei neuen Technologien Sinn, da es dort oft an guter Dokumentation fehlt. Wie einfach man bei diesem Programm mitmachen kann hatte ich schon hier beschrieben.

Unfertige Bücher können auch einmal nicht erscheinen. Dies trat bei mir bisher nur bei einer Bestellung ein und wurde durch Manning vorbildlich gelöst.

 

Gute Dinge brauchen Zeit

Seit heute kann ich nun über ein weiteres Kapitel berichten. Es kann durchaus vorkommen, dass ein Buch erst mit einigen Jahren Verspätung erscheint. So erhielt ich heute die gedruckte Ausgabe von „Groovy in Action, Second Edition“. Dies wäre nicht der Rede wert, wenn ich mich noch an die Bestellung erinnern könnte. Ein Blick ins Mailarchiv lieferte mir als Bestelldatum den 29. Dezember 2009.

Von der Bestellung bis zur Auslieferung sind demnach ganze 5.5 Jahre vergangen. In dieser Zeit konnte ich dank der elektronischen Formate (PDF und Mobi) zahlreiche Versionen lesen. Dass der Weg zum fertigen Buch noch so lange sein wird hätte ich mir 2009 allerdings nicht vorstellen können.

 

Fazit

Solch lange Wartezeiten hatte ich bisher noch nie erlebt. Trotz dieser neuen Erfahrung finde ich MEAP noch immer eine gute Idee. Der Vorteil dieser Programme liegt allerdings klar im Bereich der elektronischen Formate und weniger bei den gedruckten Ausgaben.

Wenn neue Versionen automatisch an den eigenen Kindle übertragen werden, hat man immer die neuste Version zur Hand und kann mit dieser Arbeiten, ganz unabhängig davon wann das Buch schlussendlich gedruckt wird.


Einsortiert unter:Bücher Tagged: .Net, Bücher, Java, Lernen

codefest.at [MS]: Kostenkontrolle mit Azure Billing API (Preview)

Ganz neu und frisch gibt es seit wenigen Tagen eine Azure Billing API. Enterprise Agreement Kunden haben ja eine eigene Verwaltung ihrer Subscriptions im Microsoft Azure - EA Portal und eine eigne Schnittstelle. Alle anderen Azure Subscriptions und deren Verwendung und die angefallenen Kosten können nun seit kurzem mit der neuen Azure Billing API (Preview) abgefragt werden.

Wozu?

Das ist besonders für kleine Unternehmen sinnvoll, die kein Azure EA besitzen, aber dennoch mehrere Azure Subscriptions verwenden. So werden etwa oft mehrere eigene Unternehmens-MSDN Abos von unterschiedlichen Mitarbeitern verwendet, da macht es Sinn die “usage” und das “billing” automatisiert (oder in weiterer Folge gesammelt) abzufragen.

Code-Beispiele

Auf GitHub gibt es bereits drei Code Samples von Bryan Lamos dafür, nämlich die ConsoleApp-Billing-Usage, die ConsoleApp-Billing-RateCard und WebApp-Billing-MultiTenant: https://github.com/Azure/BillingCodeSamples

image

Hier die Beschreibung der Code Samples von GitHub:

Microsoft liefert die Daten über die Verwendung über den Provider "providers/Microsoft.Commerce/UsageAggregates" und die Kostendaten über den Provider "providers/Microsoft.Commerce/RateCard" (siehe auch unten) – daher auch die Benennung der Beispiele nach diesen Endpunkten mit “Usage” und “RateCard”.

Start mit Authentifizierung

Ich habe zunächst einmal das Beispiel ConsoleApp-Billing-Usage angesehen. Hier müssen natürlich zuerst die eigenen Daten und die Berechtigungen gesetzt werden. Das erste Compile lädt die erforderlichen NuGet Packages nach und wirft gleich einen Fehler mit dem Hinweis im Code, dass die AppSettings korrekt eingetragen werden müssen:

#error Please update the appSettings section in app.config, then remove this statement

Danke für den Hinweis, also die Zeile im Code entfernen, die Settings wollte ich soundso gerade anpassen…

image

Das Sample verwendet natürlich die ADAL Bibliotheken zur Authentifizierung mit OAuth und benötigt ein AD (TenantDomain), eine native App (ClientID) darin und eine Azure Subscription ID (SubscriptionID). Das Gute dabei ist, dass eine App in einem beliebigen AD ausreicht, um mehrere Azure Subscriptions abzufragen (natürlich muss das verwendete Konto darin berechtigt, sprich zB. Co-Admin, sein).
Die Anleitung zur Inbetriebnahme ist übrigens auf GitHub im Sample zu finden.

Um es kurz zu machen, so funktionierts: Im Azure Portal werden aus den “Settings” die SubscriptionID und das Default-Directory benötigt. In diesem Beispiel wird die Subscription mit dem AD “mvpdemo2014.onmicrosoft.com” verwaltet.

image

In diesem AD (mvpdemo2014*…) wird eine neue “native” App angelegt. Wichtig hierbei ist, dass die “ADALRedirectURL” wie im Code-Beispiel in den AppSettings verwendet wird. Bei uns lautet sie “https://localhost/”.

SNAGHTMLd1f583

Zum Abschluss sind noch die erforderlichen Permissions für die App zu setzen, wie hier - alles auf einen Blick:

SNAGHTMLd4145b

Diese Daten werden nun in die AppSettings eingetragen (hier nur der Beginn der IDs… bitte die eigenen verwenden).

image

Das war die Konfiguration. Nun geht es mit dem Programm weiter.

Die Abfrage der Daten

Die Abfrage erfolgt durch den REST Endpoint und Parameter. Für die “Usage” sieht das beispielsweise wie folgt aus:

https://management.azure.com/subscriptions/<SubscriptionID>/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedstartTime=2015-03-01+00%3a00%3a00Z&reportedEndTime=2015-05-18+00%3a00%3a00Z

Eine Liste der Parameter und der Bedeutung für Usage sind in der API Documentation zu finden:
Get price and metadata information for resources used in an Azure subscription

Wenn man das Sample ConsoleApp-Billing-RateCard ansieht (und ev. gleich in das Usage-Sample integriert), sieht man, dass es nach demselben Prinzip funktioniert. Hier wollen wir die Daten einer MSDN-Subscription in Euro und mit deutschen Bezeichnungen:

https://management.azure.com/subscriptions/<SubscriptionID>/providers/Microsoft.Commerce/RateCard?api-version=2015-06-01-preview&$filter=OfferDurableId eq 'MS-AZR-0061P' and Currency eq 'EUR' and Locale eq 'de-DE' and RegionInfo eq 'DE'

Die Namen der Subscription (hier: MS-AZR-0061P) sind in Microsoft Azure Offer Details ersichtlich.

SNAGHTMLf70e46

Eine Liste der Parameter und der Bedeutung für die RateCard sind in der API Documentation zu finden:
Resource RateCard (Preview)

Das bedeutet ggf. die Parameter nach eigenen Erfordernissen anpassen.

Los gehts

Wenn nun die App mit F5 gestartet wird, folgt zunächst eine SignIn-Box. Hier mit einem berechtigten Azure-Konto und der App “azurebillingdemo” (unserer native App im AD) anmelden.

image

Beim ersten Start müssen noch die App-Berechtigungen (Consent) erteilt werden:

image

Die Daten

Wenns lauft, dann laufts. So sieht dann etwa die “usageResponse” im JSON Format aus. Sie zeigt mehrere Values mit ihren verschiedenen properties – eben die verwendete Benutzung einzelner Cloud-Dienste.

image

Genauso sieht es mit den Kostendaten “rateCardResponse” aus:

image

Diese Daten gehören dann wohl in eine Datenbank oder in meinem Beispiel zu mindestens in eine CSV-Datei zur Weiterverarbeitung geschrieben. Man sieht aber bereits, was hier geliefert wird.

Jede “Usage”-Zeile besitzt eine “MeterId”, das ist eine GUID, etwa wie hier (teilweise):

image

Diese findet sich auch in der “RateCard” wieder.

image

In diesem Beispiel wären also die Kosten für “0.016129” mal “DB Units” genau “7.439 Euro” im Zeitraum zwischen usageStartTime und usageEndTime. Und so weiter.

Die Felder und deren Bedeutung sind in Get price and metadata information for resources used in an Azure subscription im Teil “JSON Element Definitions” dokumentiert:

image

Das Schöne an der neuen Azure Billing API: Die Abfragen funktionieren sehr schnell (ganz im Gegensatz zum elendslangsamen manuellen Herunterladen dieser Rechnungsdaten im Azure Billing Portal).

Mein derzeitiges Handicap: Ich habe es noch nicht geschafft, hier dieselben Daten, sprich dieselben Kosten, zu erhalten, die ich auch im Azure-Billing Portal angezeigt bekomme. Bei der Fülle an Daten ist das auch recht aufwändig und ich werde hier noch etwas Energie investieren müssen. Oder es liegt an der Preview. Oder an meinem Verständnis der Rechnungen. Das wird also noch etwas dauern.

Aber, wie heißt es so schön: You get the idea. Zwinkerndes Smiley

Mehr

Es gibt auch bereits fertige Produkte, welche diese (Preview) APIs nutzen: Cloudyn und Cloud Cruiser. Die sehen bereits recht vielversprechend aus, diese möchte ich mir auch noch näher ansehen.

Danke an Oliver Michalski für den API-Tipp im Azure Community Deutschland Blog!

Ich denke, die Azure Billing API wird Anwendern und Unternehmen sehr helfen die lästigen manuelle Tätigkeiten im Azure Portal durch ein nettes kleines Tool und entsprechende Auswertung dazu zu ersetzen. Endlich gibt es eine Azure Billing API – wenn auch noch in Preview!

Viel Spaß beim Ausprobieren!

Johannes Renatus: HTML5 Drag And Drop Direktive mit AngularJs und TypeScript

Mit Drag und Drop hatte ich bisher nicht viel zu tun, aber glücklicherweise gibt es immer ein erstes mal. Ich habe im Netz auch die ein oder andere Drag and Drop Implementierung, auch für AngularJs gefunden, aber keine die meine Bedürfnisse so richtig erfüllt hat. Außerdem hat mich die Thematik auch selbst brennend interessiert. Denn […]

Kazim Bahar: User Interfaces – Zukunftsvisionen (2)

Wie werden wohl Benutzeroberflächen künftig aussehen? Die folgenden Videos geben eindrucksvolle Beispiele von möglichen User Interfaces von morgen wieder....

Christian Binder [MS]: ALM Days 2016 – Deine Themen?

Der Sommer bringt uns den TFS 2015, der aus meiner Sicht wirkliche viele Bereiche signifikant erweitert und so die Engineering Plattform vor allem viel offener und erweiterbarer gestaltet. Ein weiterer Schritt zu einer Engineering Plattform, die auch Heterogene Teams optimal unterstützt, um den DevOps LifeCycle zu realisieren. Auf den ALM Days 2015 hatten wir Anfang des Jahres schon mal einen ersten Ausblick gegeben (Videos) und seitdem hat sich auch noch einiges getan – siehe Feature Timeline. Für die ALM Days 2016 habe ich mir daher schon die ersten Gedanken zum Design gemacht und wie immer interessiert mich, welche Themen für Euch besonders wichtig sind. Wer also ein Thema hat, dass er besonders spanned findet, kann mir gerne hier seine Idee zukommen lassen. Den Termin werden wir sobald er fixiert ist bekannt geben. Für alle Sommerurlauber wie mich, wünsche ich gutes Wetter Smile 

Chris

Holger Sirtl: Azure News on Friday (KW26/15)

Auch diese Woche gab’s wieder viele Nachrichten zur Microsoft Azure Plattform. Hier sind nähere Infos dazu…

Aktuelle Neuigkeiten

Datum Nachricht
25.06. Azure AD Conditional Access preview update: More apps and blocking access for users not at work
Neue Möglichkeiten für bedingte Zugriffe auf unternehmensweit verwaltete Apps via Azure Active Directory
25.06. Getting Started with Logic App Templates
Mit vorgefertigten Vorlagen schnell Business-Workflows mit Azure Logic Apps umsetzen.
25.06. New troubleshooting SSH connections
Schritt-für-Schritt Anleitung zur Problemlösung von SSH-Verbindungen zu Linux basierten Azure Virtual Machines
25.06. Announcing the 1.0.0 release of Application Insights Windows SDKs
Das erste Release (v1.0.0) des Windows SDK für Application Insights ist verfügbar.
25.06. New Azure Billing APIs Available
Jetzt endlich den aktuellen Verbrauch an Azure Ressourcen messen mit der Usage API (Teil der neuen Billing API)
24.06. Updated Azure SQL Database Elastic Database Pool Minimum Size
Die Minimalgröße eines Azure SQL Database Elastic Pools wurde auf 100 eDTU abgesenkt (zuvor 200 eDTU)
24.06. Azure AD Connect & Connect Health is now GA!
Spielend AD Federation mit Azure AD einrichten und lokale ADs überwachen: Azure AD Connect und Connect Health sind GA
24.06. New preview + 21 new partners announced for Azure SQL Data Warehouse
Vorstellung von 21 Partnern, die Azure SQL Data Warehouse nutzen.
24.06. Azure SQL Data Warehouse opens for Limited Public Preview
Das zur BUILD 2015 angekündigte Azure SQL Data Warehouse ist jetzt als Limited Public Preview verfügbar
23.06. Logic Apps Live Community Webcast – June 25
Gelegenheit, mit den Machern des Azure App Service zu sprechen: Community Webcast am 25. Juni
23.06. Container Apps now available in the Azure Marketplace
Neu im Azure Marketplace: Docker Apps - einfaches Setup via Docker Extensions und Azure Resource Manager
23.06. Tuesdays with Corey: Docker Con keynote goodness
Corey Sanders fasst die Announcements der DockerCon und den aktuellen Stand zu Docker auf Azure zusammen.
23.06. Docker and Microsoft announce more innovation to cross platforms and win hearts
Viele weitere Ankündigungen zu Docker auf der Microsoft Plattform.
19.06. Azure Redis Cache Updates for June 2015
Tolle Neuerungen im Azure Redis Cache - Änderungen der Cache-Größe zur Laufzeit und Infos zur Speicherbelegung
19.06. Azure News on Friday (KW25/15)
Was gab's letzte Woche Neues zu Microsoft Azure ? Hier gibt's eine Zusammenfassung (News, Videos, etc.)

Neue Videos

Datum Nachricht
25.06. Treating the Azure CLI as a Docker Container to speed development
Azure Friday: Installation der Azure CLI (Cross-Platform Command Line Interfaces) in einen Docker Container
25.06. Managing Large amounts of Data Throughput using Azure Event Hubs with Nicole Berdy
Azure Friday: Effiziente Verarbeitung auch größter eingehender Datenmengen mit Azure Event Hub

Sven Hubert: A brief description of the new features in WordToTFS 4.5

Jürgen Gutsch: ASP.NET 5 Console Application

Der Titel ist interessant, nicht war? Was zum Geier ist eine ASP.NET 5 Console Application?

Der Name ist genauso irreführend, wie das Thema interessant ist. Lange war mit nicht klar, was dieser neue Projekttyp überhaupt sein sollte.

Eine in der Console gehostete ASP.NET 5 Applikation ist es definitiv nicht, mit ASP.NET hat dieser Projekttyp ebenfalls wenig zu tun.

Genau gesagt, handelt es sich um eine einfache Console Application die mit .NET Core läuft und dabei auch die Vorteile der neuen .NET Core Projekte beinhaltet:

  • .NET Core
  • CoreCLR
  • project.json
  • .NET Utilities (dnx)

Gebrauchen kann man diese Art der Console Application natürlich ebenso unter Linux und MacOS, aber natürlich am besten auf IoT-Geräten, sowie für Aufgaben ohne UI z. B. in Docker Containern.

Gestartet werden diese Console Applications wie ASP.NET 5 webs:

[code language="JScript"]> dnvm install latest
> dnu restore
> dnx . ConsoleApp1[/code]

Das dnx Command muss natürlich in der project.json deviniert sein:

"commands": {
  "ConsoleApp1" : "ConsoleApp1 a b c d e f"
},

In meinem kleinen Test-Projekt habe ich die Argumente “a b c d e f” angehängt die ich dann entsprechend ausgebe:

public void Main(string[] args)
{
    Console.WriteLine("{0} - {1} - {2} - {3} - {4} - {5}", args);
    Console.ReadKey();
}

image

Für kommende Spielereien mit meinem Raspberry PI wird dieser Projekttyp nun die erste Wahl sein.

Sven Hubert: DWX 2015 – Developer Week in Nürnberg – Nachlese

André Krämer: Video zum Windows 10 Developer Readiness Screencast auf Channel 9 online

Am 8. Juni hatte ich die Freude gemeinsam mit meinen MVP Kollegen Thomas Mutzl und Christian Nagel einen Screencast über die Entwicklung für Windows 10 / die Universal Windows Plattform durchzuführen. Im Rahmen einer weltweiten MVP Initiative berichteten wir in gut 2,5 h darüber, welche Idee hinter der Windows Universal Plattform steckt, welche Änderungen es für XAML Entwickler geben wird und wie ich meine App darauf vorbereiten kann, auf mehreren Endgerätetypen zu laufen.

Seit kurzem ist die Aufnahme des Screencasts nun auf Channel 9 online. Wer also keine Gelegenheit hatte, den Vortrag live zu verfolgen, kann sich nun bequem die Aufnahme ansehen.

Ich selbst habe über das Thema Adaptive UI und Adaptive Code gesprochen. Dieser Teil startet bei ca. 1:42 h. Den Demo Code werde ich in Kürze auf GitHub veröffentlichen.

Und nun: Viel Spaß beim Ansehen!

Dmitrij Doberstein: VMware Player >>> serial port configuration

Start VMware Player

1) select the target OS 
2) click on 'Edit virtual machine settings' on right side

3) click on 'Add...' button

4) select 'Serial Port' 
5) 'Next'

6) select 'Use physical serial port on the host' 
7) 'Next' 

8) select 'Auto detect' or a specific COM port
Note that to communicate with the VM through this serial port, you will have to connect another machine to the physical serial port (COM1 in this case) using a null modem cable. You cannot just run minicom on that same machine and connect to /dev/ttyS0
9) 'Finish' 

10) 'OK' 

11) and now 'Play virtual machine'

 More useful and detailed information can find here:



Sven Hubert: Visual Studio Info Day in Karlsruhe – Was gibt’s Neues in Visual Studio und im Team Foundation Server 2015?

Dmitrij Doberstein: Ubuntu 14.04 >>> Problem Web + Python + PySerial

Environment:

VMware Player 7
Ubuntu 14.04
Lighttpd
Python
PySerial


If I ´m trying to open ttyS0 so i become error [Errno 13] Permission denied: '/dev/ttyS0'

To solve this problem check next:

  • is the user in dialout group?


>>> cat /etc/group | grep dialout


  • if the user not in dialout group, so add them:

>>> usermod -a -G dialout root
>>> usermod -a -G dialout userXXX
>>> usermod -a -G dialout www-data


  • add rw-persmission to ttyS0

>>> chmod 666 /dev/ttyS0





Sven Hubert: Cloud-Dienste für verteilte Entwicklungsteams

Sven Hubert: Zugriff von externen Mitarbeitern auf VSO Taskboards

Code-Inside Blog: FAKE: Create NuGet Packages without knowing a tiny bit of F#

This is a follow-up to my first two FAKE posts:

Creating NuGet Packages - with a NuSpec

FAKE has at least two approaches to build NuGet Packages. The first approach is that you define a NuSpec-Template and fill the missing pieces during the build via FAKE. This scenario is covered here. The second on is “simpler”, at least for me (but… you know… I have no idea how to write real F# code): You just need to manage your .nuspec manually. Currently I use this approach, because I can handle everything inside the .nuspec files and can still use FAKE for the build process.

Project Overview

The sample project consists of one class library project and the .fsx file.

x

The .nuspec content:

<?xml version="1.0"?>
<package >
	<metadata>
    <id>Test.Foobar</id>
    <version>2.0.0</version>
    <title>Test Foobar</title>
    <authors>Code Inside Team</authors>
    <owners>Code Inside Team</owners>
    <licenseUrl>http://blog.codeinside.eu</licenseUrl>
    <projectUrl>http://blog.codeinside.eu</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Hello World</description>
    <releaseNotes>
    </releaseNotes>
    <copyright>Copyright 2015</copyright>
    <tags></tags>
  </metadata>
  <files>
    <file src="CreateNuGetViaFake.dll" target="lib\net45" />
  </files>
</package>

Important here are the required NuSpec meta fields and the files section. If you are not familiar with the .nuspec syntax, take a look at the reference.

The FAKE script

Now to the FAKE script. At the end of the post you will see a link to the complete script, but I will highlight the “important” parts:

Building the library

...
let artifactsBuildDir = "./artifacts/build/"
...

Target "BuildApp" (fun _ ->
   trace "Building App..."
   !! "**/*.csproj"
     |> MSBuildRelease artifactsBuildDir "Build"
     |> Log "AppBuild-Output: "
)

Nothing special - we just build the library and the output will be stored in our artifacts/build folder.

Building the NuGet package - with the correct version

...
let artifactsNuGetDir = @"./artifacts/nuget/"
let artifactsBuildDir = "./artifacts/build/"
...

Target "BuildNuGet" (fun _ ->
   
    let doc = System.Xml.Linq.XDocument.Load("./CreateNuGetViaFake/Test.nuspec")
    let vers = doc.Descendants(XName.Get("version", doc.Root.Name.NamespaceName)) 

    NuGet (fun p -> 
    {p with
        Version = (Seq.head vers).Value
        OutputPath = artifactsNuGetDir
        WorkingDir = artifactsBuildDir
        })  "./CreateNuGetViaFake/Test.nuspec"
)

The built-in NuGetHelper will invoke nuget.exe with the given nuspec. We set the WorkingDir to the output of the other target and set the OutputPath to another location. The version handling is a bit complicated, because of this issue. The default Version is 1.0.0 and FAKE will currently ignore the Version-Information inside the .nuspec. The workaround is: Parse the .nuspec and get the version number and pass it to the NuGetHelper. Easy, right?

Make sure you include System.Xml.Linq

To get things running you will need to reference System.Xml.Linq like this:

// include Fake lib
#r "packages/FAKE/tools/FakeLib.dll"
#r "System.Xml.Linq"
open Fake
open System.Xml.Linq

RestorePackages()

The result: Our NuGet Package

x

Discover the NuGetHelper or Paket for more options

The NuGetHelper from FAKE has some pretty nice functionality built-in, for example you can publish to NuGet.org with a given access key.

For a more complete solution around consuming and creating NuGet Packages take a look at Paket.

For my simple use cases FAKE was “good enough” and I hope this might help.

You can find the complete sample & build script on GitHub.

Jürgen Gutsch: HTTP Sniffer Part 5: SSL ent- und verschlüsseln

Inhalt

Generell

In diesem Teil geht es um das ent- und verschlüsseln der zuletzt beschriebenen Streams in Falle einer SSL Verbindung.

Dieser Teil ist der kritischste Teil dieser Serie, im Sinne von “ich bin mir nicht sicher, ob ich das veröffentlichen soll, oder nicht.” Einerseits ist dieses Vorgehen sicherheitstechnisch nicht ganz ohne, allerdings ein bekanntes Verfahren das auch von Fiddler verwendet wird.

Was meine ich?

Wenn der Sniffer in einer eingehenden Anfrage erkennt, dass es sich um HTTPS Verbindung handelt (HTTP Verb “CONNECT”) dann muss der Proxy auch ein passendes Zertifikat bereitstellen.

Die Remote-Verbindung dagegen ist einfach, denn hier ist der Sniffer ein Client, der sich wie ein Browser verhält und die Daten anhand des öffentlichen Schlüssels wieder entschlüsseln kann.

Für die Client-Verbindung muss der Sniffer ein Zertifikat bereitstellen das auch noch vertrauenswürdig ist, um die Benutzer nicht mit Meldungen und Hinweisen des Browsers zu verunsichern. Der Sniffer erstellt also on-the-fly bei jedem HTTPS Request ein – für den angefragten Remote-Host – passendes SSL Zertifikat. Getrustet wird dieses Zertifikat mit einem Root-Zertifikat, das auf dem System im Certificate Store abgelegt wird.

Die Installation des Root-Zertifikats benötigt – zum Glück – Admin-Rechte.
Wehe dem, der UAC abgestellt hat.

Auf diese Art haben wir keine SSL Fehler im Browser, haben uns aber zwischen den Client und den Remote-Server gesetzt und die HTTPS Verbindung unterbrochen um mit zu lesen.

Wie sieht das aus?

Sobald wir nun eine CONECT Anfrage erhalten, Antworten wir dem Client und sagen ihm das alles in bester Ordnung ist:

var connectStreamWriter = new StreamWriter(state.ClientStream);
connectStreamWriter.WriteLine("HTTP/1.0 200 Connection established");
connectStreamWriter.WriteLine("Timestamp: {0}", DateTime.Now);
connectStreamWriter.WriteLine("Proxy-agent: GOS Proxy Service");
connectStreamWriter.WriteLine();
connectStreamWriter.Flush();

Ist die Antwort abgeschickt, kann der ClientStream in einen SslStream gesteckt werden (der Einfachheit halber wieder ohne Fehlerbehandlung und Logging):

var sslStream = new SslStream(state.ClientStream, false);
var certProvider = new CertificateProvider();

bool created;
var certificate = certProvider.LoadOrCreateCertificate(state.RemoteHost, out created);
sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, true);

var nstate = new ClientConnectionState
{
    Session = state.Session,
    Client = state.Client,
    ClientStream = sslStream,
    ClientStreamBase = (NetworkStream)state.ClientStream,
    Buffer = new byte[Globals.BufferSize],
    MessageStream = new MemoryStream(),
    IsSsl = true,
};

sslStream.BeginRead(nstate.Buffer, 0, nstate.Buffer.Length, ReadFromClient.Run, nstate);

Der SslStream kann nun benutzt werden um Anfragen entschlüsselt zu lesen und Antworten zu schreiben und zu verschlüsseln. Der ClientStream kann nun nicht mehr direkt gelesen und geschrieben werden, sondern eben nur noch über diesen SslStream. Also, alles was wir schreiben wird verschlüsselt an den Client übertragen und alles was wir vom Client lesen wird vorher entschlüsselt.

Ab jetzt beginnt der Prozess wieder beim anfänglichen einlesen des ClientStreams, denn der nächste Request des Clients wird mit den Standard-Verben (GET, POST, etc.) beginnen. In dem neuen ClientConnectionState wird nun der SslStream als ClientStream weitergeführt (siehe HTTP Sniffer Part 4: Streams optimal verarbeiten).

Die Zertifikate

Die Zertifikate werden über eine Hilfsklasse namens CertificateProvider erstellt. Diese wiederum nutzt die MakeCert.exe – die ins Ausführungsverzeichnis gelegt wird – um die nötigen Zertifikate in einem separaten Prozess zu erstellen und im Certificate Store des Systems abzulegen oder um diese dort auszulesen und für die SslStreams zurückzugeben.

Schaut euch dafür am besten den Code direkt auf GitHub an.

Die Remote-Seite

Für die Anfrage an den Server, wird ebenfalls ein SslStream benutzt, wenn es sich um eine HTTPS-Anfrage handelt, allerdings ist die Behandlung wesentlich einfacher, da wir keine Zertifikate explizit behandeln müssen. Die Methode AuthenticateAsClient übernimmt fas für uns und entschlüsselt den Stream mit dem öffentlichen Schlüssel.

var remoteStreamBase = state.RemoteClient.GetStream();
Stream remoteStream = remoteStreamBase;

if (state.IsSsl)
{
    var sslStream = new SslStream(remoteStream, false);
    sslStream.AuthenticateAsClient(state.RemoteHost);

    remoteStream = sslStream;
}

Nun wird der remoteStream genutzt, um wie gewohnt mit dem Stream zu senden und zu empfangen.

Im nächsten Teil sehen wir wie der Prozess als ganzes aufgebaut ist.

Jürgen Gutsch: HTTP Sniffer Part 4: Streams optimal verarbeiten

Inhalt

Generell

Im letzten Teil hatte ich den Zugriff auf den Stream, der vom TcpClient geliefert wird, kurz gezeigt: Wir lesen immer einen Teil des Streams aus und verarbeiten diesen Teil. Nach der Verarbeitung geben wir diesen Teil umgehend weiter an den nächsten Stream.

Diese Verarbeitung von Stream macht IMHO nur bei großen Dateien/Datenmengen Sinn. Kleine Dateien und Streams müssen so nicht behandelt werden. Der Aufwand lohnt nicht. Allerdings wissen wir in diesem Projekt nicht, wie groß die Daten im Stream sein wird.

In diesem Projekt erfolgt das auf die alten Methoden BeginRead und EndRead, die allerdings unheimlich flexibel sind und mit denen ich modular und sogar funktional arbeiten kann.

Was ich Web-Umfeld häufig machen musste, ist das lesen von großen Dateien (z. B: aus einem Azure Blob Storage und das weitergeben an den Client über den OutputStream im Repsonse Objekt). In diesem Fall bekommen wir einen Stream (von Azure-Client) und müssen diesen in den OutputStream “schreiben”. Um das ganze, bei sehr großen Dateien speicherschonend und performant zu halten müssen wir den Quell-Stream stückweise auslesen und ebenso stückweise in den Ziel-Stream schreiben. Dadurch halten wir nur dieses Teilstücks des Streams im Speicher. Die Herausforderung hier ist die Balance zwischen der Grüße des Teilstücks (Speichernutzung) und Schleifendurchläufe (Prozessornutzung).

Unter ASP.NET MVC ist der FileStreamResult eine einfache Möglichkeit einen gegebenen Stream auszuliefern. Allerdings habe ich den noch nicht mit sehr großen Dateien (500MB und mehr) ausprobiert. Interessant wäre zu wissen, ob hiermit wirklich stetig ausgeliefert wird, oder ob der Stream doch als ganzes auf einem mal ausgeliefert wird. Letzteres wäre nicht sehr speicherschonend. Bei kleinen Dateien macht das auf alle Fälle Sinn

Ein einfacher Kopiervorgang eines eingehenden Streams in einen Verschlüsselten ausgehenden Stream könnte wie folgt aussehen:

private const int _bufferSize = 20* 1024;

// …

var cryptoStream = new CryptoStream(outputStream, algorythm.CreateEncryptor(algorythm.Key, algorythm.IV), CryptoStreamMode.Write);
var bytes = new byte[_bufferSize];

var read = inputStream.Read(bytes, 0, _bufferSize);
while (read == _bufferSize)
{
    cryptoStream.Write(bytes, 0, read);
    cryptoStream.Flush();
    read = inputStream.Read(bytes, 0, _bufferSize);
}
cryptoStream.Write(bytes, 0, read);
cryptoStream.FlushFinalBlock();

// …

Hier handelt es sich konkret um das verschlüsselte Ablegen einer Datei.

In unserem Fall mit dem Sniffer, ist diese Schleife allerdings nicht so einfach und schön zu nutzen. Es würde schnell sehr komplexer und unschöner Code entstehen. Daher habe ich die Variante mit BeginRead und EndRead gewählt, die zudem noch Asynchron läuft.

Stream.BeginRead

Analog zu der Methode Write, die man im obigen Code-Beispiel sieht, wird bei BeginRead eben falls ein Byte-Array als Puffer übergeben, sowie die Position als auch die zu lesende Menge an Bytes.

Zusätzlich wird aber die Referenz auf einen Handler-Methode übergeben, welche die eingelesenen Bytes verarbeitet, als auch ein beliebiges Objekt (AsyncState), mit dem weitere Daten an den Handler übergeben werden können. Für diesen Sniffer sind das spezielle Typen die für den jeweiligen Schritt die benötigten Informationen weitergeben:

var state = new ClientConnectionState
    {
        Session = new RequestSession(),
        Client = tcpClient,
        ClientStream = clientStream,
        ClientStreamBase = clientStream,
        Buffer = new byte[Globals.BufferSize],
        MessageStream = new MemoryStream(),
        IsSsl = false
    };

clientStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadFromClient.Run, state);

An dieser Stelle geben wir unter anderem den TcpClient, den clientStream, den Puffer mit den Daten als auch einen MemoryStream mit.

  • Den TcpClient wird nur mitgegeben, um ihn am Ende der Verarbeitung korrekt zu schließen
  • Der ClientStream wird benötigt, um EndRead aufzurufen und die Daten fertig zu lesen
  • ClientStreamBase ist der unverschlüsselte ClientStream, wenn wir später den ClientStream verschlüsselt haben. Wir führen parallel also eine unverschlüsselte Verbindung mit
  • Buffer wird später unsere Daten enthalten, ist der ausgelesene Teil-Stream
  • Der MessageStream ist der einzige MemoryStream der hier verwendet wird um die HTTP HeaderDaten als ganzes auszulesen. Diese werden benötigt, um die Verbindung zum entfernten Server herzustellen.
  • Die Session ist ein Objekt, das die Verbindungsdaten zum entfernten Server enthält als auch statistische Daten zum Loggen mit aufnimmt. z. B. die Anzahl der Schleifendurchläufe (Aufrufe von BeginRead pro Request. die Zahl der gelesenen Bytes als auch die Gesamtzahl der gelesenen Bytes)

Jeder AsyncState kann pro Verarbeitungsschritt etwas anders aussehen und andere Daten enthalten. insgesamt gibt es fünf dieser Objekte:

  • ClientConnectionState
    • Beim Auslesen vom ClientStream
  • ConnectToRemoteState
    • Beim herstellen der Remote-Verbindung
  • RemoteConnectionState
    • Beim starten der Remote-Verbindung
  • WriteToRemoteState
    • Beim schreiben in den RemoteStream
  • ReceiveFromRemoteState
    • Beim Lesen aus dem RemoteStream

Stream.EndRead

EndRead wird in der jeweiligen Handler-Methode aufgerufen. Vereinfacht in etwas so:

var state = asyncResult.AsyncState as ClientConnectionState;

if (state != null)
{
    var read = state.ClientStream.EndRead(asyncResult);

    state.MessageStream.Write(state.Buffer, 0, read);

    if (state.ClientStreamBase.DataAvailable)
    {
        state.ClientStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadFromClient.Run, state);
    }
    // …
}

Zuerst holen wir uns unseren AsyncState aus dem IAsyncResult und rufen dann EndRead auf. Erst dann können wir sicher sein, dass der Puffer complett ist.

Man beachte, dass wir hier mit Referenz-Typen arbeiten: Wir haben state.Buffer als Argument an BeginRead übergeben und haben diesen gefüllten Puffer nun gefüllt in unserem Handler, nachdem wir EndRead aufgerufen haben.

Nun speichern wir die Daten in unserem MessageStream zwischen, um später auf die Header-Daten zugreifen zu können.

Befinden sich noch Daten im Stream, so wird der aktueller Handler erneut aufgerufen, bis die Eigenschaft DataAvailable false ist. Dann können wir mit der weiteren Verarbeitung fortfahren. 

Die Tatsache, dass wir den Request komplett auslesen, ist keine wirklich fließende Stream-Verarbeitung. Wenn man annimmt, dass die Headerdaten die 20 KB nicht überschreiten, kann man die Informationen im ersten Schleifendurchlauf schon verarbeiten und dann wirklich die Daten von A bis Z fließend durchreichen. Ggf. lässt sich der Teil optimieren, indem man in jedem schleifendurchlauf die Header-Daten auf Vollständigkeit prüft, oder prüft, ob beim ersten durchlauf schon alle benötigten Daten vorhanden sind.

Fazit

Mit dieser Behandlung blocken wir und keinen Thread und es können mehrere Verarbeitungen parallel stattfinden. Das das Tatsächlich funktioniert, sieht man am Logging, indem die Ausgaben mehrerer parallel laufender Requests hineinlaufen. Schön ist das zu sehen, bei Bilder-lastigen Websites wie Pinterest oder Facebook. Sowohl die Logausgabe ist parallel als auch die Bilder die im Browser parallel geladen werden.

Die am ende angesprochene Optimierung um den eingehenden Request fließend an den RemoteStream zu übergeben, muss man abhängig davon machen, was man mit dem Sniffer bezweckt. Geht es um das reine Mitlesen oder Cachen von Daten, macht das absolut Sinn. Möchte man allerdings Filtern und Inhalte ersetzen und entschärfen – wie es bei einer Kinderschutz-Software Sinn machen würde -  müssen wir die Anfragen und Antworten komplett puffern. Ein Bild kann schließlich erst dann gut analysiert werden, wenn es komplett geladen ist. Eine Pufferung geht allerdings immer zu Lasten der Performance.

Marco Scheel: Links for 2015-06-19 [del.icio.us]

Holger Sirtl: Azure News on Friday (KW25/15)

Auch diese Woche gab’s wieder viele Nachrichten zur Microsoft Azure Plattform. Hier sind nähere Infos dazu…

Aktuelle Neuigkeiten

Datum Nachricht
18.06. Click Once Deployment von Windows Anwendungen via Azure Blob Storage
Click Once Deployment von Windows Anwendungen via Azure Blob Storage
17.06. Room service: How IoT creates a custom hotel experience
Coole IoT Konzeptstudie zum "Connected Room" - das moderne Hotelzimmer powered by Windows 10.
17.06. “Bring your own app” with Azure AD Self-Service SAML configuration -> now in preview
Die Azure AD Gallery unterstützt jetzt auch SaaS Anwendungen, die Single Sign-on via SAML 2.0 implementieren.
17.06. Report from Open Networking Summit: Achieving Hyper-Scale with Software Defined Networking
Mark Russinovich erklärt wie über Software Defined Networking mit Azure eine der größten Public Clouds betrieben wird.
16.06. Big data made clearer: handy infographic explains the fundamentals of predictive analytics
Infografik zu Predictive Analytics, Big Data, Klassifizierungen etc. Wichtig u.a. für Azure Machine Learning
16.06. Architecture Matters: The Service Fabric of Our Lives
Artikel, der Herausforderungen und Möglichkeiten der Azure Service Fabric am Beispiel Microsoft Intune beschreibt.
16.06. Addressing interoperability in IoT
Dieser Artikel zeigt auf, wie mit den Microsoft-IoT-Services der Herausforderung der Interoperabilität der IT-Systeme begegnet werden kann.
16.06. Azure Active Directory Premium reporting now detects leaked credentials
Das Azure AD kann jetzt über statistische Algorithmen erkennen, ob Credentials missbräuchlich verwendet werden.
15.06. Cloud Success Comes in Completing the Cloud Handshake
Guter Überblick über Best Practices, um maximal von Microsoft Azure hinsichtlich SLAs etc. zu profitieren.
15.06. Azure Data Factory Updates: Copy data from MySQL, DB2, Sybase, PostgreSQL and Teradata
Azure Data Factory unterstützt als Datenquellen jetzt auch MySQL, DB2, Sybase, PostgreSQL and Teradata
15.06. Azure Media Services delivers Widevine encrypted stream by partnering with Castlabs
Neben PlayReady unterstützen Azure Media Services jetzt auch Widevine zur Auslieferung DRM-geschützter Inhalte
12.06. Update to default partition count for Event Hubs
Die minimale Anzahl der Partitionen im Azure Event Hub wurde auf 2 reduziert. Default ist jetzt 4.
12.06. Azure AD, Microsoft Intune and Windows 10 – Using the cloud to modernize enterprise mobility!
Infos zum Zusammenspiel von Azure AD, Windows 10 und Intune für modernes Mobile Device Management.

Neue Videos

Datum Nachricht
18.06. The HTTP Platform Handler with Scott Hanselman
Scott Hanselman erklärt, wie mit dem HTTP Platform Handler Java, Ruby, F# etc. auf Azure ausgeführt werden kann
18.06. Azure Web App Log Streaming with Scott Hanselman
Scott Hanselman zeigt Schritt für Schritt wie mit Log Streaming Azure Web Apps überwacht werden können
17.06. Tuesdays with Corey: A little somethin' about Scale Sets
Corey Sanders zeigt wie mit Scale Sets und Azure Resource Manager skalierbare Deployments umgesetzt werden können.
12.06. Episode 177: More API Management Features with Vlad Vinogradsky
Neue Cloud Cover Episode mit Schwerpunkt Azure API Management

Marco Scheel: Links for 2015-06-18 [del.icio.us]

Holger Sirtl: Click Once Deployment von Windows Anwendungen via Azure Blob Storage

Dieser Artikel beschreibt in wenigen Schritten, wie Windows Anwendungen via Azure Blob Storage und Click Once Deployment auf Clients installiert werden können.

Disclaimer: Dieser Artikel ist eine Übersetzung/Aktualisierung eines Blogposts meines Kollegen Avkash Chauhan, dem ich an dieser Stelle meinen expliziten Dank für seine Vorarbeit aussprechen möchte.

Das Vorgehen zum Bereitstellen, Installieren und Deinstallieren einer Click Once Anwendung soll in folgenden 6 Schritten erfolgen:

  • Schritt 1: Erstellen eines öffentlichen Containers im Microsoft Azure Blob Storage
  • Schritt 2: Publishing einer Windows Forms Anwendung
  • Schritt 3: Kopieren aller Click Once Dateien in den Microsoft Azure Blob Storage Container
  • Schritt 4: Aufruf der Installer URL
  • Schritt 5: Aufruf der einmal Installierten Anwender auf dem Windows Client PC
  • Schritt 6: Entfernen der installierten Anwendung

Schritt 1: Erstellen eines öffentlichen Containers im Microsoft Azure Blob Storage

Zunächst benötigt man eine Azure Subscription sowie einen darin installierten Storage Account. Für eine detailliertere Beschreibung wie man diese erhält, verweise ich hier auf die offizielle Azure Dokumentation.

Erstellen Sie nun im ersten Schritt im Storage Account einen neuen Container (z.B. mit Namen “clickonceinstall”), für den Sie öffentlichen Zugriff auf die darin abgelegten Blobs konfigurieren. Hierzu können Sie beispielsweise den Azure Explorer der Firma Cerebrata verwenden.

image

Klicken Sie im Explorer im Storage Account mit der rechten Maustaste, wählen Sie den Menüpunkt New Blob Container. Wählen Sie einen Namen, setzen Sie das Zugriffslevel auf Blob – Public read Access for Blobs und bestätigen Sie mit OK.

In meinem Fall hat dieser Container nun die Adresse: https://hsirtldocs.blob.core.windows.net/clickonceinstall

Schritt 2: Publishing einer Windows Forms Anwendung

In Visual Studio 2013 habe ich nun eine kleine Windows Forms Anwendung namens ClickOnceApplication erstellt. Diese soll als Beispiel dienen (und enthält deshalb keine wirkliche Funktionalität), verwenden Sie hier eine eigene Anwendung.

Für das Publishing klicken Sie nun im Solution Explorer in Visual Studio auf das Projekt und wählen den Menüpunkt Publish… .

image

Da ein direktes Publishing in den Blob Storage Container (noch) nicht möglich ist, wählen Sie als Publishing Location ein lokales Verzeichnis (z.B. C:\Temp\ClickOnce) und bestätigen Sie mit Next>.

image

Wählen Sie im nächsten Fenster als Installationsort From a Web site und geben dort als URL die Adresse des oben angelegten Blob Storage Containers an. Bestätigen Sie mit Next>.

image

Wählen Sie im nächsten Fenster die Option “Yes, this application is available online or offline” und bestätigen Sie mit Finish.

image

Damit werden die für die Installation benötigten Dateien in den lokalen Ordner geschrieben.

image

Schritt 3: Kopieren aller Click Once Dateien in den Microsoft Azure Blob Storage Container

Kopieren Sie nun alle Inhalte des lokalen Ordners in des Blob Storage Container (also die drei Dateien und das Verzeichnis Application Files).

image

Schritt 4: Aufruf der Installer URL

Rufen Sie nun die URL der Installer-Datei (also Container-URL + “publish.htm”

image

Dies zeigt Ihnen eine Installationsseite an, über die Sie die Anwendung nun installieren können. Klicken Sie hierzu im Browser auf Install.

Bestätigen Sie, dass Sie die Datei Setup.exe ausführen möchten.

image

Da die Anwendung nicht speziell signiert ist, erhalten Sie noch diverse Warnungen bestätigen Sie jeweils mit Run, Run anyway und Install.

image

image

Die Anwendung sollte dann auf dem Windows Client PC installiert und ausgeführt werden.

image

Schritt 5: Aufruf der einmal Installierten Anwender auf dem Windows Client PC

Die Anwendung lässt sich nun auch auf dem Windows Client PC starten. Sofern man in Visual Studio die Erstellung eines Desktop-Icons konfiguriert hat, kann die Anwendung nach der Installation über dieses Icon aufgerufen werden.

Schritt 6: Entfernen der installierten Anwendung

Eine Deinstallation der Anwendung ist äußerst simpel. Rufen Sie die Systemsteuerung auf und suchen Sie die Anwendung unter Programs/Programs and Features.

image

Klicken Sie mit der rechten Maustaste auf die Anwendung und wählen Sie Uninstall.

image

Bestätigen Sie die Deinstallation im folgenden Dialog und bestätigen Sie mit OK.

Weitere Informationen

Jürgen Gutsch: Dependency Injection in ASP.NET MVC 6 Views

Nicht genug, dass Dependency Injection nun ein durchgehendes Konzept in ASP.NET 5 ist, nun lassen sich auch Services direkt in die Views injizieren. Wie das aussieht?

Ganz einfach :)

Erstellen wir spaßeshalber eine einfache Klasse, die uns eine Liste mit Ländern (vom Type Country) liefert und nennen diese CoutryService. Erstellen wir parallel ein Interface mit dem Namen ICountryservice:

public class CountryService : ICountryService
{
    public IEnumerable<Country> All()
    {
        return new List<Country>
        {
            new Country {Code = "DE", Name = "Deutschland" },
            new Country {Code = "FR", Name = "Frankreich" },
            new Country {Code = "CH", Name = "Schweiz" },
            new Country {Code = "IT", Name = "Italien" },
            new Country {Code = "DK", Name = "Dänemark" }
        };
    }
}

public interface ICountryService
{
    IEnumerable<Country> All();
}

public class Country
{
    public string Code { get; internal set; }
    public string Name { get; internal set; }
}

Diesen CountryService müssen wir nun dem DI Container hinzufügen. Das passiert in der Startup.cs in der Methode ConfigureServices:

services.AddTransient<ICountryService, CountryService>();

Diese Zeile mappt das Interface ICountryService auf die Implementation CountryService. Transient meint in diesem Fall, dass jedes Mal eine neue Instanz von CountryService erstellt wird, wenn wir nach der Implementation von ICountryService fragen. Das ist für diesen Fall absolut in Ordnung.

Nun können wir überall eine Instanz des Coutryservices erhalten. Wie bereits bekannt ist, natürlich auch im Controller per Constructor Injection:

public class HomeController : Controller
{
    private readonly ICountryService _countryService;

    public HomeController(ICountryService countryService)
    {
        _countryService = countryService;
    }
    // …
}

Und neu in ASP.NET MVC 6 auch in den Views.

Folgende Zeile definiert die Injection per Razor-Syntax in der View:

@inject DiViews.Services.ICountryService countryService;

Der erste Teil des @inject legt das Interface fest. Hier wird der komplette Namespace angegeben, sofern kein @using definiert ist und der zweite Wert ist der Name der Variablen, welche die Instanz hält. also analog zur Contructor Injection weiter oben.

Anschließend kann die Instanz wie gewohnt verwendet werden:

@if (countryService.All().Any())
{
    <ul>
        @foreach (var country in countryService.All().OrderBy(x => x.Name))
        {
            <p>@country.Name (@country.Code)</p>
        }
    </ul>
}

Alternativ würden sich auch Select-Boxen füllen lassen oder was auch immer:

@Html.DropDownList("Coutries", countryService.All()
    .OrderBy(x => x.Name)
    .Select(x => new SelectListItem
    {
        Text = x.Name,
        Value = x.Code
    }))

Für was ist das gut?

Eigentlich wird das recht schnell klar: Mit dieser Technik lassen sich z. b. Lookup-Daten einfacher und sauberer in die View bringen als über den ViewBack oder über das Model, bei typisierten Views. Somit wird das Model sauberer und schlanker und die Nutzung des ViewBacks wird reduziert. Die Actions übermitteln nur noch die Daten, die wirklich dynamisch ausgegeben werden sollen. Aus meiner Sicht wird diese Technik auch die Controller um einiges übersichtlicher machen, weil eben diese Lookup-Werte nicht mit ermittelt und zurückgegeben werden müssen.

Da Dependency Injection überall funktioniert, könnte man nun z. B. auch wiederverwendbare TagHelper für Lookup-Werte schreiben.

Jürgen Gutsch: ASP.NET MVC Web kontinuierlich nach Azure ausliefern mit Jenkins und FAKE

Vorab

Für ein aktuelles Projekt ist es nötig, schnell auf reale Umgebungen auszuliefern. In einen Fall soll der Entwicklungsstand (DEV) auf eine Instanz ausgeliefert werden, in der wir Entwickler nochmals testen und ggf. debuggen können und im nächsten Fall soll ein Zwischenstand (QS, mit fertigen Features) zum Testen und für Kundenabnahmen auf eine weitere Instanz ausgeliefert werden. Im letzten Fall, soll der abgenommene Stand (PROD) auf das Produktiv-System ausgeliefert werden.

Es soll allerdings nicht nur ausgeliefert werden. Sowohl die Website als auch drum herum entstandene Projekte sollen auch gebaut und anschließend getestet werden.

Wir haben hier drei - nahezu identische – Deployments auf fast identische Umgebungen. Die unterschiede sind minimal:

  • DEV:
    • voll automatisiert
    • baut im Debug-Modus
  • QS:
    • voll automatisiert
    • baut im Release-Modus
  • PROD:
    • automatischer Build
    • manueller Build-Trigger
    • baut im Release-Modus

Die Versionierung lasse ich in diesem Beitrag mal aus.

Die ersten beiden Builds laufen nach dem Commit in den entsprechenden Branch. Der letzte Build wird manuell angestoßen, wenn die Features getestet und abgenommen sind und dieser Stand in den master-Branch comittet sind.

Alternativ zu den Varianten mit Visual Studio Online die aktuelle überall beschrieben sind, stelle ich hier eine andere, offenere und – aus meiner Sicht – leichtgewichtigere  Variante vor.

Jenkins

Als Build-Server dient eine Jenkins-Installation auf einer VM auf Azure. Dort sind drei Build-Jobs angelegt, von denen zwei auf Änderungen im entsprechenden Branches im Git-Repository reagieren und einer auf den manuellen Start wartet.

Jenkins ist ein sehr Leichtgewichtiger und schneller Build-Server, den ich schon seit Ewigkeiten (Noch unter dem Namen Hudson) eingesetzt habe. Die UI ist zwar nicht sehr hübsch, allerdings ist er leicht zu bedienen und schnell installiert. Für Windows gibt es einen kompletten Installer von Bitnami, für alle denen selbst die manuelle Installation noch zu schwer ist ;-)

Alle Build-Jobs ziehen sich den aktuellen Stand des jeweiligen Branches und rufen ein FAKE-Skript mit Parametern auf. Die Parameter sind unter anderem:

  • Build-Nummer
  • Build-Configuration (debug oder release)
  • Name der entsprechenden Azure Deployment Configuration
  • Das Publish-Passwort

FAKE hatte ich in einem separaten Beitrag kurz vorgestellt und kommt bei mir in privaten Projekten immer zum Einsatz. Im Geschäft ist dies der erste Einsatz von FAKE. Ich gehe hier nur auf den Deploiyment Teil in FAKE ein, nicht auf die Konfiguration des Builds und der Tests, da das nicht sehr von dem abweicht, was in der Dokumentation zu FAKE steht. Die Reihenfolge (Konfigurieren, Bauen, Testen und Ausliefern) ist eh klar.

Der Aufruf des FAKE-Scripts in Jenkins erfolgt über ein Batch-Task, Hier wird ebenfalls nur ein Batch-Script aufgerufen, das – bevor das FAKE-Skript gestartet wird – FAKE aktualisiert, in dem es die aktuellen NuGet Packages zieht. War das update erfolgreich wird das FAKE-Script wie folgt aufgerufen:

CI\build.bat bn=%BUILD_NUMBER% conf=Debug pubprofile="MyMvcProject - Web Deploy.pubxml" pubpwd=%PUBLISH_PASSWORDD%

Deployment mit FAKE

Die Auslieferung war etwas Tricky, wir mussten zuerst herausfinden, wie das mit MS-Build gelöst werden kann. Am Ende war es klar: Wir mussten die Web App nochmals bauen mit den Targets Publish und der Angabe der Azure Deployment Configurations. Also ein Web-Deployment direkt auf die Azure Web App.

Wir haben im FAKE-Script wieder einen MsBuild Aufruf, diesmal mit den erwähnten zusätzlichen Parametern:

let setParamsWeb = [
        "DebugSymbols", "True"
        "Configuration", buildConf
        "Platform", "Any CPU"
        "PublishProfile", publishProfile
        "DeployOnBuild", "true"
        "Password", publishPassword
        "AllowUntrustedCertificate", "true"
        "IgnoreDatabaseSettingOutOfSync", "true"
]

// Publish the application
Target "PackageApp" (fun _ –>
    MSBuild buildDir "Build" setParamsWeb ["MySolution/MyMvcProject/MyMvcProject.csproj"]
      |> Log "AppBuild-Output: "
)

Fazit

Im Grunde war es das auch schon. Dieses Setup ist schnell aufgesetzt, einfach zu warten und läuft auch relativ schnell durch. Das Continuous Deployment an sich ist also angenehm leichtgewichtig. Projektverantwortliche und Kunden können schnell auf den aktuellen Stand schauen und schnell Feedback geben. Was im aktuellen Projekt hervorragend funktioniert hat.

Nach Möglichkeit sollte dieses Setup nun in allen zukünftigen .NET-Projekten genutzt werden. Durch FAKE spart man sich eine übermäßige Konfiguration im Jenkins und kann den gesamten Build- und Deployment-Prozess bequem im Visual Studio bearbeiten. Beim nächsten Commit in den jeweiligen Branch wird das FAKE-Script sofort angewendet.

André Krämer: Kostenlose Performance Sprechstunde mit André Krämer auf der Developer Week 2015

Die Anwendung ist viel zu langsam!

Diesen Satz möchte wohl kein Entwickler gerne von seinen Kunden oder Anwendern hören.

Am 17. Juni 2015 werde ich deswegen während der Mittagspause der Developer Week einen Kurzvortrag über drei typische Performance Probleme halten. Anschließend haben wir noch ca. 15 Minuten für Fragen und Antworten zu konkreten Performance Problemen, ehe die Sessions wieder starten.

Jeder Besucher der DWX ist herzlich willkommen, mich am Stand von Redgate zu besuchen und seine Fragen mitzubringen.

Kostenlose .NET Performance Sprechstunde mit Andre Kraemer auf der Developer Week 2015

Manfred Steyer: Folien und Beispiele zu meinem Vortrag über Micro-Services mit ASP.NET 5

Nachfolgend die Folien und Beispiele zu meinem Talk über Micro-Services mit ASP.NET 5 MVC. Die Demo-Anwendung besteht aus zwei Micro-Services. Der eine basiert auf AngularJS, Web APIs und ASP.NET 5; der andere ist eine klassische Web-Anwendung, welche auf ASP.NET MVC 6 basiert. Zur Authentifizierung kommen Tokens zum Einsatz. Diese werden via OpenId Connect angefordert und als Identity Provider fungiert Google. Darüber hinaus kommt zur Kommunikation zwischen den beiden Micro-Services neben einer REST-API auch der Microsoft Service Bus zum Einsatz.

Downloads

Marco Scheel: Links for 2015-06-15 [del.icio.us]

Manfred Steyer: Folien und Beispiele zu meinem Vortrag zum Erweitern von Entity Framework 6.x

Nachfolgend finden sich die Folien und Beispiele zu meinem Vortrag zum Erweitern von Entity Framework 6.x, welchen ich heute auf der DWX gehalten habe. Die Beispiele zeigen den Einsatz von Caching, Filter, Bulk-Updates mit Entity Framework 6.x. Dazu kommen Community-Erweiterungen sowie eigene Implementierungen zum Einsatz. Ein weiteres Beispiel zeigt, wie man sich mit einem eigenen MigrationGenerator DDL-Code für History-Tabellen generieren lassen kann.

Folien und Beispiele


Manfred Steyer: Ein gut gehütetes Geheimnis: Proxies in Visual Studio für Web-APIs mit dem Azure SDK auf Knopfdruck generieren

Bis dato fehlt in Visual Studio die Möglichkeit, per Knopfdruck einen Proxy für eine Web API zu generieren. Das ist ärgerlich, zumal dies einen Rückschritt gegenüber SOAP-basierter Web-Services darstellt. Glücklicherweise hat Microsoft hier nachgerüstet. Allerdings haben das die wenigsten bemerkt. Der Grund dafür dürfte sein, dass diese Neuerung mit dem aktuellen SDK für Azure kommt. Microsoft nutzt diese Möglichkeit für die neuen Azure-basierten Api-Apps. Trotzdem kann man damit auch eigene Web APIs, die über Swagger dokumentiert sind, adressieren und somit einfach Proxies erhalten.

Zum Generieren eines Proxys in einem Client-Projekt nutzt der Entwickler die vom Azure-SDK eingerichtete Anweisung Add | Azure Api App Client im Kontextmenü des Solution-Explorers (siehe Abbildung). Der auf diese Weise aufgerufene Dialog bietet die Möglichkeit, entweder eine API App aus einem Azure-Konto auszuwählen oder eine Swagger-Datei direkt anzugeben. Letztere Option kann der Entwickler somit auch für Web APIs, die nicht via Azure gehostet werden, nutzen.

Nach dem Bereitstellen der geforderten Informationen generiert Visual Studio einen Proxy. Listing 2 veranschaulicht die Funktionsweise von Proxys anhand der Methode GetAll des in Listing 1 gezeigten HotelControllers. Der Name des Proxys entspricht dem Namen der API App. Er weist pro beschriebener Web API eine Eigenschaft auf. Über diese Eigenschaft lassen sich die angebotenen Methoden aufrufen.

var client = new Steyerhotels();
var hotels = client.Hotel.GetAll();

foreach (var hotel in hotels)
{
    Console.WriteLine(hotel.Name);
}

Neben den synchronen Proxy-Methoden liegen auch asynchrone Gegenstücke vor. Wer die gesamte empfangene HTTP-Nachricht lesen möchte, greift auf Methoden mit der Endung WithOperationResponseAsync zurück. Diese liefern eine Instanz von HttpOperationResponse, welche die HTTP-Nachricht über eine Eigenschaft Response des Typs HttpResponseMessage repräsentiert (siehe nachfolgendes Listing).

var client = new Steyerhotels();
var result = client.Hotel.GetAllWithOperationResponseAsync().Result;
Console.WriteLine(result.Response.StatusCode);
var hotels = result.Body;

foreach (var hotel in hotels)
{
    Console.WriteLine(hotel.Name);
}

Um ausgehende Nachrichten zu beeinflussen, bietet der Proxy über eine Eigenschaft HttpClient jene HttpClient-Instanz, die er auch zum Zugriff auf die Web API heranzieht. Diese Instanz kann zum Beispiel genutzt werden um standardmäßig zu übersendende Kopfzeilen festzulegen.

[1] http://azure.microsoft.com/de-de/downloads/

Manfred Steyer: Swashbuckle zur Generierung von Swagger-Dokumentationen für Web APIs konfigurieren

Wie in einen vorangegangenen Beitrag beschrieben, bietet das freie Community-Projekt Swashbuckle die Möglichkeit, für mit ASP.NET Web API bereitgestellte Services ein Swagger-Dokument zu erzeugen. Dabei handelt es sich um eine JSON-basierte Service-Beschreibung, welche zum Generieren von Dokumentationen oder clientseitigen Proxys genutzt werden kann.

Swashbuckle bietet zahlreiche Konfigurationsmöglichkeiten, von denen drei hier näher betrachtet werden. Um diese Konfigurationsmöglichkeiten zu nutzen, übergibt der Entwickler einen Lambda-Ausdruck an die Methode EnableSwagger, welche Swashbuckle aktiviert. Bei EnableSwagger handelt es sich um eine Erweiterungsmethode für die Klasse HttpConfiguration, mit der ASP.NET Web API konfiguriert wird.

Das Beispiel im nächsten Listing veranschaulicht dies. Der Parameter c des Lambda-Ausdrucks steht für ein Konfigurationsobjekt, welches die einzelnen Konfigurationsoptionen anbietet. Durch Aufruf der Methode ResolveConflictingActions wird festgelegt, wie Swashbuckle vorgehen soll, wenn für ein und dieselbe Url mehrere Service-Operationen existieren. Solch ein Fall ergibt sich, wenn Web API zwischen mehreren Service-Operationen lediglich anhand der übergebenen Url-Parameter wählen muss. Das nächste Listing veranschaulicht dies anhand eines einfachen Controllers, da hier die standardmäßig vorherrschende Route dazu führt, dass ASP.NET Web API die ersten beiden Operationen bei einer an /api/hotel gerichteten GET-Anfrage in Erwägung zieht. Übersendet der Aufrufer einen Parameter minSterne zieht Web-API erste heran; ansonsten letztere. Auch wenn es auf dem ersten Blick so wirken mag, verursacht die dritte Methode in Listing 4 keinen Konflikt, da sie durch die standardmäßig vorherrschende Route auf die Url /api/hotel/{id} abgebildet wird, wobei {id} ein Platzhalter für den gleichnamigen Übergabeparameter ist.

Leider unterstützt Swagger diese Art der (Methoden-)Überladung nicht und löst in solchen Fällen eine Ausnahme aus. Um diese Ausnahme zu vermeiden, kann der Entwickler jedoch über die Konfigurationseinstellung ResolveConflictingActions (siehe nächstes Listing) angeben, wie mit solchen Konflikten umzugehen ist. Dazu verweist diese Option auf einen Lambdaausdruck, der pro Konflikt eine Auflistung mit Informationen zu sämtlichen in Konflikt stehenden Operationen übergeben bekommt und die Aufgabe hat, ein Objekt mit jenen Informationen, die für die jeweilige Url in das Swagger-Dokument aufzunehmen sind, zu retournieren. Im betrachteten Fall wird einfach die erste Beschreibung retour geliefert und somit alle anderen Operationen außer Acht gelassen. Es wäre hingegen auch denkbar sämtliche Beschreibungen zu einer einzigen Beschreibung zu vereinen.
Hat der Entwickler diese Einschränkung beim Implementieren der Web API im Hinterkopf, kann er hingegen solche Konflikte bereits von vorn herein vermeiden, indem er jeder Operation eine eigene Url verpasst sowie Überladungen zugunsten von optionalen Parametern vermeiden.

GlobalConfiguration.Configuration.EnableSwagger(c => { 

        c.ResolveConflictingActions(descriptions =>
        {
            var result = descriptions.First();
            return result;
        });
});
public class HotelController : ApiController
{
        [HttpGet]
        public List FindHotelsBySterne(int minSterne)
        {
            […]
        }

        public List GetHotels()
        {
            […]
        }

        /// 
        /// Liefert ein Hotel anhand der übergebenen Id zurück.
        /// 
        public Hotel GetHotel(int id)
        {
            […]
        }
}

Eine weitere nützliche Konfigurationsoption, die hier vorgestellt werden soll, ist Möglichkeit, mit IncludeXmlComments die Informationen aus XML-basierten Kommentaren, wie jene, die im nächsten Listing für die Methode GetHotel hinterlegt wurden, in die generierte Swagger-Dokumentation aufzunehmen. Dazu ruft der Entwickler IncludeXmlComments im Rahmen der Konfiguration auf und übergibt dabei einen String, der den vollständigen Dateinamen der beim Kompilieren generierten XML-Datei beinhaltet:

     c.IncludeXmlComments(
              System.AppDomain.CurrentDomain.BaseDirectory 
                + @"\bin\SwaggerServer.XML");

Damit Visual Studio diese XML-Datei beim Kompilieren generiert, muss in den Projekteinstellungen unter Build die Option XML documentation file aktiviert werden.

Zum Abschluss betrachtet der vorliegende Beitrag eine Herausforderung, die sich ergibt, wenn eine Service-Operation den Typ HttpResponseMessage oder IHttpActionResult retourniert. In diesem Fall ist Swashbuckle nicht in der Lage, via Reflektion den über die Nutzdaten übersendeten Rückgabewert zu erkennen. Abhilfe schafft hier das Attribut ResponseType, über das der Entwickler über den tatsächlichen Rückgabewert informieren kann:

[ResponseType(typeof(Hotel))]
public HttpResponseMessage PostHotel(Hotel hotel) { […] }

Manfred Steyer: Client-seitige Proxies für Web APIs generieren

Das quelloffene Projekt Swagger.WebApiProxy [1] bietet dem Entwickler die Möglichkeit, aus einer Swagger-basierten Beschreibung [2] eines RESTful Services bzw. einer Web API einen clientseitigen Proxy zu generieren.

Die einfachste Art, diese Community-Erweiterung zu nutzen, besteht darin es von Github [1] herunterzuladen und das sich unterhalb des Ordners src befindliche Projekt Swagger.WebApiProxy.Template in die eigene Solution einzubinden. Zwar ist es auch möglich, via NuGet zu beziehen. Allerdings geht dies mit der Notwendigkeit einer unter [1] beschriebenen manuellen Änderung der genutzten Projektdatei einher.

Das Projekt Swagger.WebApiProxy.Template besteht im Wesentlichen aus einer T4-Datei, welche sich um das Generieren der gewünschten Client-seitigen Proxys kümmert. Die dazu nötigen Informationen bezieht sie aus der Datei SwaggerApiProxy.tt.settings.xml, in die unter anderem die URL des Swagger-Dokuments sowie der Namensraum, in dem der Proxy generiert werden soll, einzutragen ist. Das nächste Listing demonstriert dies. Das Element Url spiegelt die Url des Dokuments wieder und das Element Namespace den gewünschten Namensraum. Unter Id findet man einen Bezeichner für die Web API. Die restlichen Elemente wurden aus der mitgelieferten Beispieldatei ohne Änderung übernommen.

<SwaggerApiProxySettings>
  <EndPoints>

    <EndPoint>
      <Id>SwaggerServer</Id>
      <Url>http://localhost:59458/swagger/docs/v1</Url>
      <Namespace>SwaggerServer</Namespace>
      <Suffix>WebProxy</Suffix>
      <BaseProxyClass>Swagger.WebApiProxy.Template.BaseProxy</BaseProxyClass>
      <ProxyConstructorSuffix>(Uri baseUrl) : base(baseUrl)</ProxyConstructorSuffix>
      <ParseOperationIdForProxyName>false</ParseOperationIdForProxyName>
      <AppendAsyncToMethodName>false</AppendAsyncToMethodName>
    </EndPoint>

  </EndPoints>
</SwaggerApiProxySettings>

Anschließend kann man mit dem generierten Proxy auf die Web API zugreifen. Das nächste Listing veranschaulicht dies, indem es zwei beispielhafte Service-Operationen, GetHotel und FindHotelsBySterne, anstößt.

HotelWebProxy proxy = new HotelWebProxy(new Uri("http://localhost:59458"));
var hotel = proxy.Hotel_GetHotel(1).Result;
var hotels = proxy.Hotel_FindHotelsBySterne(3).Result;

Karsten Kempe: Branch Policies in TFS2015 und Visual Studio Online

TFSlovesGitHeute bin ich auf der DWX – Developer Week 2015 und demonstriere das Zusammenspiel von GIT und TFS. Während meiner Vorbereitung ist mir aufgefallen, dass sich in den letzten Wochen viel getan hat und einige Neuerungen für GIT im TFS/VSO zu finden sind. Eine sehr spannende Erneuerung im Bereich Softwarequalität sind die sogenannten Branch Policies für Git Repositories.

In Zeiten von Continuous Delivery und schnellen Feedback-Schleifen ist ein funktionierender Source Code-Branch ein MUST HAVE. Um die Stabilität eines solchen Branches zu gewährleisten, sind verschiedene Qualitätsrichtlinien sinnvoll. Entwickler-Tests wie z.B. Unit-Tests setze ich hierbei voraus, ebenso wie die Verwendung von ausgewählten Entwicklungs-Branches. Spannend wird es aber dann, wenn man sich mit dem Merge-Prozess zwischen verschiedenen Entwicklungsständen beschäftigt.

Pull Requests

Für die Zusammenführung unterschiedlicher Source Code Stände gibt es im TFS oder Visual Studio Online seit geraumer Zeit die sogenannten Pull Requests.

Branch Policies PullRequestAbbildung 1: Pull Request von SampleBranch to Master

In einem Pull Request können Entwickler darum bitten, dass z.B. ihre Source Code Änderung aus ihrem Entwicklungs-Branch in einen Integrations-Branch aufgenommen wird. Der Request bietet die Möglichkeit, dass ein oder mehrere Reviewers benannt werden können, um sich den geänderten Code anzusehen. Die Idee ist, dass nur überprüfte und für gut befundene Änderungen in den Integrations-Branch übernommen werden können. Außerdem überprüft das System, ob eine Merge automatisch durchgeführt werden kann oder ob ein Konflikt besteht.

Branch Policies PullRequest WorkItemLink CommentsAbbildung 2: Pull Request mit Kommentar und ohne Merge-Konflikte

Branch Policies

Viele von Euch kennen vermutlichen den „Gated Check-In“-Mechanismus der Team Foundation Version Control, der zusätzliche Sicherheit bei der Integration von Source Code in einen bestimmten Branch bietet. Dieses Policy Gate gibt es in Git leider nicht, so dass man andere Methoden zur Qualitätssicherung verwenden muss. Die vorgestellten Pull Requests spielen dabei wieder ein zentrale Rolle. Mit der Version TFS 2015 (oder schon jetzt in Visual Studio Online) wird es eine Erweiterung geben, die sogenannten Branch Policies. Mit Hilfe dieser Branch Policies können für jeden Source Code-Branch Richtlinien hinterlegt werden. Die Einstellungsseite der Branch Policies befindet sich in der Projekt-Administration im Bereich der Version Control und wird für jeden Branch einzeln festgelegt (Team Projekt | Version Control | Repository | Branch).

Branch PoliciesAbbildung 3: Branch Policies Einstellungen in der Admin-Ansicht

In den Polcies kann beispielsweise ein automatischer Build ausgewählt werden, der den zu committenden Source Code überprüft und den Merge in den Branch gegebenenfalls verhindert, wenn das Ergebnis negativ ausfällt (Block the merge if the latest build did not succeed).

Eine kleine Einschränkung gibt es hier aber an dieser Stelle. Der Mechanismus funktioniert nur mit Build Definitionen der neuen Build Engine und nicht für XAML Builds.

Eine zweite Richtlinie sind Code Review Requirements. Mit Hilfe dieser Policy lässt sich festlegen, ob ein Code Review Voraussetzung für einen Pull Request ist und sogar wieviele Reviewers mindestens am Review-Prozess teilnehmen müssen.

Als Erweiterung der Code Review Requirements kann sogar festgelegt werden, dass einzelne Code Pfade von bestimmten Personen begutachtet werden.

Die Ergebnisse der eingestellten Richtlinien werden dann beim Durchführen eines Pull Requests im rechten oberen Bereich der Pull Request Ansicht dargestellt. In den nachfolgenden Abbildungen seht ihr einmal das Feedback für einen fehlgeschlagenen Build und einmal  das Feedback für die Verletzung der Reviewer-Regel.

Branch Policies PullRequest Build errorAbbildung 4: Pull Request mit fehlgeschlagenem Build

Branch Policies PullRequest ReviewersAbbildung 5: Pull Request mit Verstoß gegen Reviewer-Regel

Fazit

Die Neuerungen finde ich super und sind aus meiner Sicht auch dringend notwendig gewesen, um die Code-Qualität eines bestimmten Branches besser schützen zu können. Ich bin mir sicher, dass in Zukunft noch weitere Policies hinzukommen werden, um die Source Code-Qualität speziell in Git Repositories bestmöglich zu unterstützen.

Manfred Steyer: Single Sign On mit OAuth 2.0 und OpenID Connect in ASP.NET 5

Um zu verhindern, dass ein Benutzer bei verschiedenen Anwendungen jeweils ein eigenes Benutzerkonto pflegen muss, setzt man in der letzten Zeit vermehrt auf zentrale Identity-Provider. Diese kümmern sich auch um die Authentifizierung des Benutzers und stellen daraufhin ein Security-Token aus. Aufgrund solcher Token können verschiedene Services herausfinden, um welchen Benutzer es sich handelt. Dazu müssen sie zunächst das Token validieren. Zu diesem Zwecke weist es häufig eine Signatur des ausstellenden Identity-Providers auf. Neben weiteren Sicherheitsmerkmalen beinhaltet es auch Claims, die den Benutzer näher beschrieben.

Der populäre Sicherheits-Standard OAuth 2.0 sowie das darauf aufbauende Protokoll OpenId Connect beschreiben, wie sich der Benutzer solch ein Token ausstellen lassen kann. Dazu definieren sie eine Komponente, die sich Authorization Server nennt und für das Ausstellen dieser Tokens verantwortlich ist. OpenId Connect legt darüber hinaus Details zum Aufbau sogenannter Identity-Tokens fest. Dabei handelt es sich um JSON Web Token (JWT), welche Claims mittels JSON repräsentieren und vom Aussteller optional verschlüsselt und/oder signiert werden können.

ASP.NET 5 bietet mit der OAuthBearerAuthenticationMiddleware-Komponente, welche sich im NuGet-Paket Microsoft.AspNet.Security.OAuthBearer befindet, Unterstützung für die Authentifizierung mit solchen Tokens. Um diese Komponente zu registrieren, ruft der Entwickler in der Methode Configure der Klasse Start die Erweiterungs-Methode UseOAuthBearerAuthentication auf (siehe nachfolgendes Listing). Wie bei Authentication-Middleware-Komponenten üblich, nimmt auch diese einen Lambda-Ausdruck entgegen. Dabei handelt es sich um eine Action, deren Aufgabe im Hinterlegen von Konfigurationseinstellungen besteht.
Das betrachtete Beispiel nutzt Google als Identity Provider. Es legt mit der Eigenschaft ValidIssuer fest, dass lediglich Tokens vom Aussteller accounts.google.com zu akzeptieren sind. Um dies sicherzustellen, erwartet die Middleware einen Claim mit dem Namen iss (Issuer) und diesem Wert im Token. Um zu verhindern, dass Angreifer Tokens fälschen, prüft die Middleware auch die Signatur der übersendeten Tokens. Der hierzu zu nutzende öffentliche Schlüssel findet sich in einem OpenId-Connect-konformen Metadaten-Dokument, welches der Programmcode der Middleware über die Eigenschaft Authority mitgeteilt.

Darüber hinaus legt das betrachtete Beispiel über die Eigenschaft ValidAudience fest, dass nur Token, die für den Client mit der Id 482348825399.apps.googleusercontent.com ausgestellt wurden, akzeptiert werden dürfen. Diese sicherheitskritische Prüfung verhindert, dass jeder beliebige Client mit einem von Google ausgestellten Token auf den Service zugreifen kann. Aus diesem Grund sehen OAuth 2.0 und OpenId Connect vor, dass sämtliche Clients beim Authorization Server zu registrieren sind. Im Zuge dessen erhalten sie unter anderem eine Client-Id. Diese Registrierung kann bei öffentlichen Anbietern, wie Google, Twitter oder Facebook, kostenfrei über eine Web-Anwendung erfolgen. Die hierzu von Google bereitgestellte Developer Console findet sich unter [2].

app.UseOAuthBearerAuthentication(options =>
{
    options.TokenValidationParameters.ValidIssuer = "accounts.google.com";
    options.Authority = "https://accounts.google.com";
    options.TokenValidationParameters.ValidAudience = 
                    "482348825399.apps.googleusercontent.com";
});
[…]

Mehrere Audiences und Issuer

Als Alternative zu den Eigenschaften ValidAudience und ValidIssuer stehen die Eigenschaften ValidAudiences und ValidIssuers zur Verfügung. Über diese Eigenschaften kann der Programmcode mehrere gültige Aussteller sowie Clients referenzieren.

Implementierung testen

Um die im letzten Abschnitt präsentierte Konfiguration zu testen, bezieht der Entwickler via OpenId Connect bei Google ein Token. Die einfachste Variante dies zu bewerkstelligen besteht in der Nutzung des sogenannten Implicit Flows. Dabei handelt es sich um jene Spielart von OpenId Connect, welche bei Single-Page-Anwendungen zum Einsatz kommt. Hierzu ruft der Entwickler die im nachfolgenden Listing gezeigte Url, die zur Login-Maske von Google führt, auf. Zur besseren Lesbarkeit wurden Zeilenschaltungen und Einrückungen eingefügt.

https://accounts.google.com/o/oauth2/auth?
    response_type=id_token
    &client_id=482348825399.apps.googleusercontent.com
    &state=[...]
    &redirect_uri=http%3A%2F%2Flocalhost%3A3749%2Findex.html
    &scope=openid%20email
    &nonce=[…]

Eine Beschreibung der verwendeten Url-Parameter, welche via OAuth 2.0 bzw. OpenId Connect definiert sind, finden sich nachfolgend:

  • response_type: Gibt an, welche Spielart (genauer: Flow) von OAuth 2.0 bzw. OpenId Connect zu nutzen ist. Der Wert id_token gibt an, dass über den Implicit-Flow ein Id-Token auszustellen ist.
  • client_id: Die Id, mit der der Client beim Authorization Server registriert ist
  • state: Ein String mit Zustandsinformationen. Dieser String wird im Zuge der Antwort vom Authorization Server zurück an den Client gesendet.
  • redirect_uri: Die Url, an die das ausgestellte Token zu senden ist. Diese Url muss für den angegebenen Client beim Authorization Server registriert sein.
  • scope: Gibt die Rechte an, welcher der Client im Namen des Benutzers wahrnehmen möchte. Kommt OpenId Connect zum Einsatz, ist hier per Definition openid anzugeben. Die zusätzliche Angabe von email gibt an, dass der Client auch die E-Mail-Adresse des Benutzers einsehen möchte.
  • nonce: Eine kryptographisch zufällige Zeichenfolge, welcher zum Verhindern von Angriffen zum Einsatz kommt. Gültige Token müssen diesen Wert als Claim beinhalten.

Nachdem sich der Benutzer bei Google angemeldet hat, muss er bestätigen, dass er der über die Client-Id referenzierten Anwendung die über den Scope ausgedrückten Rechte zukommen lassen möchte. Tut er das, leitet Google den Benutzer auf die angegebene Redirect-Uri um und übergibt dabei um Hash-Fragment neben dem zuvor übersendeten State ein Id-Token:

http://localhost:3749/index.html#state=[…]&id_token=[…]&[…]

Existiert keine Web-Anwendung, die auf den Aufruf dieser Url reagiert, kann der Entwickler sie zum Testen zumindest mit Tools, wie Fiddler, auslesen. Mit dem auf diese Weise erhaltenen Id-Token kann nun der Service aufgerufen werden. Dazu ist es gemeinsam mit dem Authentifizierungs-Typ Bearer im Authorization-Header der Anfrage zu inkludieren:

Authorization: Bearer ...Token...

Die OAuthBearerAuthenticationMiddleware übernimmt sämtliche Claims aus dem übersendeten Id-Token in den ClaimsPrincipal, den ASP.NET MVC 6 über die geerbte Eigenschaft User anbietet. Aus diesem Grund sollte man im hier beschriebenen Fall die bei Google hinterlegte Email-Adresse sowie die von Google für das Benutzerkonto verwendete Id als Claims wiederfinden.
Token anfordern

Single-Page-Anwendungen können Id-Tokens mit dem im letzten Abschnitt gezeigten Implicit Flow anfordern. OpenId Connect verpflichtet den Client den empfangenen Tokens einigen Prüfungen [3] zu unterziehen. Mit diesen Prüfungen sollen Angriffe verhindert werden. Eine Implementierung hierfür, welche sich auf JavaScript und AngularJS stützt, stellt der Autor unter [4] zur Verfügung.
Für klassische, auf Postbacks basierte Web-Sites bietet Microsoft hingegen über das NuGet-Paket Microsoft.AspNet.Authentication.OpenIdConnect eine Middleware-Komponente, die ein Login via OpenId Connect ermöglicht, an. Ein Beispiel dazu findet sich unter [5]. Native Clients sind hingegen angehalten, ein Browser-Control, welches die Login-Seite des Authorization Servers zeigt, einzublenden. Diese Vorgehensweise dürfte den meisten Visual-Studio-Benutzern bekannt sein, zumal die Authentifizierung von Entwicklern aus Visual Studio heraus auf dieselbe Weise erfolgt.
Bei klassischen Websites und nativen Clients kommt im Gegensatz zu Single-Page-Anwendungen die etwas komplexere jedoch auch mit mehr Sicherheitsmerkmalen bestücke Spielart Authorization Code Grant, zum Einsatz. Google beschreibt diese unter dem Name Server Flow unter [6].

Literatur

Manfred Steyer: Web APIs mit Swagger dokumentieren

Im Bereich verteilter Systeme gehört die Generierung clientseitiger Proxys seit Jahrzehnten zum Alltag. Die Aufgabe dieser Proxys ist es, unter Verwendung des gewählten Netzwerkprotokolls und Datenformats mit einem Service zu kommunizieren. Nach außen hin bietet der Proxy eine Schnittstelle an, welche jener des Services gleicht. Diese Schnittstelle kann der Client nutzen, um serverseitige Operationen anzustoßen, ohne sich mit den Details der Netzwerkprogrammierung auseinandersetzen zu müssen.

Um Proxies generieren zu können, bedarf es einer formalen Beschreibung der angebotenen Services. Für diesen Zweck wurden für zahlreiche Service-Technologien Interfacebeschreibungssprachen entwickelt. Ein sehr bekannter Vertreter ist die Web Service Description Language (WSDL), welche in erster Linie zum Beschreibung SOAP-basierter Web-Services zum Einsatz kommt. Für RESTful Services bzw. Web APIs hat sich noch kein solcher Standard auf breiter Basis durchgesetzt. Allerdings hat die Beschreibungssprache Swagger [1] in der letzten Zeit sehr viel Unterstützung erfahren, sodass heute für fast jede Plattform Swagger-Unterstützung zumindest durch Erweiterungen aus der Community vorliegen.

Während auch für ASP.NET MVC 6 eine Unterstützung für Swagger geplant ist [2], existiert mit Swashbuckle [3] ein ausgereiftes quelloffenes Projekt, das heute schon das Generieren von Swagger- Dokumentationen für ASP.NET-Web-API-basierte Projekte ermöglicht. Der Entwickler kann Swashbuckle via NuGet in ein Web-API-Projekt laden. Hostet er die Web API in IIS muss er dazu lediglich das Paket Swashbuckle einbinden. Im Zuge dessen erhält er auch im Ordner App_Start eine Datei SwaggerConfig.cs generiert. Die gleichnamige Klasse, die sich darin wieder findet, weist eine Methode Register auf, welche Swashbuckle konfiguriert. Diese Methode wird über ein Attribut PreApplicationStartMethod referenziert und somit im Zuge des Startups innerhalb von IIS ohne weiteres Zutun des Entwicklers zur Ausführung gebracht.

Nutzt der Entwickler hingegen Self-Hosting, ist laut Dokumentation das NuGet-Paket Swashbuckle.Core zu beziehen. In diesem Fall wird Swashbuckle durch Aufruf von Erweiterungsmethoden, die für die Klasse HttpConfiguration, mit der Web API konfiguriert wird, zu aktivieren. Informationen dazu findet man unter [2].

Nach dem Start der Web-Anwendung, erhält der Entwickler durch Aufruf der Url /swagger/docs/v1 eine nach den Vorgaben von Swagger generierte Beschreibung der von ihm bereitgestellten Web API. Dabei handelt es sich um ein JSON-Dokument, welches die einzelnen Urls sowie die unterstützten Verben und erwarteten Nachrichten beschreibt. Durch Aufruf der Url /swagger gelangt der Entwickler zu einer aus diesem JSON-Dokument generierten interaktiven Dokumentation, über welche er die einzelnen Service-Operationen auch zum Testen direkt anstoßen kann (siehe Abbildung).

Für das Generieren von clientseitigen Proxies stehen zahlreiche Projekte aus der Community zur Verfügung. Eines davon ist Swagger.WebApiProxy [4], welches in einem weiteren Beitrag näher betrachtet wird.

Manfred Steyer: Folien und Beispiele zu meinem Talk über Angular 2 und Migrationspfade

Nachfolgend finden sich die Folien und Beispiele zu meinem Talk über Angular 2 und Migrationspfade, den ich heute auf der DWX in Nürnberg gehalten habe. Die Beispiele zeigen den Einsatz von Angular 2 mit TypeScript aber auch den Einsatz der aktuellen Vorab-Version des neuen Component Routers mit Angular 1.x.

Folien und Beispiele

Jürgen Gutsch: HTTP Sniffer Part 3: Der TcpListener

Inhalt

Zu allererst:

Dieser Sniffer kann über die Console und über einen Windows-Service gestartet werden. Während der Entwicklung empfiehlt sich der Start über die Konsole. Dafür sollten die Startparameter in den Projekteigenschaften unter Debug festgelegt werden:

image

In der Program.cs werden als erste diese Parameter mit den Mono.Options ausgelesen und validiert:

IPAddress ip = null;
int port = 0;

var p = new OptionSet()
    .Add("a|address=", v => ip = IPAddress.Parse(v))
    .Add("p|port=", v => port = int.Parse(v));

p.Parse(args);

Im Anschluss erfolgt der Aufruf der Klasse Proxy, die auch vom Windows-Service aufgerufen wird:

var proxy = new Proxy
{
    ListenToIp = ip,
    ListenOnPort = port
};
proxy.Start();

In der Klasse Proxy sitzt nun der TcpListener.

Der Einfachheit halber lasse ich in den folgenden Code-Beispielen das Logging weg. Der Logger ist hier eine eigene kleine Implementation um in eine Textdatei und in das Windows Event Log zu schreiben.

Der TcpListener

Der TcpListener aus dem Namespace System.Net.Sockets, hängt sich an die angegebenen IP-Adresse und den angegebenen Port und lauscht auf eingehende Anfragen. Das ist unser Einstiegspunkt. Hier kommen die Requests rein, die wir filtern bzw. mitlesen wollen.

In folgenden Beispiel ist die komplette Klasse Proxy zu sehen.

public class Proxy
{
    private TcpListener _tcpListener;
    public IPAddress ListenToIp { get; set; }
    public int ListenOnPort { get; set; }
       
    public void Start()
    {
        Stop();
        ServicePointManager.ServerCertificateValidationCallback +=
            (sender, certificate, chain, policyErrors) => true;

        _tcpListener = new TcpListener(ListenToIp, ListenOnPort);
        _tcpListener.Start();

        _tcpListener.BeginAcceptTcpClient(AcceptTcpClient.Run, _tcpListener);
    }
       
    public void Stop()
    {
        if (_tcpListener != null)
        {
            _tcpListener.Stop();
        }
        _tcpListener = null;
    }
}

Das erste was hier beim Start gemacht wird, ist einen eventuell laufenden TcpListener zu stoppen, um Konflikte zu vermeiden, wenn bereits eine Instanz auf den angegebenen Port lauscht.

Im zweiten Schritt deaktivieren wir die Server Zertifikat Validierung, um auch Antworten von Servern mit nicht validen Zertifikaten verarbeiten zu können.

Nun wird eine neue Instanz eines TcpListeners mit der IP-Adresse und der Portnummer erstellt und gestartet. Die nächste Zeile repräsentiert die komplette asynchrone Verarbeitung in dieser Bibliothek. Der Aufruf von BeginAcceptTcpClient lässt den TcpListener auf den nächsten eingehenden Request reagieren und einen TcpClient erstellen. Diesem Aufruf übergeben wir den Zeiger auf den Handler und den aktuellen TcpListener als AsyncState-Variable.

Der Handler ist die statische Methode Run in der Klasse AcceptTcpClient. Auch diese Klasse ist angenehm klein. Sie erzeugt einen TcpClient, lässt den TcpListener wieder weiter lauschen und delegiert weiter um die Streams zu bearbeiten:

Der TpListener wird aus den AsyncState ausgelesen. In der ersten Zeile innerhalb des Try-Blockes wird dann mit dem Aufruf EndAcceptTcpClient der TcpClient geladen, mit dem wir nun weiter arbeiten werden. Ganz am Ende der Methode Run, wird wieder die Methode BeginAcceptTcpClient des TcpListeners aufgerufen – wie in der Klasse Proxy – um auf die nächste eingehende Anfrage reagieren zu können. Das ist schon die ganze direkte Verwendung des TcpListeners:

public class AcceptTcpClient
{
    public static void Run(IAsyncResult result)
    {
        if (result.IsCompleted == false || !(result.AsyncState is TcpListener))
        {
            return;
        } 
       
        var tcpListener = result.AsyncState as TcpListener;

        try
        {
            var tcpClient = tcpListener.EndAcceptTcpClient(result);

            tcpClient.ReceiveBufferSize = Globals.BufferSize;
            tcpClient.SendBufferSize = Globals.BufferSize;

            var clientStream = tcpClient.GetStream();

            var state = new ClientConnectionState
                {
                    Session = new RequestSession(),
                    Client = tcpClient,
                    ClientStream = clientStream,
                    ClientStreamBase = clientStream,
                    Buffer = new byte[Globals.BufferSize],
                    MessageStream = new MemoryStream(),
                    IsSsl = false
                };

            clientStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadFromClient.Run, state);
        }
        catch(Exception ex)
        {
            Logger.Log("Error while attempting to complete async connection.");
            Logger.Log(ex);
        }

        // auf den nächsten Client warten und reagieren
        tcpListener.BeginAcceptTcpClient(AcceptTcpClient.Run, tcpListener);
    }
}

Der TcpClient wird nun so Konfiguriert, dass er mit der selben Puffergröße arbeitet, wie wir das das mit den Streams tun werden. 20 KB haben sich als optimale Größe herausgestellt. in der Regel wird man mit dem Wert etwas herum spielen werden. In diesem Fall müssen wir aber sicherstellen, dass der TcpCLient, die Leitungskapazität und unsere Stream-Behandlung einigermaßen gleich schnell abläuft.

Den Stream den wir hier vom TcpClient bekommen nennen wir nun den clientStream, da er die Verbindung mit dem Client offen hält.

Auch jetzt müssen wir asynchron weiterarbeiten. um den aktuellen Thread nicht zu blocken und vor allem, um Speicher-schonend weiter zu arbeiten. Wir rufen nun also die Methode BeginRead des clientStreams auf, erzeugen dafür eine Klasse ClientConnectionState die wir als AsyncState an den Aufruf übergeben. Ebenso nutzen wir den definierten Byte-Array-Puffer unseres ClientConnectionState, um Blockweise aus dem Stream zu lesen. Die statische Handler-Methode Run in der Klasse ReadFromClient wird nun so oft aufgerufen, bis der Stream zu Ende gelesen ist. Es werden also immer 20 KB ausgelesen und per ClientConnectionState an den Handler übergeben.

Alle Streams werden auf diese Art behandelt. So erreichen wir einen gleichmäßigen und Speicher-schonenden Datenfluss und können mehrere Anfragen parallel behandeln. Mehr dazu im nächsten Teil mit dem Thema: Streams optimal verarbeiten.

Holger Sirtl: Azure News on Friday (KW24/15)

Auch diese Woche gab’s wieder viele Nachrichten zur Microsoft Azure Plattform. Hier sind nähere Infos dazu…

Aktuelle Neuigkeiten

Datum Nachricht
12.06. Update to default partition count for Event Hubs
Die minimale Anzahl der Partitionen im Azure Event Hub wurde auf 2 reduziert. Default ist jetzt 4.
12.06. Azure AD, Microsoft Intune and Windows 10 – Using the cloud to modernize enterprise mobility!
Infos zum Zusammenspiel von Azure AD, Windows 10 und Intune für modernes Mobile Device Management.
11.06. Microsoft a Leader in 2015 Gartner Magic Quadrant for Client Management Tools
Microsoft wurde auch im Magic Quadrant für Client Management Tools in den Leader-Quadranten gesetzt.
11.06. Step through creating a Resource Manager-based Azure Virtual Machine with PowerShell
Anleitung für ein Resource Manager basiertes PowerShell Skript zur Verwendung als Runbook in Azure Automation
11.06. Microsoft Azure Adds Global Array of New Certifications, including US DoD DISA Level 2
Neue Azure Zertifizierungen: DISA L2 (USA), FISC (Japan), GCIO (Neu Seeland), MTSC (Singapur).
11.06. Querying and Editing DocumentDB Data Just Got Better
Weitere Verbesserungen im Azure DocumentDB Query und Document Explorer und neuer Scipt Explorer für JavaScript UDFs
10.06. Azure Premium Storage Generally Available – Australia East
Azure Premium Storage ist jetzt auch in Ost-Australien verfügbar.
10.06. MapR-based Hadoop Clusters Coming to the Azure Marketplace
Für HDInsight Fans: MapR wird neben Hortonworks weiterer Anbieter von Hadoop as a Service Installationen im Azure Marketplace.
10.06. Neues, kostenloses eBook zu Azure Web Apps für Entwickler
Neues, kostenloses eBook zu Azure App Service Web Apps für Entwickler zum Download bei Microsoft Press
09.06. Azure Backup is Now Available in Central US, North Central US, South Central US, East US2, Brazil South
Azure Backup ist jetzt in weiteren Regionen verfügbar.
09.06. Complimentary access to Gartner IDaaS MQ now available
Gartners IDaaS Magic Quadrant (mit Azure, AzureAD etc.)... hier gibt's kostenlosen Zugriff...
09.06. Azure Linux VM Infrastructure Monitoring and Diagnostics
Neue Möglichkeiten zum Monitoring verschiedener Performance Metriken von Azure Linux Virtual Machines
09.06. Additional updates to Support Site Extension for Azure App Service Web Apps
Support Site Extensions für Azure App Service Web Apps jetzt über das Azure Preview Portal verfügbar.
08.06. Query Store: A flight data recorder for your database
Mit Query Store die Historie von Azure SQL Database v12 Abfragen aufzeichnen und auswerten. Hier steht wie's geht.
08.06. Run Azure CLI as a Docker Container: Avoid installation and setup
Durch Ausführung des Azure Command Line Interface (CLI) als Docker Container schnell und plattformunabhängig mit Azure CLI loslegen.
08.06. SharePoint Server 2013 Dev/Test Environments
Verschiedene SharePoint Dev/Test Szenarien aufsetzen mit Resource Manager, Azure PowerShell und dem Azure Portal.

Neue Kurse in der MVA

Datum Nachricht
09.06. MVA: Einführung in den Azure App Service
Neuer MVA Kurs: Einführung in den Azure App Service mit Basics zu Web Apps, Mobile Apps, API Apps und Logic Apps

Neue Videos

Datum Nachricht
12.06. Episode 177: More API Management Features with Vlad Vinogradsky
Neue Cloud Cover Episode mit Schwerpunkt Azure API Management
11.06. The Docker Visual Studio Extension with Ahmet Alp Balkan
Azure Friday: Nutzung von Docker via Visual Studio Extension und Deployment in Azure Virtual Machines
11.06. Docker 101 with Ahmet Alp Balkan
Azure Friday: Grundlagen zu Docker und dessen Möglichkeiten u.a. in Azure Virtual Machines.

Marco Scheel: Links for 2015-06-13 [del.icio.us]

Jürgen Gutsch: Dependency Injection in ASP.NET MVC 6

Schon früh war es möglich Depency Injection mit ASP.NET MVC zu nutzen. Mit jeder Version wurde es etwas einfacher machbar. ASP.NET MVC, SignalR und Web API nutzten allerdings jeweils andere Implementationen

Dependency Injection ist nun ASP.NET 5, bzw. ASP.NET MVC 6 vereinheitlicht. Der komplette ASP.NET Stack (MVC, SignalR and Web API) nutzt nun den selben DI-Container.

Wie dieser Konfiguriert wird und wie dieser Ersetzt wird, schreibt Ed Charbeneau in folgendem ausführlichen Blog Beitrag: http://developer.telerik.com/featured/dependency-injection-in-asp-net-mvc6/

Dmitrij Doberstein: Installation of new Linux-image on Toradex Colibri iMX6

What we need


To create a Linux image we need next things:


Initial preparation:




Now we must check availability of next tools. If not available than install this:
  • mtools
  • symlinks
  • parted
  • awk



As next step we must manipulate update.sh. For this open update.sh 
  • cd /temp/imx6_image/Colibri_iMX6_LinuxImageV2.4
  • nano update.sh


and search for awk –V. Please replace –V through –W version and save file.


And now we can run the update.sh script with -o argument pointing to the mount point of above mentioned card (at this example SD-card was mounted to /media/toradex)
  • update.sh –o / media/toradex


If all went well, then next files must be available:
  • boot.vfat
  • configblock.bin
  • flash_blk.img
  • flash_eth.img
  • flash_mmc.img
  • imx6dl-colibri-cam-eval-v3.dtb
  • imx6dl-colibri-eval-v3.dtb
  • mbr.bin
  • root.ext3
  • u-boot.imx
  • uImage
  • versions.txt


Linux image Installation (here we use Iris board)

  • Connect the serial debug console to UARTA aka FFUART X13 using a null modem RS-232 cable and a 10 pin IDC to 9 pin D-sub male connector (DTK or Intel standard).
  • Now put micro SD card into the socket (Iris board >>> X10)
  • Apply power or reset
  • Hit any key to stop auto booting
  • Use the ‘run setupdate’ U-Boot command and then
  • Use the ‘run update’ U-Boot command



READY!!!

Norbert Eder: Softwarebranche: Bessere Entscheidungen durch Programmiererfahrung

Im Beitrag Should a Scrum Master be able to write code habe ich folgendes ausgesagt:

Is someone without development skills able to know what matters in software development? In my opinion, yes. It isn’t important to know how to solve a specific technical problem but what is really important to create a great product. [..] Long story short, a Scrum Master does not made decisions. Content decisions are made by the Product Owner and the development team is responsible for all technical decisions.

Zwar war die Aussage auf einen Scrum Master bezogen, dennoch hatte ich hier großflächiger gedacht. Mittlerweile sehe ich das etwas anders.

Jeder der an der Entwicklung einer Software beteiligt ist, muss wissen wie Softwareentwicklung funktioniert.

Das ist eine sehr allgemeine Aussage und hat erstmal nichts mit irgendwelchen Methoden oder Prozessen zu tun.

Wer auch immer die Planung eines Software-Projektes inne hat, muss die Auswirkungen seiner Entscheidungen kennen und beurteilen können. Nur so können die richtigen Prioritäten gesetzt werden. Ohne Kenntnisse ist das schwierig bis unmöglich. Das mag zu Beginn der Entwicklung oft gar nicht so auffallen, aber bei einem langfristigen Projekt müssen dann Basisimplementierungen schon mal getauscht werden, weil sich durch diverse Änderungen ein Engpaß entwickelt hat oder anderweitige Probleme auftreten. Da sind auch schnell mal Bibliotheken etc. zu aktualisieren, was vielleicht nicht kurz nebenbei geht, da Breaking Changes enthalten sind.

Natürlich kosten „technische Maßnahmen“ Zeit und es wäre cooler, an Features arbeiten zu können. Aber was ist, wenn beispielsweise Aktualisierungen Wochen oder Monate hinausgezögert werden? Irgendwann ist eine Aktualisierung mit annehmbarem Aufwand einfach nicht mehr möglich. Das resultiert dann darin, dass die Software technologisch veraltet. Das ist bei langjährigen Projekten und Produkten untragbar.

Bei fehlendem Verständnis fällt dann auch schnell mal die Aussage:

„Ihr Softwareentwickler wollt doch nur spielen und immer das Neueste“.

Das mag schon stimmen, aber gerade deswegen ist es auch wichtig und notwendig, dass der Entscheidungsträger Ahnung von der Materie hat. Ist dem nicht so, können Entscheidungen nur willkürlich getroffen werden. Keine gute Wahl wenn man an das Projekt/Produkt, das Wohl des Unternehmens, dessen Mitarbeiter und die Kunden denkt …

PS: Schön langsam bin ich ja der Meinung, dass jeder, ausnahmslos jeder das Programmieren erlernen muss. Mittlerweile ist das wirklich essentiell.

The post Softwarebranche: Bessere Entscheidungen durch Programmiererfahrung appeared first on Norbert Eder.

codefest.at [MS]: “Lernen Sie Microsoft Edge kennen”– und mehr für Web Entwickler

Vor kurzen hat unser Schweizer Kollege Simon A. Strebel einen interessanten Artikel zum Thema “Microsoft Edge, den neuen, speziell für Windows 10 entwickelten Webbrowser”veröffentlicht.

Neben einer Einführung in Edge (ehemals Project Spartan) erklärt er wie wir alle auf die Entwicklung dieses Browser Einfluss nehmen können und verlinkt – meiner Meinung nach für alle Webentwickler interessant – zu einigen Tools, die das Testen und die Entwicklung für unterschiedliche Plattformen und Browser vereinfachen sollen. Eines dieser Tools ist Visual Studio Code, die neue Entwicklungsumgebung für Windows, Mac OSX und Linux.

Zum Artikel…

Holger Sirtl: Neues, kostenloses eBook zu Azure Web Apps für Entwickler

Microsoft Press hat ein neues eBook zu Azure veröffentlicht:

Azure Web Apps for Developers

Dieses steht als PDF zum Download zur Verfügung.

4744_9781509300594_7A8756C5

Für alle, die Web Apps in Aktion sehen wollen, möchte ich auf meinen Kurs in der Microsoft Virtual Academy zum Azure App Service hinweisen, der im zweiten Modul speziell Azure Web Apps behandelt.

Inhalt

Das Buch umfasst vier Kapitel:

  • Kapitel 1: “Microsoft Azure Web Apps”
    Hier werden Konzepte wie Azure Resource Groups und App Service Pläne vorgestellt. Web Apps werden erstellt und konfiguriert. Dabei werden auch Themen wie Deployment Slots und Continuous Deployment mit Visual Studio Online behandelt.
  • Kapitel 2: “Azure WebJobs”
    Dieses Kapitel widmet sich der Hintergrundverarbeitung von Tasks via WebJobs und der Verwendung des WebJobs SDKs.
  • Kapitel 3: “Scaling Azure Web Apps”
    In diesem Abschnitt geht es um die Skalierung von Web Apps via Auto-Scaling in Abhängigkeit verschiedener Performance Metriken.
  • Kapitel 4: “Monitoring and Diagnostics”
    Die Überwachung und Möglichkeiten zur Fehlersuche bilden den Inhalt dieses letzten Kapitels.

Weitere Informationen

Jürgen Gutsch: HTTP Sniffer Part 2: Grundlegendes zur Funktionsweise

Inhalt

Grundlegendes zur Funktionsweise

Sowohl Fiddler, als auch der Sniffer den ich hier beschreiben möchte, ist nichts anderes als ein Proxy Server, der Lokal auf dem Rechner läuft, dessen Traffic mitgelesen, bzw. gefiltert werden soll.

Das heißt der komplette Traffic wird umgeleitet zu diesem Proxy und dort weiterverarbeitet. Das passiert systemweit in den Proxy Einstellungen der Internet Optionen die unter anderem über den Internet Explorer erreichbar sind. Einige andere Browser nutzen eigene Proxy Einstellungen die ebenfalls entsprechend gesetzt werden müssen. Mehr dazu später im Detail.

In Richtung der Browser verhält sich dieser Sniffer wie ein Server: Er nimmt die Requests entgegen und beantwortet diese. In die andere Richtung ist dieser Sniffer ein Browser, der die Anfragen an die eigentlichen Webserver sendet und die Antworten entgegennimmt.

image

Der Proxy befindet sich also zwischen dem echten Server und dem Client. Auf die selbe Art findet übrigens auch eine Man-in-the-Middle-Attacke statt. Diesen Hinweis merken wir uns, da er später in Verbindung mit der SSL Verschlüsselung wieder wichtig wird.

Die Hauptsächliche Arbeit findet in der Mitte statt.

Wir benötigen also ein kleines Programm oder einen Service, welcher auf einem speziellen Port auf eingehenden Traffic lauscht und verarbeitet. Das könnte z. B: Port 12345 sein. Die Proxy Einstellungen müssten also wie folgt aussehen:

image

In dieser Serie gehe ich nicht darauf ein, wie die Einstellungen für alle Clients automatisch geändert werden. In diesem Fall werden die Einstellungen manuell gesetzt werden müssen. Auf diese Art kann auch ein spezieller Browser zum testen genutzt werden. Und das System bleibt wie es ist. Zum Beispiel hat Firefox eigene Proxy Einstellungen.

Geschrieben ist alles in C#. Damals .NET 4. Jetzt werde ich es mit .NET 4.6 neu aufsetzen. Die einzige externe Abhängigkeit ist Mono.Options, die ich inzwischen in jede Console App mit reinnehme.

Um jede Art von Traffic lesen zu können, vor allem um auch SSL verschlüsselten Traffic lesen und senden zu können, wird ein TcpListener verwendet (mehr dazu im nächsten Teil). Weiterhin werden wir uns -  da wir uns auf Socket-Ebene (OSI Level 5) befinden - mit den zu lesenden Protokollen auseinandersetzen müssen. In dieser Serie gehe ich der Einfachheit halber allerdings nur auf HTTP und HTTPS ein.

Dieser Sniffer arbeitet also mit NetworkStreams, die der TcpClient zur Verfügung gestellt wird. Der TcpClient wiederum wird vom TcpListener bereitgestellt, sobald sich ein Client mit dem Listener verbindet. Dieser Stream wird im weiteren Kontext von mit ClientStream genannt, da dieser die Verbindung zum Client aufrecht erhält

Um mich nun mit dem Remote Server zu verbinden, muss ich die HTTP-Header Informationen aus dem ClientStream auslesen und die IP und den Port des angefragten Remote-Host ermitteln. Mit diesen Daten kann ich dann wiederum einen TcpClient erstellen, mit dem ich eine Socket-Verbindung zum Remote-Server herstellen kann. Diese Verbindung liefert mir ebenfalls einen NetworkStream, den ich im weiteren Kontext RemoteStream nennen werde.

Das parsen des HTTP Request Headers ist recht einfach. Da dieser Zeilenweise aufgebaut ist. Ich kann also den Stream ab Position 0 zeilenweise auslesen, bis zur ersten Leerzeile ab dann folgt der Body, der erst später interessant wird.

Jeder Request beginnt mit einem HTTP Verb (GET, POST, etc.) mit einer Besonderheit: Eine Anfrage per HTTPS wird nämlich zuerst mit dem Verb CONNECT geführt. CONNECT ist im Prinzip die Anfrage um SSL Tunneling über einen Proxy zu ermöglichen. Erst wenn die CONNECT Anfrage beantwortet ist, wird die GET oder POST Anfrage per HTTPS vom Browser abgeschickt. Dieser Teil muss also gesondert behandelt werden.

Die beiden Streams ClientStream und RemoteStream werden – soweit erforderlich – permanent offen gehalten. NetworkStreams haben die Eigenschaft, dass sie sowohl ausgelesen, also auch beschrieben werden können, wobei nie beide Seiten gleichzeitig schreiben können. Man muss also warten bis eine Seite fertig ist mit schreiben.

Da der Proxy sehr performant sein sollte, ist alles asynchron aufgebaut. Sobald ein TcpClient erstellt wurde, lauscht der TcpListener schon wieder auf die nächste Verbindung. Mehrere Client- und RemoteStreams können so parallel verarbeitet werden

Die aktuelle Lösung reduziert die Netzwerk-Performance spürbar und hat sicherlich noch optimierungspotential. Allerdings ist der Performanceverlust nicht störend und man gewöhnt sich dran. Während der Entwicklungszeit damals hatte ich den Proxy als Windows Service zwei Wochen auf meiner Maschine am laufen. Eating your own dog food

Im nächsten Teil zum TcpListener zeige ich nun endlich auch etwas Code.

friends header

bloggers headline

links header

 
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.