From 115b07257053769b91a56a0e11fc68420e5ec611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 4 Dec 2025 13:49:37 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20OpenAPI=20security=20schem?= =?UTF-8?q?e=20definitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/openapi/utils.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py index dbc93d289..e7e6da2f7 100644 --- a/fastapi/openapi/utils.py +++ b/fastapi/openapi/utils.py @@ -79,7 +79,8 @@ def get_openapi_security_definitions( flat_dependant: Dependant, ) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]: security_definitions = {} - operation_security = [] + # Use a dict to merge scopes for same security scheme + operation_security_dict: Dict[str, List[str]] = {} for security_requirement in flat_dependant.security_requirements: security_definition = jsonable_encoder( security_requirement.security_scheme.model, @@ -88,7 +89,15 @@ def get_openapi_security_definitions( ) security_name = security_requirement.security_scheme.scheme_name security_definitions[security_name] = security_definition - operation_security.append({security_name: security_requirement.scopes}) + # Merge scopes for the same security scheme + if security_name not in operation_security_dict: + operation_security_dict[security_name] = [] + for scope in security_requirement.scopes or []: + if scope not in operation_security_dict[security_name]: + operation_security_dict[security_name].append(scope) + operation_security = [ + {name: scopes} for name, scopes in operation_security_dict.items() + ] return security_definitions, operation_security