0.120.3 breaks SecurityBase based dependencies in Swagger
#14263
-
First Check
Commit to Help
Example Codefrom uvicorn import run
from fastapi import FastAPI, Depends
from fastapi.security import OpenIdConnect
_oidc = OpenIdConnect(
openIdConnectUrl="https://localhost/auth/realms/test/.well-known/openid-configuration",
)
app = FastAPI(
title="My Application",
docs_url="/swagger",
redoc_url="/docs",
openapi_url="/openapi.json",
dependencies=(Depends(_oidc),),
)
@app.get("/")
async def hello_world():
return {"Hello": "World"}
if __name__ == "__main__":
run(app=app, port=8080)DescriptionUnder FastAPI 0.120.2
Under FastAPI 0.120.3
As well as testing What I'd expect is that FastAPI 0.120.3 displays consistent behavior with FastAPI 0.120.2, when defining a security dependency, and that the "Authorize" button and padlock icon on the root endpoint would be displayed in the auto generated Swagger documentation. It would seem that in 0.120.3, the security section of the generated Under FastAPI 0.120.2{
"openapi": "3.1.0",
"info": {
"title": "My Application",
"version": "0.1.0"
},
"paths": {
"/": {
"get": {
"summary": "Hello World",
"operationId": "hello_world__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"security": [
{
"OpenIdConnect": []
}
]
}
}
},
"components": {
"securitySchemes": {
"OpenIdConnect": {
"type": "openIdConnect",
"openIdConnectUrl": "https://localhost/auth/realms/test/.well-known/openid-configuration"
}
}
}
}Under FastAPI 0.120.3{
"openapi": "3.1.0",
"info": {
"title": "My Application",
"version": "0.1.0"
},
"paths": {
"/": {
"get": {
"summary": "Hello World",
"operationId": "hello_world__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
}
}
}
}
}If this behavior is expected, and I'm doing something wrong here, please let me know. Thank you. Operating SystemLinux Operating System DetailsUbuntu 24.04 FastAPI Version0.120.3 Pydantic Version2.12.3 Python VersionPython 3.13.8 Additional ContextSwagger UI - FastAPI 0.120.2
Swagger UI - FastAPI 0.120.3
|
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 4 replies
-
|
Also seems to break I suspect this issue effects any dependency inheriting from Example Codefrom uvicorn import run
from fastapi import FastAPI, Security
from fastapi.security import APIKeyHeader
_api_key = APIKeyHeader(
name="X-Signature",
scheme_name="HMAC (SHA-512)",
)
app = FastAPI(
title="My Application",
docs_url="/swagger",
redoc_url="/docs",
openapi_url="/openapi.json",
dependencies=(Security(_api_key),),
)
@app.get("/")
async def hello_world():
return {"Hello": "World"}
if __name__ == "__main__":
run(app=app, port=8080) |
Beta Was this translation helpful? Give feedback.
-
|
Further investigation points to the refactor of the It would seem that the security requirements of a top level dependency in the dependency chain are never assessed. Inserting the following block of code at line 259 in if dependant.call is not None:
use_security_scopes = security_scopes or []
if isinstance(dependant.call, SecurityBase):
use_scopes: List[str] = []
if isinstance(
dependant.call, (OAuth2, OpenIdConnect)
):
use_scopes = use_security_scopes
security_requirement = SecurityRequirement(
security_scheme=dependant.call, scopes=use_scopes
)
dependant.security_requirements.append(security_requirement) |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
The use case is actually strange - this way you just check that token is provided, but don't validate the token itself. Usually you need to implement a function that requires token as a sub-dependency and validates it: from fastapi import Depends, FastAPI, Security
from fastapi.security import APIKeyQuery
from fastapi.testclient import TestClient
from pydantic import BaseModel
api_key = APIKeyQuery(name="key")
def validate_token(token: str = Security(api_key)):
# validation
return token
app = FastAPI(dependencies=[Depends(validate_token)])
@app.get("/users/me")
def read_current_user():
return {} |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
|
Thanks for the complete report @oldfielj-ansto! 🙌 And thanks for the discussion here everyone. ☕ This was solved by @YuriiMotov in #14266. It was just released in FastAPI 0.120.4. 🚀 🎉 |
Beta Was this translation helpful? Give feedback.
-
|
Thank you @tiangolo and @YuriiMotov, I can confirm this issue is resolved in 0.120.4. |
Beta Was this translation helpful? Give feedback.




Thanks for the complete report @oldfielj-ansto! 🙌
And thanks for the discussion here everyone. ☕
This was solved by @YuriiMotov in #14266. It was just released in FastAPI 0.120.4. 🚀 🎉