path_param_names = get_path_param_names(path)
endpoint_signature = get_typed_signature(call)
signature_params = endpoint_signature.parameters
+ if isinstance(call, SecurityBase):
+ use_scopes: List[str] = []
+ if isinstance(call, (OAuth2, OpenIdConnect)):
+ use_scopes = security_scopes
+ security_requirement = SecurityRequirement(
+ security_scheme=call, scopes=use_scopes
+ )
+ dependant.security_requirements.append(security_requirement)
for param_name, param in signature_params.items():
is_path_param = param_name in path_param_names
param_details = analyze_param(
security_scopes=use_security_scopes,
use_cache=param_details.depends.use_cache,
)
- if isinstance(param_details.depends.dependency, SecurityBase):
- use_scopes: List[str] = []
- if isinstance(
- param_details.depends.dependency, (OAuth2, OpenIdConnect)
- ):
- use_scopes = use_security_scopes
- security_requirement = SecurityRequirement(
- security_scheme=param_details.depends.dependency, scopes=use_scopes
- )
- sub_dependant.security_requirements.append(security_requirement)
dependant.dependencies.append(sub_dependant)
continue
if add_non_field_param_to_dependency(
--- /dev/null
+# Test security scheme at the top level, including OpenAPI
+# Ref: https://github.com/fastapi/fastapi/discussions/14263
+# Ref: https://github.com/fastapi/fastapi/issues/14271
+from fastapi import Depends, FastAPI
+from fastapi.security import HTTPBearer
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
+
+app = FastAPI()
+
+bearer_scheme = HTTPBearer()
+
+
+@app.get("/", dependencies=[Depends(bearer_scheme)])
+async def get_root():
+ return {"message": "Hello, World!"}
+
+
+client = TestClient(app)
+
+
+def test_get_root():
+ response = client.get("/", headers={"Authorization": "Bearer token"})
+ assert response.status_code == 200, response.text
+ assert response.json() == {"message": "Hello, World!"}
+
+
+def test_get_root_no_token():
+ response = client.get("/")
+ assert response.status_code == 403, response.text
+ assert response.json() == {"detail": "Not authenticated"}
+
+
+def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == snapshot(
+ {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/": {
+ "get": {
+ "summary": "Get Root",
+ "operationId": "get_root__get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ }
+ },
+ "security": [{"HTTPBearer": []}],
+ }
+ }
+ },
+ "components": {
+ "securitySchemes": {"HTTPBearer": {"type": "http", "scheme": "bearer"}}
+ },
+ }
+ )