8000 OAuth2 security schemes duplicated in OpenAPI, with and without scopes, when used at the router level · Issue #14454 · fastapi/fastapi · GitHub
[go: up one dir, main page]

Skip to content

OAuth2 security schemes duplicated in OpenAPI, with and without scopes, when used at the router level #14454

@tiangolo

Description

@tiangolo

Privileged issue

  • I'm @tiangolo or he asked me directly to create an issue here.

Issue Content

OAuth2 security schemes duplicated in OpenAPI, with and without scopes, when used at the router level

Reported by @Kludex on another channel 🙌

(I'm working on it)

# /// script
# dependencies = [
#   "fastapi[standard]==0.121.3",
# ]
# ///

import json
import sys
from typing import Annotated

import fastapi
from fastapi import APIRouter, Depends, FastAPI, Security
from fastapi.security import OAuth2AuthorizationCodeBearer, SecurityScopes


# print the dependencies
print(f'fastapi version = {fastapi.__version__}')
print(f'Python version = {sys.version}')



app = FastAPI()

o
6FC1
auth2_scheme = OAuth2AuthorizationCodeBearer(
    authorizationUrl='api/oauth/authorize',
    tokenUrl='/api/oauth/token',
    refreshUrl='/api/oauth/token',
    auto_error=False,
    scopes={'read': 'Read access', 'write': 'Write access'},
)

async def get_token(
    token: Annotated[str, Depends(oauth2_scheme)],
) -> str:
    return token

AccessToken = Annotated[str, Depends(get_token, use_cache=True)]


async def require_oauth_scopes(security_scopes: SecurityScopes, token: AccessToken) -> None:
    pass        


async def check_limit(token: AccessToken) -> None:
    pass

# The problem is here. If we remove the dependency from the router, the schema is generated correctly in both fastapi versions.
router = APIRouter(prefix='/v1', dependencies=[Depends(check_limit)])

channels_router = APIRouter(prefix='/channels', tags=['Channels'])
@channels_router.get("/", dependencies=[Security(require_oauth_scopes, scopes=['read'])])
def read_items():
    return {"msg": "You have READ access"}


router.include_router(channels_router)

app.include_router(router)
schema = app.openapi()
pretty_schema = json.dumps(schema, indent=4)
print(pretty_schema)

"""
with fastapi 0.123.7, the generated openapi schema icludes security without scopes:

                "security": [
                    {
                        "OAuth2AuthorizationCodeBearer": []
                    }
                ]

but in fastapi 0.121.3, the generated openapi schema includes two items in security:

                "security": [
                    {
                        "OAuth2AuthorizationCodeBearer": []
                    },
                    {
                        "OAuth2AuthorizationCodeBearer": [
                            "read"
                        ]
                    }
                ]
"""

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0