IIS globales HTTP Modul

Man kann in ASP.NET Webforms (und MVC) Anwendungen recht einfach Logik in die HTTPipeline einklinken. So wird jeder Request zusätzlich bearbeitet. Die Konfiguration der Module findet sich in der Web.Config. Die Idee ist allerdings das Modul global auf Webserver Ebene zu registrieren und damit für alle Websites gültig zu haben,

Das HTTP Module

Mit folgendem VB.NET Code wird ein Querystring ausgelesen und als Cookie hinzugefügt. Die Idee dahinter ein Affiliate Marketing System für das gesamte ppedv Ecosystem zu bauen. Dazu wird eine Klasse angelegt die das Interface HtttpModule implementiert. Da hier kein Context in der RequestPipline direkt verfügbar ist wird dieser injiziert.

   1:  Public Class CookiePipe
   2:      Implements IHttpModule
   3:      Private WithEvents _context As HttpApplication
   4:      Public Sub Init(context As HttpApplication) Implements IHttpModule.Init
   5:          _context = context
   6:      End Sub
   7:      Public Sub Dispose() Implements IHttpModule.Dispose
   8:      End Sub
   9:   
  10:      Public Sub OnLogRequest(ByVal source As Object, ByVal e As EventArgs) Handles _context.LogRequest
  11:          Dim affid = _context.Request.QueryString("affid")
  12:          If Not IsNothing(affid) Then
  13:              Dim myCookie As HttpCookie
  14:              myCookie = New HttpCookie("affid")
  15:              myCookie.Value = affid
  16:              myCookie.Domain = "ppedv.de"
  17:              myCookie.Expires = Date.Now.AddHours(4)
  18:              Debug.Write(myCookie.Expires)
  19:              _context.Response.Cookies.Add(myCookie)
  20:          End If
  21:      End Sub
  22:  End Class

Diese Datei lässt sich in einer Website im Ordner App_Code ablegen und in der Web.Config registrieren.

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
        <add name="Query2CookieModule" 
type="Query2CookieModule.CookiePipe, Query2CookieModule"/>

Allerdings gilt das dann nur für eine Website. Das Ziel ist IIS weit dieses Setting zu haben,

Installierbares Assembly

Um im IIS das .NET Modul nutzen zu können, muss man eine DLL daraus machen und (vermutlich) im Global Assembly Cache registrieren (GAC).

Dazu erstellt man in Visual Studio ein neues .NET Klassen Bibliothek Projekt (hier Query2CookieModule genannt). Referenziert System.Web (deswegen kein .NET Standard 2.0).

Der Code für die Worker Klasse CookiePipe wie oben. Dann wird das Assembly signiert mit Visual Studio 2019. Eigenschaften des Projekts – Signierung – Assembly Signieren. Dabei wird einen .snk Datei erzeugt.

image

Beim kompilieren wird die DLL erzeugt, die ich am Webserver in das Verzeichnis C:\Windows\System32\inetsrv\ kopiere.

GACUTIL

Auf dem Webserver ist das Tool Gacutil nicht vorhanden. Insofern wird ein Umweg über Powershell gewählt. Die Powershell Console per Administrator Rechte starten.

   1:  Set-location "C:\Windows\System32\inetsrv"
   2:  [System.Reflection.Assembly]::Load("System.EnterpriseServices, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
)
   3:  $publish = New-Object System.EnterpriseServices.Internal.Publish
   4:  $publish.GacInstall("C:\Windows\System32\inetsrv\Query2CookieModule.dll")

Blöd ist, das egal was man tut, keine Fehlermeldung angezeigt wird. Es hilft nur der Blick in den Event Viewer (Ereignisanzeige). Wenn es klappt taucht ein neues Verzeichnis im Windows Server auf unterhalb von

C:\Windows\Microsoft.NET\assembly\gac_msil

Darin findet sich nun das Assembly und der Strong Name im Verzeichnisnamen. Diesen benötigt man um dann wiederrum in der globalen Konfiguration des Internet Information Servers das Modul zu registrieren. Datei applicationhost.config Pfad C:\Windows\System32\inetsrv\config

   1:     <add name="Query2CookieModule" 
type="Query2CookieModule.CookiePipe, Query2CookieModule,Version=1.0.0.0,
Culture=neutral, PublicKeyToken=d63479dc63b0f141"
preCondition="managedHandler" />
   2:              

Am besten den IIS neu starten mit iisrestart.

Nun sind alle Websites die .NET verwenden mit dem Cookie versehen. Leider aber nicht die aspnet core Websites, weil deren Application Pool unmanaged läuft. Ich müsste also C++ nutzen um ein natives IIS Modul zu schreiben.

Kommentare sind geschlossen