Der AS4 Outbound Sender empfängt signierte und verschlüsselte AS4-Nachrichten vom Crypto Operations Service via Message Broker und versendet diese per HTTP(S) an den Marktpartner. Die versendete Nachricht wird zur Persistierung an den AS4 Message Service weitergeleitet. Die empfangene Empfangsbestätigung (Receipt) des Marktpartners wird zur Signaturprüfung an den Crypto Operations Service übergeben.
Features
| Feature | Property | Default | Beschreibung |
|---|---|---|---|
| Kryptografie überspringen | skipCrypt |
false |
Deaktiviert die Anbindung an Crypto Operations (nur für Entwicklung) |
| mTLS | client.ssl.enabled |
false |
Aktiviert mutual TLS für ausgehende AS4-Verbindungen |
| SSL Startup-Check | startupSslCheck |
false |
Prüft beim Start ob die SSL-Konfiguration erfolgreich ist (Health-Endpoint) |
| SSL Trust-Info | ssl.trust-info |
false |
Aktiviert die Abfrage von Trust-Informationen für TLS |
| Proxy | proxyEnable |
false |
Aktiviert einen HTTP-Proxy für ausgehende Verbindungen |
| Zertifikat-Cache-Aktualisierung | clear-certificate-cache |
0 0 6 * * * |
Cron-Ausdruck für die automatische Cache-Aktualisierung |
| Keystore-Dateien löschen | deleteKeystoreFiles |
false |
Löscht temporäre Keystore-Dateien nach Verwendung |
| Revocation-Status-Cache | revocation.status.cache.enabled |
false |
Aktiviert einen Cache für den Sperrstatus von Zertifikaten |
| Trust-Info-Cache | ssl.trust-info.cache.enabled |
true |
Aktiviert einen Cache für Trust-Informationen |
| Alle Content-Types akzeptieren | acceptResponseAllContentTypes |
true |
Akzeptiert beliebige Content-Types in Partner-SOAP-Antworten |
| Delay-Queue | delayExchangeName |
as4.outbound.delay |
Verzögerte Wiederholung bei temporären Fehlern |
| Max Verbindungen pro Partner | as4.outbound.max-connections-per-mpid |
200 |
Begrenzt parallele HTTP-Verbindungen je Marktpartner |
Hardware Anforderungen
Eine Service-Instanz erfordert mindestens 512 MB RAM.
Wir empfehlen 0,4 CPU-Kerne je Instanz.
Logs werden auf die Festplatte geschrieben, entsprechend muss genügend Speicherplatz vorhanden sein.
Abhängigkeiten
Der Service greift auf einen Message-Broker zu, um Nachrichten zu empfangen und zu versenden.
Der Service nutzt die REST API des Security Server FSS. Der FSS muss im Hintergrund auf ein HSM zugreifen können.
Der Service verbindet sich per AS4 mit zahlreichen anderen AS4 Endpunkten. Dies beinhaltet auch externe AS4-Endpunkte.
Einfache Konfiguration der as4-outbound-sender.properties
Der AS4 Outbound Sender versendet die Edifact Nachricht als AS4 Nachricht an den Marktpartner. Anschließend wird diese AS4 Nachricht als Business Message an den AS4 Message Service und die erhaltene Bestätigung als Receipt an den Crypto Operations übergeben.
Dazu benötigt der AS4 Outbound Sender die Angaben zum Message-Broker.
rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest
Mit skipCrypt lässt sich die Anbindung zum Crypt Operation für Entwicklungszwecke ausschalten.
skipCrypt=false
AMQP Konfiguration
Falls Sie das Standard Routing nutzen, muss das Routing nicht weiter konfiguriert werden. Wenn Sie Ihr Routing anpassen möchten, lesen Sie die folgende Dokumentation.
Die Property consumer.max.attempts verhindert das mehrfache Versenden der Nachricht, wenn die Versendung fehlgeschlagen oder ein anderer Fehler aufgetreten ist.
consumer.max.attempts=1
Default: 3
Das Intervall zwischen den einzelnen Versuchen kann konfiguriert werden. Der Wert ist in Millisekunden angegeben
consumer.retry.interval=2000
Default: 1000
Empfang der AS4 Nachricht
Der Consumer empfängt die signierte AS4 Nachricht über die Queue as4.outbound.default vom Crypto Operations. Siehe AMQP Routing Konfiguration weiter unten.
AMQP Routing Konfiguration
Im Standard-Routing ist keine weitere Konfiguration nötig. Die folgende Tabelle gibt eine Übersicht über alle vom Service genutzten Exchanges und ihre Gegenstellen. Die Default-Queue ergibt sich aus <exchange>.default.
| Richtung | Property | Exchange | Default-Queue | Gegenstelle | Zweck |
|---|---|---|---|---|---|
| Consumer | cryptoConsumerExchangeName |
as4.outbound |
as4.outbound.default |
Crypto Operations | Empfang der signierten/verschlüsselten AS4-Nachricht zum Versand |
| Consumer | delayExchangeName |
as4.outbound.delay |
as4.outbound.delay.default |
self (Delay-Queue) | Verzögerte Wiederholung bei temporären Sendefehlern |
| Producer | businessMessageExchangeName |
as4.messages |
as4.messages.default |
AS4 Message Service | Versand der AS4 Business Message (auch Fallback bei Crypto-Fehlern) |
| Producer | receiptCryptoExchangeName |
as4.verify |
as4.verify.default |
Crypto Operations | Weiterleiten der Empfangsbestätigung des Marktpartners zur Verifizierung |
| Producer | receiptExchangeName |
as4.receipt |
as4.receipt.default |
AS4 Message Service | “Leeres” Receipt bei Crypto-Fehler oder fehlgeschlagener Quittungs-Verifikation |
Begrenzung der Sendeversuche pro Nachricht:
consumer.max.attempts=1
Consumer-Gruppen anpassen
Für die Consumer-Exchanges können Gruppe und Binding-Routing-Key geändert werden. Bei deaktiviertem Routing muss bindingRoutingKey zwingend auf default gesetzt werden. Über max-concurrency lässt sich die Anzahl gleichzeitiger Verarbeitungsthreads einstellen.
cryptoConsumerGroup=default
cryptoConsumerMaxConcurrency=50
delayConsumerGroup=default
delayConsumerMaxConcurrency=20
spring.cloud.stream.rabbit.bindings.consumeSignedEncryptedMessage-in-0.consumer.bindingRoutingKey=default
Producer-Routing nach Header
Für Producer-Exchanges lässt sich das Routing über <exchangeProperty>HeaderName und <exchangeProperty>HeaderValues aktivieren. Nachrichten mit Werten, die nicht in HeaderValues aufgelistet sind, laufen weiterhin über die Default-Route. Die Gegenstelle muss entsprechend eingerichtet werden.
Mögliche HeaderName-Werte:
- tenant: ILN Nummer des Senders
- partner: ILN Nummer des Empfängers
- sector:
GAS,ELECTRICITY
Beispiel für businessMessageExchangeName:
businessMessageExchangeName=as4.messages
businessMessageHeaderName=tenant
businessMessageHeaderValues=9907647000008,9903111000003
Mindestens verfügbare Consumer
Es ist möglich dem Outbound-Sender vorzugeben, wie viele Consumer er mindestens vorhalten soll – unabhängig von der aktuellen Last. Somit werden Verzögerungen bei schwankenden Nachrichtenvolumen verhindert. Default: 1.
spring.cloud.stream.bindings.consumeSignedEncryptedMessage-in-0.consumer.concurrency=5
Delay Queue
Der Outbound Sender verschiebt bei bestimmten temporären Fehlern (z.B. nicht erreichbarer Marktpartner) Nachrichten in eine Delay-Queue. Nach dem konfigurierten Intervall wird die Nachricht erneut verarbeitet (siehe AMQP Routing Konfiguration).
Maximale Verbindungen pro Partner
Um eine Überlastung einzelner Marktpartner-Endpunkte zu verhindern, kann die maximale Anzahl paralleler HTTP-Verbindungen pro Marktpartner-MPID begrenzt werden. Default: 200.
as4.outbound.max-connections-per-mpid=200
Connection Timeout
Der Timeout für die Verbindung zum Marktpartner (in Sekunden). Default: 300.
connectionTimeout=300
REST API
Die API bietet Server-Health Informationen an.
Der Port lässt sich über folgende Property konfigurieren: server.port=8080
Multi-Mandantenfähigkeit
Falls das AS4-System für mehrere Mandanten betrieben wird, kann der AS4 Outbound Sender für jeden Mandanten mindestens eine eigene Instanz haben. Bei einer solchen Konfiguration muss für jeden Mandanten eine eigene Queue eingerichtet werden. Über die Exchange muss entsprechend dem Mandanten in die jeweilige Queue geroutet werden.

