|
| 1 | +/** |
| 2 | + * Copyright (c) 2024, RTE (http://www.rte-france.com) |
| 3 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 4 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 5 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 6 | + */ |
| 7 | +package org.gridsuite.gateway.filters; |
| 8 | + |
| 9 | +import org.slf4j.Logger; |
| 10 | +import org.slf4j.LoggerFactory; |
| 11 | +import org.springframework.cloud.gateway.filter.GatewayFilterChain; |
| 12 | +import org.springframework.core.Ordered; |
| 13 | +import org.springframework.http.HttpStatus; |
| 14 | +import org.springframework.stereotype.Component; |
| 15 | +import org.springframework.web.server.ServerWebExchange; |
| 16 | +import reactor.core.publisher.Mono; |
| 17 | + |
| 18 | +import java.util.regex.Pattern; |
| 19 | + |
| 20 | +/** |
| 21 | + * A global pre-filter that controls access to supervision endpoints in the API gateway. |
| 22 | + * |
| 23 | + * This filter inspects the incoming request path and blocks access to specific supervision |
| 24 | + * endpoints based on a predefined pattern. The filter is designed to enhance security by |
| 25 | + * restricting access to potentially sensitive supervision functionalities. |
| 26 | + * |
| 27 | + * The filter blocks access to paths matching the following pattern: |
| 28 | + * {@code /v<number>/supervision} or {@code /v<number>/supervision/<any-sub-path>} |
| 29 | + * where {@code <number>} can be any positive integer representing the API version. |
| 30 | + * |
| 31 | + * Examples of blocked paths: |
| 32 | + * - /v1/supervision |
| 33 | + * - /v2/supervision/ |
| 34 | + * - /v10/supervision/health |
| 35 | + * - /v999/supervision/metrics |
| 36 | + * |
| 37 | + * When a matching path is detected, the filter responds with a 403 Forbidden status. |
| 38 | + * |
| 39 | + * @author Achour BERRAHMA <achour.berrahma at rte-france.com> |
| 40 | + */ |
| 41 | +@Component |
| 42 | +public class SupervisionAccessControlFilter extends AbstractGlobalPreFilter { |
| 43 | + |
| 44 | + private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionAccessControlFilter.class); |
| 45 | + private static final Pattern SUPERVISION_PATTERN = Pattern.compile("^/v\\d+/supervision(/.*)?$"); |
| 46 | + public static final String ACCESS_TO_SUPERVISION_ENDPOINT_IS_NOT_ALLOWED = "{}: 403 Forbidden, Access to supervision endpoint is not allowed"; |
| 47 | + |
| 48 | + @Override |
| 49 | + public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| 50 | + String path = exchange.getRequest().getURI().getPath(); |
| 51 | + if (SUPERVISION_PATTERN.matcher(path).matches()) { |
| 52 | + LOGGER.info(ACCESS_TO_SUPERVISION_ENDPOINT_IS_NOT_ALLOWED, |
| 53 | + exchange.getRequest().getPath()); |
| 54 | + return completeWithCode(exchange, HttpStatus.FORBIDDEN); |
| 55 | + } |
| 56 | + |
| 57 | + return chain.filter(exchange); |
| 58 | + } |
| 59 | + |
| 60 | + @Override |
| 61 | + public int getOrder() { |
| 62 | + // Execute after TokenValidatorGlobalPreFilter and UserAdminControlGlobalPreFilter |
| 63 | + return Ordered.LOWEST_PRECEDENCE - 2; |
| 64 | + } |
| 65 | +} |
0 commit comments