Callbacks validieren
TL;DR – Eingehende HTTP-Callbacks von FIT-Connect über HMAC (SHA-512 über
{timestamp}.{body}) und Zeitstempel prüfen, bevor Sie reagieren. Beide SDKs liefern dafür
CallbackValidationUtil; der Callback selbst sagt nur, dass etwas anliegt — die Nachrichten holen
Sie danach authentifiziert ab.
Warum validieren?
Ohne HMAC-Prüfung könnte ein Angreifer beliebige HTTP-Requests an Ihren Callback-Endpunkt schicken und Ihre Anwendung in Geschäftsprozesse zwingen, die zu unautorisierten Datenzugriffen führen.
HMAC-Signatur prüfen
- Java
- .NET (C#)
Das Java-SDK bietet eine CallbackValidationUtil-Utility-Klasse:
import dev.fitko.fitconnect.sdk.util.CallbackValidationUtil;
import dev.fitko.fitconnect.core.validation.api.ValidationResult;
@PostMapping("/fit-connect/callback")
public ResponseEntity<Void> onCallback(
@RequestHeader("callback-authentication") String hmac,
@RequestHeader("callback-timestamp") Long timestamp,
@RequestBody String body) {
ValidationResult result = CallbackValidationUtil.validateCallback(
hmac, timestamp, body, callbackSecret);
if (result.isError()) {
LOGGER.warn("Ungültiger Callback: {}", result.message());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
handleCallback(body);
return ResponseEntity.ok().build();
}
CallbackValidationUtil (Fitko.FitConnect.Core.Callbacks) prüft HMAC und Zeitstempel — ohne
konfigurierten SDK-Client, also auch in einem schlanken Callback-Endpunkt. Lesen Sie den Body
roh, bevor Model Binding die Bytes verändert:
using Fitko.FitConnect.Core.Callbacks;
app.MapPost("/fit-connect/callback", async (HttpRequest request, IOrganisationClient organisation) =>
{
using var buffer = new MemoryStream();
await request.Body.CopyToAsync(buffer); // Bytes exakt wie gesendet
var result = CallbackValidationUtil.ValidateCallback(
request.Headers[CallbackHeaders.Authentication],
request.Headers[CallbackHeaders.Timestamp],
buffer.ToArray(),
callbackSecret);
if (!result.IsValid)
{
logger.LogWarning("Ungültiger Callback: {Reason}", result.GetErrorMessage());
return Results.Unauthorized();
}
// Der Callback sagt nur, DASS etwas anliegt — jetzt authentifiziert abholen
var waiting = await organisation.FetchAvailableSubmissionsFromDestination(myDestinationId);
await queue.EnqueueAsync(waiting);
return Results.Accepted();
});
Die Überladungen nehmen den Body als byte[] oder string und den Zeitstempel als long oder
rohen Header-String; CallbackValidationUtil.DefaultMaxAge (5 Minuten) begrenzt die zulässige
Abweichung in beide Richtungen.
Wenn Sie mehrere Callback-Endpunkte haben, kapseln Sie die Prüfung in einer ASP.NET-Middleware oder einem Endpoint-Filter.
Callback-Typen unterscheiden
FIT-Connect sendet drei Arten von Callbacks. Den Typ erkennen Sie am Body bzw. am
type-Feld (siehe Callback-Dokumentation):
| Typ | Wann | Empfänger |
|---|---|---|
NewSubmissionsCallback | Neue Einreichung beim Zustellpunkt eingegangen | Verwaltungssystem |
NewRepliesCallback | Neue Antwort (Reply) für einen Case eingegangen | Onlinedienst (Sender) |
NewEventsCallback | Neues Event im Eventlog (z. B. accepted/rejected) | Sender oder Subscriber |
Häufige Stolperfallen
- Body roh lesen: Der HMAC gilt über die Bytes, die FIT-Connect gesendet hat. Sobald ein
Framework den JSON-Body deserialisiert und neu serialisiert, ändern sich die Bytes und die
Prüfung schlägt fehl. Puffern Sie den Request-Body vor dem Model Binding (ASP.NET Core:
request.EnableBuffering()oder wie oben direkt ausrequest.Bodykopieren; Spring:@RequestBody String body). - Timestamp-Drift: Die Prüfung berücksichtigt den Zeitstempel. Wenn Ihre Serveruhr stark abweicht, schlägt die Validierung fehl. NTP einrichten.
- Secret-Rotation: Wechseln Sie das Callback-Secret im Self-Service-Portal, müssen beide Versionen für eine Übergangszeit nebeneinander geprüft werden.
Weiterführende Themen
- Funktionsweise von Callbacks – Header, Retries, HMAC-Algorithmus
- Status verfolgen – wenn Sie statt Callbacks lieber pollen wollen
- Anträge abholen und prüfen – was nach dem Callback passiert