Skip to content

Commit 7ae62f8

Browse files
committed
fix
1 parent 52cbdf4 commit 7ae62f8

File tree

7 files changed

+99
-228
lines changed

7 files changed

+99
-228
lines changed

api-gateway/src/main/java/com/craftpilot/apigateway/config/CorsConfiguration.java

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.craftpilot.apigateway.config;
2+
3+
import com.craftpilot.apigateway.security.FirebaseAuthenticationFilter;
4+
import jakarta.ws.rs.HttpMethod;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.core.annotation.Order;
9+
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
10+
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
11+
import org.springframework.security.config.web.server.ServerHttpSecurity;
12+
import org.springframework.security.web.server.SecurityWebFilterChain;
13+
import org.springframework.web.cors.CorsConfiguration;
14+
import org.springframework.web.cors.CorsConfigurationSource;
15+
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
16+
17+
import java.util.Arrays;
18+
19+
@Configuration
20+
@EnableWebFluxSecurity
21+
@RequiredArgsConstructor
22+
public class SecurityConfig {
23+
24+
private final FirebaseAuthenticationFilter firebaseAuthenticationFilter;
25+
26+
@Bean
27+
@Order(Ordered.HIGHEST_PRECEDENCE)
28+
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
29+
return http
30+
.csrf(ServerHttpSecurity.CsrfSpec::disable)
31+
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // CORS yapılandırması buraya taşındı
32+
.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
33+
.formLogin(ServerHttpSecurity.FormLoginSpec::disable)
34+
.authorizeExchange(exchanges -> exchanges
35+
.pathMatchers(HttpMethod.OPTIONS).permitAll()
36+
.pathMatchers(SecurityConstants.PUBLIC_PATHS.toArray(new String[0])).permitAll()
37+
.anyExchange().access(new RouteMetadataAuthorizationManager())
38+
)
39+
.addFilterAt(firebaseAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION)
40+
.build();
41+
}
42+
43+
@Bean
44+
public CorsConfigurationSource corsConfigurationSource() {
45+
CorsConfiguration config = new CorsConfiguration();
46+
config.setAllowCredentials(true);
47+
config.setAllowedOriginPatterns(Arrays.asList(
48+
"http://localhost:*",
49+
"https://*.craftpilot.io",
50+
"https://craftpilot.io"
51+
));
52+
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
53+
config.setAllowedHeaders(Arrays.asList("*"));
54+
config.setMaxAge(3600L);
55+
56+
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
57+
source.registerCorsConfiguration("/**", config);
58+
return source;
59+
}
60+
}

api-gateway/src/main/java/com/craftpilot/apigateway/config/SecurityConfiguration.java

Lines changed: 0 additions & 68 deletions
This file was deleted.

