Security Schemes and Authentication
Security in this codebase is implemented through a set of Pydantic models in fastapi/openapi/models.py that strictly follow the OpenAPI 3.0.3 specification. These models define how security requirements—such as API keys, Bearer tokens, and OAuth2 flows—are represented in the generated documentation and validated during request processing.
Core Security Models
All security schemes in this project derive from SecurityBase, which establishes the fundamental structure for any authentication mechanism.
class SecurityBase(BaseModelWithConfig):
type_: SecuritySchemeType = Field(alias="type")
description: str | None = None
The SecuritySchemeType enumeration defines the four supported categories of security:
apiKey: Authentication via a key in a header, query parameter, or cookie.http: Standard HTTP authentication schemes (e.g., Basic, Bearer).oauth2: OAuth2 authentication flows.openIdConnect: OpenID Connect discovery.
API Key Authentication
API Key authentication is defined by the APIKey model. It requires specifying the location of the key using the APIKeyIn enum and the name of the parameter.
class APIKeyIn(Enum):
query = "query"
header = "header"
cookie = "cookie"
class APIKey(SecurityBase):
type_: SecuritySchemeType = Field(default=SecuritySchemeType.apiKey, alias="type")
in_: APIKeyIn = Field(alias="in")
name: str
In fastapi/security/api_key.py, these models are used to implement specific security dependencies. For example, APIKeyHeader initializes the APIKey model with location=APIKeyIn.header:
# From fastapi/security/api_key.py
class APIKeyHeader(APIKeyBase):
def __init__(self, *, name: str, ...):
super().__init__(
location=APIKeyIn.header,
name=name,
...
)
HTTP Authentication
HTTP authentication schemes use HTTPBase and its specialized subclass HTTPBearer. These models are found in fastapi/openapi/models.py and are utilized by the security classes in fastapi/security/http.py.
class HTTPBase(SecurityBase):
type_: SecuritySchemeType = Field(default=SecuritySchemeType.http, alias="type")
scheme: str
class HTTPBearer(HTTPBase):
scheme: Literal["bearer"] = "bearer"
bearerFormat: str | None = None
When using HTTPBearer in a route, FastAPI expects an Authorization header. If the scheme is missing or incorrect, it returns a 401 status code. Note that HTTPDigest is also available as a model but is currently a stub in the security implementation, requiring manual subclassing for full logic.
OAuth2 Flows and Configuration
OAuth2 is the most complex security implementation, involving multiple potential "flows." The OAuth2 model contains an OAuthFlows object, which can hold configurations for different grant types.
OAuth2 Model Structure
The hierarchy of models for OAuth2 is as follows:
OAuth2: The top-level security scheme.OAuthFlows: A container for specific flow types.OAuthFlow: The base for all flows, containingscopesand an optionalrefreshUrl.
class OAuthFlows(BaseModelWithConfig):
implicit: OAuthFlowImplicit | None = None
password: OAuthFlowPassword | None = None
clientCredentials: OAuthFlowClientCredentials | None = None
authorizationCode: OAuthFlowAuthorizationCode | None = None
Specific Flow Requirements
Each flow type has specific URL requirements:
- Password Flow (
OAuthFlowPassword): Requires atokenUrl. - Authorization Code Flow (
OAuthFlowAuthorizationCode): Requires bothauthorizationUrlandtokenUrl. - Client Credentials Flow (
OAuthFlowClientCredentials): Requires atokenUrl. - Implicit Flow (
OAuthFlowImplicit): Requires anauthorizationUrl.
In fastapi/security/oauth2.py, classes like OAuth2PasswordBearer automatically construct these models:
# From fastapi/security/oauth2.py
flows = OAuthFlowsModel(
password=cast(
Any,
{
"tokenUrl": tokenUrl,
"refreshUrl": refreshUrl,
"scopes": scopes,
},
)
)
OpenID Connect
The OpenIdConnect model provides a way to define an OpenID Connect discovery URL.
class OpenIdConnect(SecurityBase):
type_: SecuritySchemeType = Field(
default=SecuritySchemeType.openIdConnect, alias="type"
)
openIdConnectUrl: str
In the current implementation within fastapi/security/open_id_connect_url.py, this class serves primarily as a metadata provider for OpenAPI. It does not implement the full OIDC validation logic out of the box; developers typically subclass it to add specific validation for their OIDC provider.
Implementation Details
Error Handling and auto_error
Most security classes in fastapi/security accept an auto_error boolean. When True (the default), FastAPI will automatically raise an HTTPException (401 Unauthorized) if the security requirement is not met. If False, the dependency returns None, allowing for optional authentication.
WWW-Authenticate Headers
For compliance with RFC 9110, this codebase ensures that 401 responses include a WWW-Authenticate header.
- For
APIKeyschemes, a custom challengeAPIKeyis used. - For
HTTPBearerandOAuth2(by default), the challenge isBearer.
Security Scopes
The SecurityScopes class in fastapi/security/oauth2.py allows dependencies to access the full list of scopes required by all dependencies in a single request chain. This is useful for complex authorization logic where different parts of a route require different permissions.
class SecurityScopes:
def __init__(self, scopes: list[str] | None = None):
self.scopes = scopes or []
self.scope_str = " ".join(self.scopes)
OAuth2 Request Forms
The codebase provides OAuth2PasswordRequestForm and OAuth2PasswordRequestFormStrict to handle the parsing of form data for the password flow. The "Strict" version enforces that the grant_type must be exactly "password", as required by the OAuth2 specification.