|
35 | 35 | import org.springframework.context.annotation.Bean; |
36 | 36 | import org.springframework.context.annotation.Configuration; |
37 | 37 | import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; |
| 38 | +import org.springframework.web.cors.CorsConfiguration; |
| 39 | +import org.springframework.web.cors.CorsConfigurationSource; |
| 40 | +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
38 | 41 | import org.springframework.web.servlet.config.annotation.CorsRegistry; |
39 | 42 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
40 | 43 |
|
@@ -103,4 +106,45 @@ private void configureOrigins(String[] allowedOrigins, String[] allowedMethods, |
103 | 106 | } |
104 | 107 | }; |
105 | 108 | } |
| 109 | + |
| 110 | + /** |
| 111 | + * Creates a {@link CorsConfigurationSource} that can be used by Spring Security |
| 112 | + * to apply CORS headers even on error responses (e.g., 401, 403). |
| 113 | + * This ensures consistent CORS behavior between Spring MVC and Spring Security. |
| 114 | + * |
| 115 | + * @param configurationUrlProviders |
| 116 | + * @param allowedOrigins |
| 117 | + * @param allowedMethods |
| 118 | + * @return |
| 119 | + */ |
| 120 | + @Bean |
| 121 | + public CorsConfigurationSource corsConfigurationSource(List<CorsPathPatternProvider> configurationUrlProviders, |
| 122 | + @Value("${basyx.cors.allowed-origins:}") String[] allowedOrigins, |
| 123 | + @Value("${basyx.cors.allowed-methods:}") String[] allowedMethods) { |
| 124 | + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
| 125 | + |
| 126 | + if (allowedOrigins.length == 0 && allowedMethods.length == 0) { |
| 127 | + return source; |
| 128 | + } |
| 129 | + |
| 130 | + CorsConfiguration configuration = new CorsConfiguration(); |
| 131 | + |
| 132 | + if (allowedOrigins.length > 0) { |
| 133 | + configuration.setAllowedOriginPatterns(Arrays.asList(allowedOrigins)); |
| 134 | + } |
| 135 | + |
| 136 | + if (allowedMethods.length > 0) { |
| 137 | + configuration.setAllowedMethods(Arrays.asList(allowedMethods)); |
| 138 | + } |
| 139 | + |
| 140 | + configuration.setAllowedHeaders(List.of("*")); |
| 141 | + configuration.setAllowCredentials(true); |
| 142 | + |
| 143 | + for (CorsPathPatternProvider provider : configurationUrlProviders) { |
| 144 | + logger.info("Registering CORS configuration for path pattern: " + provider.getPathPattern()); |
| 145 | + source.registerCorsConfiguration(provider.getPathPattern(), configuration); |
| 146 | + } |
| 147 | + |
| 148 | + return source; |
| 149 | + } |
106 | 150 | } |
0 commit comments