Skip to content

Installation

Voraussetzungen

  • Die .NET Core Runtime (8.0.0) Windows Hosting Bundle müssen installiert sein.
  • Der CMI Mandant muss als Authentifizierung STS gewählt haben.
  • Websocket-Protokoll ist unter Internetinformationsdienste / WWW-Dienste / Anwendungsentwicklungsfeatures aktiviert:

Anleitung

Es folgt eine Zusammenfassung, die den Betrieb des Push Services mit IIS beschreibt. Grundsätzlich kann der IIS gemäss der Dokumentation von Microsoft für einen ASP.NET Core Service konfiguriert werden.

  1. Internet Information Services (IIS) Manager öffnen.
  2. Unter Application Pools neuen Application Pool hinzufügen.
  3. Name des Application Pools kann frei gewählt werden.
  4. .NET CLR version muss: No Managed Code sein.
  5. Start application pool immediately: Aktivieren.
  6. Mit OK bestätigen.
  7. Unter Sites eine neue Website hinzufügen.
  8. Name der Site kann frei gewählt werden.
  9. Application Pool: Den vorhin erstellten Application Pool auswählen.
  10. Physical path: Pfad in welchem sich da API-Applikation des Push Services befindet.
  11. Binding: Type: Entweder http oder https (wir empfehlen https)
  12. Binding: IP-Adresse: All Unassigned
  13. Binding: Port: Frei wählbar.
  14. Binding: Hostname: Domain (bei http optional)
  15. Binding: Require Server Name Indication: optional
  16. Binding: Wenn https: SSL certificate: Ein gültiges SSL-certificate, welches auf dem Host name gebunden ist.
  17. Binding: Start Website immediately: optional (wir empfehlen: aktiviert)

Konfiguration Push-Service

Die Konfiguration erfolgt in der Datei appsettings.json vom Push-Service. Die nachfolgenden Unterkapitel beschreiben jeweils einen Toplevel-Eintrag.

Hinweis: Pfadangaben müssen mit doppelten Backslashes geschrieben werden.

Serilog

"Serilog": {
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
        {
            "Name": "File",
            "Args": {
                "rollingInterval": "Day",
                "rollOnFileSizeLimit": true,
                "fileSizeLimitBytes": 100000,
                "path": "%TEMP%\\push_mandant_log-{Date}.log"
            }
        }
    ]
  },

Dies ist die Serilog Konfiguration und wird für das Logging gebraucht. Details siehe: GitHub: serilog/serilog-settings-configuration.

Bei WriteTo muss unter Args der Pfad (path) für das Log File angepasst werden.

Host filtering

 "AllowedHosts": "*"

Ermöglicht die explizite Angabe vom Host. Für Details siehe: Host filtering with ASP.NET Core Kestrel web server

Server-Service

 "ServerService": {
    "apiBaseUrl": "https://mandant.kunde.ch/develop/private/api"
  },

apiBaseUrl ist die vollständige URL vom OWIN-private Endpoint vom Server-Service (inkl. Protokoll und Port). Falls ein Relay-Server im Einsatz ist, muss die URL von diesem angegeben werden.

Push-Service

"PushService": {
    "AllowedClients": [
        "http://localhost:4200",
        "https://web-mandant.kunde.ch"
    ],
    "PurgeRestoreStorageAfterSeconds": 180,
    "AllowDebug": false,
    "EnableDetailedErrors": false
},

Mit AllowedClients werden die erlaubten Client-Urls explizit angegeben. Je nach Systemumgebung kann ein Web Client über mehrere Urls erreichbar sein. Keine Wildcards. Die Werte PurgeRestoreStorageAfterSeconds, AllowDebug und EnableDetailedErrors sind optional. Defaultwerte entsprechen dem obigen Beispiel. PurgeRestoreStorageAfterSeconds gibt die Zeit an, wie lange bei einem Restore die Push-Meldungen im Memory gehalten werden (dieses Cacheing ist Client-übergreifend). Ist AllowDebug true, so können mit GET /api/debug/clients die aktuell verbunden Clients aufgelistet werden. Mit EnableDetailedErrors wird das erweiterter Errorhandling von SignalR (Websocket-Verbindung zwischen Client und Push-Service) eingeschaltet.

Authentication

Hinweis: Der Push-Service verbindet sich im normalen Betrieb mit dem Token vom Web Client mit dem Server-Service.

Einzig für den Restore (dem Web Client fehlen Push-Messages) fordert der Push-Service selber ein Token vom STS an. Eine diesbezügliche Fehlkonfiguration wird also nicht unmittelbar festgestellt.

Das Token wird vom Push Service wie folgt abgefordert:

  • bei Verwendung von STS 2: eine impersonated Server-zu-Server-Verbindung
  • bei Verwendung von STS 3: eine Verbindung mit Scope push-api Hinweis: Ab Push Service Version 3.0 ist dabei kein Backend User mehr notwendig und kann aus der STS 3 Konfiguration entfernt werden.

Für den CMI STS 3.x reicht eine vereinfachte Konfiguration. Der Push-Service detektiert zur Laufzeit, ob STS 2 oder STS 3 im Einsatz ist.

Konfiguration für CMI STS 3

Beim STS 3 reicht es den fix benannten Client pushServiceClient zu konfigurieren.

Push Service: appsettings.json

"security": {
    "authority": "https://sts3.kunde.ch/mandant/identity",
    "client_id": "pushServiceClient",
    "client_secret": "XXXxxxXXX"
}

In der Konfiguration von STS 3 muss für den Client pushServiceClient hinterlegt sein:

  • AllowedScopes: metatool und push-api
  • AllowedGrantTypes: client_credentials