api-gateway/src/main/java/com/craftpilot/apigateway/controller/FallbackController.java

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,52 @@
1-
package com.craftpilot.apigateway.security;
2-
3-
import org.springframework.cloud.gateway.route.Route;
4-
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
5-
import org.springframework.http.HttpMethod;
6-
import org.springframework.security.authorization.AuthorizationDecision;
7-
import org.springframework.security.authorization.ReactiveAuthorizationManager;
8-
import org.springframework.security.core.Authentication;
9-
import org.springframework.security.web.server.authorization.AuthorizationContext;
10-
import org.springframework.web.server.ServerWebExchange;
11-
import reactor.core.publisher.Mono;
12-
13-
import java.util.List;
14-
import java.util.Map;
15-
1+
@Slf4j
2+
@Component
163
public class RouteMetadataAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
17-
4+
185
@Override
196
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext context) {
207
ServerWebExchange exchange = context.getExchange();
218
Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
229

2310
if (route == null) {
11+
log.debug("No route found for path: {}", exchange.getRequest().getPath());
2412
return Mono.just(new AuthorizationDecision(false));
2513
}
2614

2715
Map<String, Object> metadata = route.getMetadata();
2816
boolean secured = metadata.containsKey("secured") ? (boolean) metadata.get("secured") : true;
29-
List<String> allowedMethods = (List<String>) metadata.getOrDefault("methods", List.of("GET", "POST", "PUT", "DELETE"));
30-
List<String> requiredRoles = (List<String>) metadata.getOrDefault("roles", List.of("USER"));
17+
18+
if (!secured || SecurityConstants.isPublicPath(exchange.getRequest().getPath().value())) {
19+
return Mono.just(new AuthorizationDecision(true));
20+
}
3121

3222
return authentication
23+
.filter(Authentication::isAuthenticated)
3324
.map(auth -> {
34-
if (!secured) return true;
35-
36-
// HTTP metod kontrolü
25+
// Method kontrolü
3726
String requestMethod = exchange.getRequest().getMethod().name();
38-
if (!allowedMethods.contains(requestMethod)) return false;
27+
List<String> allowedMethods = (List<String>) metadata.getOrDefault("methods",
28+
Arrays.asList("GET", "POST", "PUT", "DELETE"));
29+
30+
if (!allowedMethods.contains(requestMethod)) {
31+
log.debug("Method {} not allowed for path {}", requestMethod, exchange.getRequest().getPath());
32+
return false;
33+
}
3934

4035
// Rol kontrolü
41-
boolean hasRequiredRole = auth.getAuthorities().stream()
42-
.anyMatch(a -> requiredRoles.contains(a.getAuthority().replace("ROLE_", "")));
43-
44-
return hasRequiredRole;
36+
List<String> requiredRoles = (List<String>) metadata.getOrDefault("roles", List.of("USER"));
37+
boolean hasRole = auth.getAuthorities().stream()
38+
.map(GrantedAuthority::getAuthority)
39+
.map(role -> role.replace("ROLE_", ""))
40+
.anyMatch(requiredRoles::contains);
41+
42+
if (!hasRole) {
43+
log.debug("User {} does not have required roles {} for path {}",
44+
auth.getName(), requiredRoles, exchange.getRequest().getPath());
45+
}
46+
47+
return hasRole;
4548
})
46-
.map(AuthorizationDecision::new)
47-
.defaultIfEmpty(new AuthorizationDecision(false));
49+
.defaultIfEmpty(false)
50+
.map(AuthorizationDecision::new);
4851
}
4952
}

api-gateway/src/main/java/com/craftpilot/apigateway/security/SecurityConstants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ public class SecurityConstants {
1414
"/subscription-plans/public/**",
1515
"/docs/**",
1616
"/swagger-ui/**",
17-
"/v3/api-docs/**"
17+
"/v3/api-docs/**",
18+
"/favicon.ico"
1819
);
1920

2021
public static boolean isPublicPath(String path) {

api-gateway/src/main/resources/application.yml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ spring:
8686
predicates:
8787
- Path=/ai/**
8888
metadata:
89-
connect-timeout: 120000
90-
response-timeout: 120000
9189
secured: true
92-
methods: [POST, GET]
9390
roles: [USER, ADMIN]
91+
methods: [GET, POST]
92+
connect-timeout: 120000
93+
response-timeout: 120000
9494
filters:
9595
- name: CircuitBreaker
9696
args:
@@ -102,8 +102,10 @@ spring:
102102
replacement: "/${segment}"
103103
- AddRequestHeader=Content-Type, application/json
104104
- AddRequestHeader=Accept, text/event-stream
105-
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
106105
- PreserveHostHeader
106+
- name: RequestSize # LLM istekleri için özel boyut limiti
107+
args:
108+
maxSize: 50MB
107109

108110
- id: image-service
109111
uri: lb://image-service
@@ -320,9 +322,3 @@ spring.sleuth:
320322
correlation-enabled: true
321323
remote-fields: x-request-id
322324
local-fields: country-code,user-id
323-
324-
cors:
325-
allowed-origins: ${ALLOWED_ORIGINS:http://localhost:3000,http://localhost:5173,https://craftpilot.io,https://*.craftpilot.io}
326-
allowed-methods: GET,POST,PUT,DELETE,OPTIONS,PATCH
327-
max-age: 3600
328-
allow-credentials: true

0 commit comments

Comments
 (0)