fastapi/fastapi
Security
Purpose
fastapi/security/ provides a small set of dependency classes for the most common HTTP authentication schemes. Each scheme is both:
- A dependency that extracts the credential from the request (e.g. reads the
Authorizationheader). - An OpenAPI
securitySchemedescription that flows into the generated schema.
Schemes are not authentication providers — they parse the credential and hand it to your code. Validating the credential (calling your auth backend, verifying a JWT, etc.) is your responsibility.
Directory layout
fastapi/security/
├── __init__.py # Public re-exports
├── base.py # SecurityBase (the marker base class)
├── api_key.py # APIKeyQuery, APIKeyHeader, APIKeyCookie
├── http.py # HTTPBasic, HTTPBearer, HTTPDigest, HTTPBasicCredentials, HTTPAuthorizationCredentials
├── oauth2.py # OAuth2*, OAuth2PasswordRequestForm, SecurityScopes
├── open_id_connect_url.py # OpenIdConnect
└── utils.py # get_authorization_scheme_param helperKey abstractions
| Class | Purpose |
|---|---|
SecurityBase (base.py) |
Marker base. Every scheme owns a model: SecurityBaseModel (an OpenAPI Pydantic model from fastapi/openapi/models.py) and a scheme_name: str. The dependency resolver checks isinstance(call, SecurityBase) to detect security schemes (Dependant._is_security_scheme in fastapi/dependencies/models.py). |
APIKeyQuery, APIKeyHeader, APIKeyCookie (api_key.py) |
Read an API key from the URL query, an HTTP header, or a cookie. Constructor accepts name, description, auto_error. |
HTTPBasic, HTTPBearer, HTTPDigest (http.py) |
Read the Authorization header. HTTPBasic returns HTTPBasicCredentials(username, password). HTTPBearer and HTTPDigest return HTTPAuthorizationCredentials(scheme, credentials). |
OAuth2PasswordBearer, OAuth2AuthorizationCodeBearer, OAuth2 (oauth2.py) |
Each declares an OAuth2 flow in OpenAPI and reads a Bearer token. The class itself does not validate the token — wrap it with your own dependency to verify. |
OAuth2PasswordRequestForm, OAuth2PasswordRequestFormStrict (oauth2.py) |
Form-data dependency that pulls grant_type, username, password, scope, client_id, client_secret from a request. Use as Annotated[OAuth2PasswordRequestForm, Depends()] on a /token endpoint. |
SecurityScopes (oauth2.py) |
A class injected into a dependency to expose the OAuth2 scopes required by the path operation. Used to perform scope-based authorization inside dependencies. |
OpenIdConnect (open_id_connect_url.py) |
Declares an OpenID-Connect discovery URL in OpenAPI and reads the Bearer token. |
How a security scheme reaches OpenAPI
graph TD
UserDep["dep: Annotated[..., Security(OAuth2PasswordBearer(tokenUrl='/token'), scopes=['me'])]"]
UserDep --> Analyze["analyze_param sees a Security marker"]
Analyze --> SubDep["Add as sub-Dependant; oauth_scopes carry through Dependant.parent_oauth_scopes"]
SubDep --> AtRequest["solve_dependencies: call the OAuth2PasswordBearer instance, get the bearer token"]
SubDep --> SchemaGen["fastapi/openapi/utils.py:get_openapi_security_definitions"]
SchemaGen --> SchemeModel["Read SecurityBase.model -> OpenAPI Pydantic model"]
SchemeModel --> SchemeOut["operation.security and components.securitySchemes"]Dependant._is_security_scheme is computed once and cached. Dependant.oauth_scopes propagates parent scopes into children so a Security(...) deep in the tree can know what the path operation requires.
fastapi/openapi/utils.py:get_openapi_security_definitions walks the flattened dependant tree, picks out the SecurityBase dependants, encodes their model into JSON via jsonable_encoder, merges scopes for repeated schemes, and returns the OpenAPI snippet.
auto_error semantics
Every scheme accepts auto_error: bool = True:
auto_error=True— when the credential is missing, raiseHTTPException(401)immediately.auto_error=False— when missing, returnNoneso your endpoint can decide whether to proceed unauthenticated.
api_key.py:APIKeyBase.make_not_authenticated_error constructs the 401 with a custom WWW-Authenticate: APIKey challenge — RFC 9110 requires some challenge on a 401, so the framework supplies one even though API-key auth is not standardised.
OAuth2 password flow example
from typing import Annotated
from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.post("/token")
def issue_token(form: Annotated[OAuth2PasswordRequestForm, Depends()]):
# Validate username/password yourself; return the access token.
return {"access_token": "...", "token_type": "bearer"}
@app.get("/me")
def me(token: Annotated[str, Depends(oauth2_scheme)]):
# token is the raw Bearer token. Verify it yourself.
return {"token": token}Integration points
- Up to user code — schemes are imported from
fastapi.security. - Across to dependency resolver — every scheme is a
Dependant;_is_security_schemeandoauth_scopesthread through resolution. - Across to OpenAPI — the scheme's
modelis what shows up undercomponents.securitySchemes.
Entry points for modification
- Adding a new scheme: subclass
SecurityBase, attach a Pydantic OpenAPISecurityBasemodel fromfastapi/openapi/models.py, define__call__that pulls from the request and returns the credential. Re-export fromfastapi/security/__init__.py. - Changing the OAuth2 form fields: edit
OAuth2PasswordRequestForm.__init__infastapi/security/oauth2.py. Mirror inOAuth2PasswordRequestFormStrictand update tests undertests/test_security_oauth2*.py. - Tightening the
auto_error=Trueresponse: most schemes raise viamake_not_authenticated_error. Update the helper rather than each scheme.
See Dependency injection for the broader resolver mechanics that make security schemes work.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Parameters
Next
OpenAPI