STS 3: appsettings.json (Verfügbare Scopes)

  "Scopes": {
    "Api": [
      "metatool",
      "api",
      "push-api"
    ]
  }

STS 3: appsettings.mandant.json (Client Konfiguration für pushServiceClient)

{
    "ClientId": "pushServiceClient",
    "AllowedGrantTypes": [ "client_credentials" ],
    "ProtocolType": "oidc",
    "AllowAccessTokensViaBrowser": false,
    "AllowOfflineAccess": true,
    "ClientSecrets": [
        {
            "value": "XXXxxxXXX (als SHA512 Hash)",
            "description": "Push Service Client"
        }
    ],
    "AllowedScopes": [
        "push-api",
        "metatool"
    ]
}

Konfiguration für CMI STS 2.x

"security": {
    "authority": "https://sts.kunde.ch/identity",
    "impersonated_user": "admin",
    "client_id": "server",
    "client_secret": "XXXxxxXXX",
    "acr_values": "tenant:kunde.mandant"
}

Die client_id ist optional. Der Default ist server . Das client_secret entspricht auf Seite STS dem Secret beim Client mit der ClientId mit dem Wert von client_id. impersonated_user ist ein User-Name eines CMI-Users mit Admin-Rechten (nicht "Administrator").

Konfiguration CMI.Server.Service

Die Konfiguration erfolgt in der Datei metatool.ini vom CMI.Server.Service.

[PushService]
ServerUrl = https://push-mandant.kunde.ch
PushServiceClientSecret = XXXxxxXXX

ServerUrl ist die URL vom Push-Service. PushServiceClientSecret ist das in der Konfiguration vom Push Service eingetragene client_secret (und entspricht somit dem Secret in der STS 3 Konfiguration, dort jedoch muss das secret als SHA-512 Hash in der Konfiguration enthalten sein).

Konfiguration CMI Identity Server

Konfiguration für CMI STS 3.x

In Tenants.<Mandant>.Clients einen Client anlegen mit der Id pushServiceClient:

{
    "ClientId": "pushServiceClient",
    "AllowedGrantTypes": [ "client_credentials" ],
    "ProtocolType": "oidc",
    "AllowAccessTokensViaBrowser": false,
    "AllowOfflineAccess": true,
    "ClientSecrets": [
        {
            "value": "XXXxxxXXX (als SHA512 Hash)",
            "description": "push service client secret (als SHA512 Hash)"
        }
    ],
    "AllowedScopes": [ "push-api", "metatool"]
}

In ClientSecrets.0.value wird das (als SHA512 Hash) Secret eingetragen, welches der Push Service zur Authentifizierung verwenden muss.

Der ClientCredentialsBackendUser ist ab Push Service Version 3.0 nicht mehr notwendig und kann aus der Konfiguration des pushServiceClient's entfernt werden. Ebenso kann ein früher benotwendigter technische Benutzer (mit Administrationsrecht) für den Push Service entfernt werden.

Konfiguration für CMI STS 2.x

Die Konfiguration erfolgt in der Datei IdentityServer.json im CMI Identity Server als separaten Client:

{
    "Enabled":  true,
    "ClientId":  "pushServiceClient",
    "AccessTokenLifetimeInMinutes":  120,
    "Secret":  "dfcmihf§23dcmi"
},
{
    "Enabled": true,
    "ClientId": "server",
    "AccessTokenLifetimeInMinutes": 120,
    "Secret": "E2cCMIM4bIquHCMI"
},

Die ClientIds müssen pushServiceClient resp. server heissen. server für die impersonated Server-zu-Server-Verbindung.

Konfiguration CMI WebClient

Die Konfiguration erfolgt in der Datei config.json im WebClient

"push": {
    "serviceUrl": "https://push-mandant.kunde.ch/data"
},

serviceUrl ist Url vom Push-Service. Der Endpoint /data muss angegeben werden.

Ping / Versionsabfrage

Es gibt den anonymen Endpoint GET /info/version um die Kompatibilitäts Version vom Push-Service als JSON abzufragen. Diese muss mit dem im CMI Server Release hinterlegten übereinstimmen.

Health-Checks

Der Push Service bietet zwei verschiedene Arten von Health-Checks. Unter /healthz wird ein einfacher Health-Check bereitgestellt, der lediglich die Verfügbarkeit des Service über HTTP(s) testet. Er eignet sich für die Überwachung der Service-Verfügbarkeit durch bspw. Kubernetes oder andere Monitoring-Tools.

Zusätzlich zu den Health-Checks von cmi-infrastructure-healthchecks bietet der Push-Service einige weitere Endpunkte, die zum Prüfen des Systems verwendet werden können. Diese Endpunkte sind unter /info/ erreichbar. Folgende Endpunkte sind verfügbar:

/info/health

Mit GET /info/health erfolgt ein End-To-End-Check.

HTTP Returnwert: 200 resp. 503 bei Fehler. Fehlerdetails sind dann den Logs (Push-Service, STS, Server-Service) zu entnehmen.

/info/restore/health

Mit GET /info/restore/health wird Restore aufgerufen. Dieser Aufruf beinhaltet die (mit STS2: impersonated | mit STS3: push-api Scope) STS-Verbindung und auf Seite CMI Server Service eine Datenbankabfrage.

/info/compatibility

Mit GET /info/compatibility werden Informationen zur Kompatibilität abgefragt und angezeigt.

[!IMPORTANT]
Der /info/health Health-Check ist deutlich aufwändiger als der unter healthz ausgeführte Check und prüft zusätzlich zu den eigenen Services auch noch externe Abhängigkeiten (STS und Server-Service). Für den Betrieb in Kubernetes ist daher die Verwendung des /healthz Endpunktes zu empfehlen.