From 0f3bd209a1660cd7b5779eec78f9b8b92460007c Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sat, 4 Apr 2026 15:05:13 +0200 Subject: [PATCH] feat: add ForwardAuth endpoint for Traefik integration GET /auth/verify validates JWT and returns X-User-Id, X-User-Email headers for downstream service routing via Traefik middleware. Co-Authored-By: Claude Sonnet 4.6 --- .../saas/config/ForwardAuthController.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/net/siegeln/cameleer/saas/config/ForwardAuthController.java diff --git a/src/main/java/net/siegeln/cameleer/saas/config/ForwardAuthController.java b/src/main/java/net/siegeln/cameleer/saas/config/ForwardAuthController.java new file mode 100644 index 0000000..0609155 --- /dev/null +++ b/src/main/java/net/siegeln/cameleer/saas/config/ForwardAuthController.java @@ -0,0 +1,43 @@ +package net.siegeln.cameleer.saas.config; + +import net.siegeln.cameleer.saas.auth.JwtService; +import net.siegeln.cameleer.saas.tenant.TenantService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import jakarta.servlet.http.HttpServletRequest; + +@RestController +public class ForwardAuthController { + + private final JwtService jwtService; + private final TenantService tenantService; + + public ForwardAuthController(JwtService jwtService, TenantService tenantService) { + this.jwtService = jwtService; + this.tenantService = tenantService; + } + + @GetMapping("/auth/verify") + public ResponseEntity verify(HttpServletRequest request) { + String authHeader = request.getHeader("Authorization"); + if (authHeader == null || !authHeader.startsWith("Bearer ")) { + return ResponseEntity.status(401).build(); + } + + String token = authHeader.substring(7); + + if (jwtService.isTokenValid(token)) { + String email = jwtService.extractEmail(token); + var userId = jwtService.extractUserId(token); + + return ResponseEntity.ok() + .header("X-User-Id", userId.toString()) + .header("X-User-Email", email) + .build(); + } + + return ResponseEntity.status(401).build(); + } +}