Spring Boot macht Webhook-Endpoints mit @RestController einfach, aber Spring Security CSRF und JSON-Converter können Payloads blockieren oder verändern, bevor der Handler läuft. Lokales Testen soll Raw-byte[]-Zugriff, CSRF-Ausnahmen auf Webhook-Pfaden und Signaturprüfung auf unveränderten Bytes beweisen.
@RestController-Webhook-Endpoint anlegen
Webhook-Controller schlank halten. Raw Bytes annehmen, Signatur prüfen, dann deserialisieren:
@RestController
@RequestMapping("/webhooks")
public class StripeWebhookController {
@PostMapping("/stripe")
public ResponseEntity handle(
@RequestBody byte[] payload,
@RequestHeader("Stripe-Signature") String signature) {
if (!verifier.isValid(payload, signature)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
JsonNode event = objectMapper.readTree(payload);
handler.process(event);
return ResponseEntity.ok().build();
}
}
@RequestBody byte[] erhält den exakten Payload von Tomcat — ideal wenn Anbieter rohes JSON signieren.
Raw-Body über HttpServletRequest lesen
Alternativ direkt aus der Servlet-Request lesen:
byte[] body = request.getInputStream().readAllBytes();
String sig = request.getHeader("Stripe-Signature");
Nicht zuerst an POJO oder Map binden — Jackson-Re-Serialisierung bricht HMAC. Siehe Leitfaden zur Signaturprüfung.
CSRF nur für Webhook-Pfade deaktivieren
Spring Security aktiviert CSRF standardmäßig. Webhook-POSTs scheitern mit 403 ohne server-to-server-Ausnahme:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.ignoringRequestMatchers("/webhooks/**"));
return http.build();
}
}
Ignore-Pattern auf /webhooks/** begrenzen — CSRF nicht global abschalten.
Signatur-Header vor Business-Logik prüfen
Provider-Header lesen, Digest aus dem Byte-Array berechnen, constant-time vergleichen. Bei Mismatch 401, bei Erfolg schnell 200 für weniger Retries.
Lokaler Tunnel-Workflow
- App starten:
./mvnw spring-boot:runauf Port 8080. - Tomcat exponieren:
npx portpreview 8080. - Tunnel-URL + Pfad ins Provider-Dashboard.
- Test-Event senden und Logs beobachten.
- Gleiche Event-ID wiederholen für Idempotenz — siehe Retry-Muster.
Häufige Stolperfallen
Filter-Reihenfolge und Body-Verbrauch
Filter die den Stream vor dem Controller lesen, hinterlassen leeren Stream. ContentCachingRequestWrapper nutzen wenn nötig.
Globales @RequestBody-Binding
Globales @ControllerAdvice das JSON früh parst, kann Bytes ändern. Webhook-Endpoints mit byte[] isolieren.
Langsame Handler lösen Retries aus
Schnell bestätigen, async verarbeiten, per Event-ID deduplizieren.
Weiterführend
Grundlagen finden Sie unter localhost-Tunneling-Grundlagen und praktisches lokales Webhook-Debugging. Zur Signaturmechanik siehe den Leitfaden zur Signaturprüfung. Für duplikatsichere Handler lesen Sie Retry- und Idempotenz-Muster. starten Sie PortPreview kostenlos.
![Ein Spring Boot RestController auf embedded Tomcat prüft Webhook-Signatur-Header aus Raw-byte[]-Payload über einen lokalen Tunnel.](/_next/image?url=%2Fimages%2Farticles%2Fspring-boot-webhook-local-testing%2Fcover.png&w=3840&q=75)