Der AS4-Outbound-Sender arbeitet außerdem als AMQP Producer. Hier müssen keine weiteren Anpassungen vorgenommen werden.
Ausfallsicherheit
Wie üblich für Microservices können mehrere Instanzen des AS4-Outbound-Senders parallel betrieben werden, um die Last zu verteilen und Ausfallsicherheit zu gewährleisten.
In einem solchen Szenario konsumieren mehrere Instanzen die gleiche Queue und verteilen so die Nachrichten.

Der AS4-Outbound-Sender arbeitet außerdem als AMQP Producer. Hier müssen keine weiteren Anpassungen vorgenommen werden.
mTLS
Der AS4-Outbound-Sender fungiert als AS4-Client, der die Geschäftsnachricht an einen AS4-Server sendet.
Um mTLS auf der Seite des AS4-Outbound-Senders zu aktivieren, müssen zum einen JDK_JAVA_OPTIONS gesetzt und zum anderen in der application.properties gewissen Eigenschaften gesetzt werden:
JDK_JAVA_OPTIONS: "-Djdk.tls.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP384R1,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP256R1,TLS_ECDHE_ECDSA_WITH_SECP384R1,TLS_ECDHE_ECDSA_WITH_SECP256R1 -Djdk.tls.namedGroups=brainpoolP384r1,brainpoolP256r1,secp384r1,secp256r1"
In der application.properties sind folgende Properties zu setzen:
client.ssl.enabled=true
addressServiceUrl=http://localhost:8089/aep-as4-address-service
#ssl.tenant.id=9907647000008,9903111000003
fss.server.api.url=http://localhost:2222/fss/api/v1
ssl.partner.client=shared-client
Die TLS-Funktionalität kann über die Eigenschaft client.ssl.enabled ein-/ausgeschaltet werden (entweder durch Setzen auf true oder false). Der Standardwert für client.ssl.enabled ist false. Wenn die Eigenschaft nicht konfiguriert ist, wird sie daher standardmäßig auf „false“ gesetzt.
Der Service unterstützt parallel mehrere Mandanten. Wenn wir die Liste der Mandanten aus dem AS4-Address-Service automatisch abrufen möchten, müssen die Mandanten im AS4-Address-Service konfiguriert werden. Für diese Verbindung müssen wir die Eigenschaft addressServiceUrl in der Konfigurationsdatei definieren. (Alternativ kann die Liste der Mandanten, für die wir TLS konfigurieren möchten, wie gezeigt explizit in der Eigenschaft ssl.tenant.id mithilfe durch Kommas getrennter Werte angegeben werden.)
Hinweis: Konfigurieren Sie entweder die Eigenschaft addressServiceUrl oder ssl.tenant.id – konfigurieren Sie nicht beide Eigenschaften gleichzeitig.
Hinweis: Falls die addressServiceUrl genutzt wird, gilt: Der AS4-Address-Service muss ausgeführt und vom AS4-Outbound-Sender aus aufrufbar sein. Alle benötigten Mandanten müssen zur Bootzeit des AS4-Outbound-Senders verfügbar sein. Falls sich Mandanten zur Laufzeit ändern, müssen Sie den AS4-Outbound-Sender neu starten.
Für jeden Mandanten muss ein Marktpartner-TLS-Zertifikat/-Schlüssel im FSS/HSM vorhanden sein. Für jeden Marktpartner müssen alle Zertifikate der Aussteller-Zertifikatskette im FSS shared-client verfügbar sein. Die FSS-URL wird über die Property fss.server.api.url konfiguriert. Der shared-client wird über die Property ssl.partner.client angegeben. Wenn die Eigenschaft von ssl.partner.client nicht festgelegt ist, lautet der Standardwert shared-client.
Hinweis: Der FSS muss ausgeführt und vom AS4-Outbound-Sender aus aufrufbar sein. Alle benötigten Zertifikate müssen zur Bootzeit des AS4-Outbound-Senders verfügbar sein. Falls sich Zertifikate zur Laufzeit ändern, müssen Sie den AS4-Outbound-Sender neu starten.
Zertifikat Cache
Zertifikate werden intern gecached. Dieser Cache muss regelmäßig aktualisiert werden. Dies ist notwendig um z.B. den änderbaren Sperrlistenstatus aktuell zu halten.
Der Cache wird automatisch auf zeitlicher Basis aktualisiert, per Default alle 6 Stunden.
Das Zeitinterval der automatischen Aktualisierung für Zertifikat-Caches kann über die Eigenschaft clear-certificate-cache konfiguriert werden. Hierbei handelt es sich um einen Cron-Ausdruck. Beispiel:
# day of week ------------+
# month ----------+ |
# day of month --------+ | |
# hour ------+ | | |
# minute ----+ | | | |
# second --+ | | | | |
# | | | | | |
clear-certificate-cache=0 0 6 * * *
Weitere Details zur Cron-Konfiguration finden Sie in der Spring-Doku.
Widerrufstatus von Zertifikaten cachen
Um den Widerrufstatus von Zertifikaten zu cachen und nicht für jede Nachricht erneut abzurufen, muss folgender Wert in der application.properties gesetzt werden:
revocation.status.cache.enabled=true
Dann wird der Widerrufstatus der Marktpartnerzertifikate maximal einmal pro Stunde geprüft. Falls Probleme beim Abrufen des Widerrufstatus auftreten, wird der gecachte Status für maximal 6 Stunden verwendet. Diese Zeiträume können mit folgenden Konfigurationseinstellungen angepasst werden:
revocation.status.cache.max.usage=T6H
revocation.status.cache.refresh.after=T1H
Syntax: 1H für eine Stunde, 30M für 30 Minuten, 1D für einen Tag, oder Kombinationen wie 1d4H or 1H30M
Zwischenspeicherung des Ergebnisses der Partnerzertifikatsvertrauensprüfung
Folgende Eigenschaften können eingestellt werden. Nachfolgend sind die Standardwerte aufgeführt.
ssl.trust-info.cache.enabled=true
ssl.trust-info.cache.refresh.after=T1H
Logging der AS4 Verbindungen
Durch die Konfiguration des Bouncycastle Loggings auf DEBUG Level in der application.properties, können die AS4 Verbindungen geloggt werden.
logging.level.org.bouncycastle=DEBUG
Der Standard ist derzeit wie folgt konfiguriert:
logging.level.org.bouncycastle=WARN
Prüfung von nicht gespeicherten Partnerzertifikaten während des TLS-Handshakes
Während des TLS-Handshakes kann die Vertrauensprüfung des Partnerzertifikats nun auch durchgeführt werden, wenn das Zertifikat nicht im FSS gespeichert ist. Diese Prüfung findet im FSS statt. Wenn das Zertifikat im FSS gespeichert ist, werden diese Informationen für die Prüfung herangezogen. Wenn das Zertifikat nicht gespeichert ist, werden die Informationen aus dem Zertifikat verwendet und die Sperrliste von der Sub-CA heruntergeladen. Folgenden Prüfungen werden durchgeführt, um zu prüfen, ob das Zertifikat vertrauenswürdig ist:
- Zertifikatskette ist im FSS vorhanden und vertrauenswürdig
- Wenn das Zertifikat vorhanden ist: Aktiv oder inaktiv
- Validity/time slice
- Sperrlistenstatus
- Purpose ist TLS
Um diese Funktion zu aktivieren (FSS-URL ist ebenfalls konfiguriert):
ssl.trust-info=true
Wichtig ist zu beachten, dass für dieses Feature mindestens die FSS Version 2025-02-27-01 verwendet werden muss.
AS4-Outbound Delay Queue
Beim Senden von AS4-Nachrichten können während eines Sendeversuchs Fehler wie Timeouts oder Ausnahmen auftreten. Ohne einen dedizierten Verzögerungsmechanismus würden fehlgeschlagene Nachrichten direkt wieder in die Standard-Queue as4-outbound zurückveröffentlicht und sofort erneut verarbeitet. In Szenarien mit hohem Durchsatz entsteht dadurch eine enge Rückkopplungsschleife, bei der eine große Anzahl fehlgeschlagener Nachrichten für denselben Marktpartner kontinuierlich durch die Queue kreist, die verfügbaren Consumer blockiert und verhindert, dass fehlerfreie Nachrichten anderer Partner verarbeitet werden.
Um dies zu lösen, landen verzögerungsverursachende Nachrichten in as4-outbound-delay anstatt in as4-outbound. Dies dient zwei Zwecken: Es unterbricht die enge Wiederverarbeitungsschleife, die entstehen würde, wenn fehlgeschlagene Nachrichten sofort wieder an den Anfang der Standard-Queue zurückgegeben würden, und es stellt eine dedizierte Queue bereit, die unabhängig überwacht werden kann, um Backpressure und Fehlerraten pro Partner zu beobachten.
Sending the business message via delay queue
Der Service veröffentlicht die zu sendende Nachricht an den Partner und verarbeitet diese auch über die Queue as4.outbound.delay.default
delayExchangeName=as4.outbound.delay
The concurrency can be controlled by:
spring.cloud.stream.bindings.consumeDelayOutboundMessage-in-0.consumer.concurrency=5
Um dies zu beheben, wird die Eigenschaft as4.outbound.max-connections-per-mpid eingeführt, um die maximale Anzahl paralleler Verbindungen zu einem einzelnen Marktpartner zu einem bestimmten Zeitpunkt zu steuern. Wenn die Anzahl der aktiven Verbindungen für eine bestimmte MPID dieses Limit erreicht oder ein Fehler bei der Verarbeitung einer Nachricht auftritt, wird die Nachricht nicht erneut in die Standard-Queue as4-outbound veröffentlicht, sondern stattdessen in die dedizierte Queue as4-outbound-delay geleitet, wo sie wartet, bevor sie erneut versucht wird.
# Maximum parallel connections per partner
as4.outbound.max-connections-per-mpid=200
Der Standardwert (200) ist auf eine sehr hohe Zahl gesetzt, um das bestehende Normalverhalten beizubehalten. Es wird empfohlen, dieses Verhalten zu überschreiben, um es an die Anforderungen des Systems anzupassen.
Anhang: Gesamtkonfiguration
Proxy-Konfiguration
Falls ausgehende Verbindungen über einen HTTP-Proxy laufen müssen:
proxyEnable=true
proxyAddress=proxy.example.com
proxyPort=8080
proxyUser=
proxyPassword=
Default: proxyEnable=false. Proxy-Benutzer und -Passwort sind optional.
Keycloak
Falls der Outbound Sender auf geschützte Services (z.B. FSS) zugreifen muss, kann die Keycloak-Authentifizierung aktiviert werden:
keycloak.rest-client=true
keycloak.auth-server-url=http://host.docker.internal:9000/auth
keycloak.realm=as4
keycloak.resource=as4-backend
keycloak.credentials.secret=
keycloak.scope=
keycloak.username=
keycloak.password=
Default für keycloak.rest-client ist false.
Folgende Konfiguration reicht in einem Standard-System mit TLS aus: application.properties:
rabbitmq.host=rabbitmq3
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=${RABBITMQ_PASSWORD}
# Timeout default to 300 second
connectionTimeout=300
# Die automatische Aktualisierung für Zertifikat-Caches kann über die Eigenschaft konfiguriert werden: Standard ist 0 0 6 * * *
clear-certificate-cache=0 0 6 * * *
# Keystore-Dateien können während der Cache-Aktualisierung durch die Eigenschaft standardmäßig false gelöscht werden
deleteKeystoreFiles=false
#=== FSS ===#
fss.server.api.url=http://fss:2222/fss/api/v1
## Page size for fss requests
fss.page.size.value=100
#=== SSL Properties ===#
client.ssl.enabled=true
ssl.partner.client=shared-client
addressServiceUrl=http://localhost:8089/aep-as4-address-service
JDK_JAVA_OPTIONS:
JDK_JAVA_OPTIONS: "-Djdk.tls.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP384R1,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP256R1,TLS_ECDHE_ECDSA_WITH_SECP384R1,TLS_ECDHE_ECDSA_WITH_SECP256R1 -Djdk.tls.namedGroups=brainpoolP384r1,brainpoolP256r1,secp384r1,secp256r1"
Optionale Proxy Configuration
Es ist möglich den Outbound-Sender mit einem Proxy zu verbinden. Falls Basic-Authentifizierung mit User und Passwort nowendig sind, kann dies ebenfalls konfiguriert werden.
#=== Proxy Properties ===#
proxyEnable=false
proxyAddress=
proxyPort=
proxyUser=
proxyPassword=
Falls der Proxy benötigt wird, muss die Eigenschaft proxyEnable auf true gesetzt werden. Die proxyAddress gibt die Addresse (Host) an, unter welcher der Proxy verfügbar ist. Wenn der Proxy beispielsweise unter localhost läuft, wird 127.0.0.1 eingetragen. Sollte keine Authentifizierung mit User und Passwort erforderlich sein, können diese Eigenschaften leer bleiben.
Allgemeine Hinweise zur Konfiguration finden Sie hier.
View Me Edit Me