From 3244efd5e0a6ab3cd60398a212aa883a9c536a91 Mon Sep 17 00:00:00 2001 From: StefanMoCoAt Date: Thu, 23 Apr 2026 10:53:52 +0200 Subject: [PATCH] =?UTF-8?q?###=20fix:=20behebe=20CORS-Probleme=20und=20Sta?= =?UTF-8?q?bilit=C3=A4tsfehler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - **MailController:** Erweitere `@CrossOrigin`-Headers und Methoden für Preflight-Checks. - **GlobalSecurityConfig:** Reaktiviere CORS und füge explizite `CorsConfigurationSource` hinzu. - **Tests:** Fix für `NoSuchBeanDefinitionException` bei Integrationstests. - **UI:** Aktualisiere Versionsmarker auf `v2026-04-23.15 - CORS STABILITY`. --- .../security/GlobalSecurityConfig.kt | 32 ++++++++++++++++--- .../mocode/mail/service/api/MailController.kt | 6 +++- .../03_Journal/2026-04-23_Plan-B-Formulare.md | 15 +++++++++ .../frontend/shell/web/WebMainScreen.kt | 2 +- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/backend/infrastructure/security/src/main/kotlin/at/mocode/infrastructure/security/GlobalSecurityConfig.kt b/backend/infrastructure/security/src/main/kotlin/at/mocode/infrastructure/security/GlobalSecurityConfig.kt index 9e413517..1938cff5 100644 --- a/backend/infrastructure/security/src/main/kotlin/at/mocode/infrastructure/security/GlobalSecurityConfig.kt +++ b/backend/infrastructure/security/src/main/kotlin/at/mocode/infrastructure/security/GlobalSecurityConfig.kt @@ -7,10 +7,16 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator -import org.springframework.security.oauth2.jwt.* +import org.springframework.security.oauth2.jwt.Jwt +import org.springframework.security.oauth2.jwt.JwtDecoder +import org.springframework.security.oauth2.jwt.JwtTimestampValidator +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter +import org.springframework.web.cors.CorsConfiguration +import org.springframework.web.cors.CorsConfigurationSource +import org.springframework.web.cors.UrlBasedCorsConfigurationSource @Configuration @EnableWebSecurity @@ -21,10 +27,8 @@ class GlobalSecurityConfig { fun filterChain(http: HttpSecurity): SecurityFilterChain { http .csrf { it.disable() } // CSRF nicht nötig für Stateless REST APIs - // WICHTIG: CORS explizit deaktivieren! - // Das API-Gateway kümmert sich um CORS. Die Microservices dürfen KEINE - // Access-Control-Allow-Origin Header setzen, sonst haben wir doppelte Header beim Client. - .cors { it.disable() } + // WICHTIG: CORS wieder aktivieren für Plan-B (Direktzugriff ohne Gateway möglich) + .cors { it.configurationSource(corsConfigurationSource()) } .sessionManagement { it.sessionCreationPolicy(SessionCreationPolicy.STATELESS) } .addFilterBefore(DeviceSecurityFilter(), UsernamePasswordAuthenticationFilter::class.java) .authorizeHttpRequests { auth -> @@ -71,4 +75,22 @@ class GlobalSecurityConfig { converter.setJwtGrantedAuthoritiesConverter(KeycloakRoleConverter()) return converter } + + @Bean + fun corsConfigurationSource(): CorsConfigurationSource { + val configuration = CorsConfiguration() + configuration.allowedOrigins = listOf( + "https://app.mo-code.at", + "https://api.mo-code.at", + "http://localhost:8080", + "http://localhost:8083", + "http://localhost:4000" + ) + configuration.allowedMethods = listOf("GET", "POST", "PUT", "DELETE", "OPTIONS") + configuration.allowedHeaders = listOf("*") + configuration.allowCredentials = true + val source = UrlBasedCorsConfigurationSource() + source.registerCorsConfiguration("/**", configuration) + return source + } } diff --git a/backend/services/mail/mail-service/src/main/kotlin/at/mocode/mail/service/api/MailController.kt b/backend/services/mail/mail-service/src/main/kotlin/at/mocode/mail/service/api/MailController.kt index 5a6e7138..829c4b72 100644 --- a/backend/services/mail/mail-service/src/main/kotlin/at/mocode/mail/service/api/MailController.kt +++ b/backend/services/mail/mail-service/src/main/kotlin/at/mocode/mail/service/api/MailController.kt @@ -39,7 +39,11 @@ data class NennungRequest( @OptIn(ExperimentalUuidApi::class) @RestController @RequestMapping("/api/mail") -@CrossOrigin(origins = ["http://localhost:8080", "https://nennung.mo-code.at", "https://app.mo-code.at"]) // Für Wasm-Web-App (Compose HTML/Wasm) +@CrossOrigin( + origins = ["http://localhost:8080", "https://nennung.mo-code.at", "https://app.mo-code.at", "https://api.mo-code.at"], + allowedHeaders = ["*"], + methods = [RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS] +) // Für Wasm-Web-App (Compose HTML/Wasm) class MailController( private val nennungRepository: NennungRepository, private val mailSender: JavaMailSender diff --git a/docs/03_Journal/2026-04-23_Plan-B-Formulare.md b/docs/03_Journal/2026-04-23_Plan-B-Formulare.md index 64126491..e453eef3 100644 --- a/docs/03_Journal/2026-04-23_Plan-B-Formulare.md +++ b/docs/03_Journal/2026-04-23_Plan-B-Formulare.md @@ -44,3 +44,18 @@ Die "Hallo Du!" Test-UI wurde durch produktive, fachlich korrekte Formulare erse - `PlatformConfig.wasmJs.kt`: Alle Logiken zur Erkennung von URLs wurden temporär deaktiviert. Die Funktionen `resolveMailServiceUrl()` und `resolveApiBaseUrl()` geben nun **zwingend** `https://api.mo-code.at` zurück. - Dies umgeht jegliches Caching von `index.html` oder fälschlich injizierte Umgebungsvariablen. - UI-Marker auf `v2026-04-23.13 - RADICAL HTTPS PRIORITIZATION` aktualisiert. + +### 2026-04-23 10:45 - Version 14: CORS Reanimation +- **Problem**: Trotz HTTPS-Fix blockierte die CORS-Policy im Backend die Anfragen von `https://app.mo-code.at`. +- **Lösung**: + - `GlobalSecurityConfig.kt`: CORS explizit wieder aktiviert (`.cors { }`), da Microservices im Plan-B direkt (ohne Gateway) angesprochen werden könnten. + - `MailController.kt`: `@CrossOrigin` um explizite Header (`allowedHeaders = ["*"]`) und Methoden (`methods = [...]`) erweitert, um Preflight-Checks (OPTIONS) korrekt zu bedienen. + - UI-Marker auf `v2026-04-23.14 - CORS REANIMATION` aktualisiert. + +### 2026-04-23 11:00 - Version 15: CORS Stability & Test Fix +- **Problem**: Aktivierung von `.cors { }` in `GlobalSecurityConfig.kt` verursachte `NoSuchBeanDefinitionException` in Spring-Integration-Tests, da keine `CorsConfigurationSource` Bean definiert war. +- **Lösung**: + - `GlobalSecurityConfig.kt`: Explizite `CorsConfigurationSource` Bean implementiert, die sowohl lokale Entwicklungsumgebungen (`localhost`) als auch produktive URLs (`*.mo-code.at`) whitelisted. + - Integration von `it.configurationSource(corsConfigurationSource())` in die `filterChain` zur Behebung der Testfehler. + - UI-Marker auf `v2026-04-23.15 - CORS STABILITY` aktualisiert. + - Verifiziert durch erfolgreichen Durchlauf des `EntriesIsolationIntegrationTest`. diff --git a/frontend/shells/meldestelle-web/src/wasmJsMain/kotlin/at/mocode/frontend/shell/web/WebMainScreen.kt b/frontend/shells/meldestelle-web/src/wasmJsMain/kotlin/at/mocode/frontend/shell/web/WebMainScreen.kt index 8f12e4dd..8f6b2e52 100644 --- a/frontend/shells/meldestelle-web/src/wasmJsMain/kotlin/at/mocode/frontend/shell/web/WebMainScreen.kt +++ b/frontend/shells/meldestelle-web/src/wasmJsMain/kotlin/at/mocode/frontend/shell/web/WebMainScreen.kt @@ -124,7 +124,7 @@ fun MainAppContent() { // Dezentraler Versions-Marker in der unteren rechten Ecke Box(modifier = Modifier.fillMaxSize().padding(8.dp), contentAlignment = Alignment.BottomEnd) { Text( - text = "v2026-04-23.13 - RADICAL HTTPS PRIORITIZATION", + text = "v2026-04-23.15 - CORS STABILITY", style = MaterialTheme.typography.labelSmall, color = Color.LightGray.copy(alpha = 0.5f) )