3535
3636
3737async def get_jwk_set (url : str ) -> KeySet :
38- """Fetch the JWK set from the cache, or fetch it from the URL if not cached."""
38+ """Fetch the JWK set from the cache, or fetch it from the URL if not cached.
39+
40+ Retrieve a JWK KeySet from the in-memory cache or fetch and cache it from the provided URL.
41+
42+ Returns:
43+ KeySet: The JWK `KeySet` corresponding to the URL.
44+ """
3945 async with _jwk_cache_lock :
4046 if url not in _jwk_cache :
4147 async with aiohttp .ClientSession () as session :
@@ -54,10 +60,21 @@ def key_resolver_func(
5460 jwk_set : KeySet ,
5561) -> Callable [[dict [str , Any ], dict [str , Any ]], Key ]:
5662 """
57- Create a key resolver function .
63+ Create a JWK key resolver used to locate the verification key from a KeySet .
5864
59- Return a function to find a key in the given jwk_set. The function matches the
60- signature expected by the jwt.decode key kwarg.
65+ The returned callable accepts a JWT header and payload and selects a key from the provided
66+ jwk_set. If the header contains a `kid`, the resolver returns the single key with that `kid`
67+ and verifies the key's `alg` matches the header `alg`. If `kid` is absent, the resolver
68+ returns the first key that matches the header `alg`. The resolver raises `KeyNotFoundError`
69+ if no suitable key is found or if multiple keys are found for the same `kid`.
70+
71+ Parameters:
72+ jwk_set (KeySet): JWK set to search for verification keys.
73+
74+ Returns:
75+ callable: A function `header, payload -> Key` that resolves and returns
76+ the verification key.
77+ Raises `KeyNotFoundError` when resolution fails.
6178 """
6279
6380 def _internal (header : dict [str , Any ], _payload : dict [str , Any ]) -> Key :
@@ -67,8 +84,16 @@ def _internal(header: dict[str, Any], _payload: dict[str, Any]) -> Key:
6784 match the algorithm to make sure the algorithm stated by the user
6885 is the same algorithm the key itself expects.
6986
70- # We intentionally do not use find_by_kid because it's a bad function
71- # that doesn't take the alg into account
87+ We intentionally do not use find_by_kid because it's a bad function
88+ that doesn't take the alg into account
89+
90+ Returns:
91+ key (Key): The JWK matching the header's selection criteria.
92+
93+ Raises:
94+ KeyNotFoundError: If the header is missing `alg`, no matching key
95+ is found, multiple keys match a `kid`, or a found key's algorithm
96+ does not match the header's `alg`.
7297 """
7398 if "alg" not in header :
7499 raise KeyNotFoundError ("Token header missing 'alg' field" )
@@ -117,13 +142,42 @@ class JwkTokenAuthDependency(AuthInterface): # pylint: disable=too-few-public-m
117142 def __init__ (
118143 self , config : JwkConfiguration , virtual_path : str = DEFAULT_VIRTUAL_PATH
119144 ) -> None :
120- """Initialize the required allowed paths for authorization checks."""
145+ """Initialize the required allowed paths for authorization checks.
146+
147+ Create a JWK-based token authentication dependency configured for a specific virtual path.
148+
149+ Parameters:
150+ config (JwkConfiguration): Configuration containing the JWK URL,
151+ claim names, and validation settings.
152+ virtual_path (str): Virtual authorization scope path used when
153+ resolving authorization rules; defaults to DEFAULT_VIRTUAL_PATH.
154+
155+ Notes:
156+ Initializes the instance and sets `skip_userid_check` to False.
157+ """
121158 self .virtual_path : str = virtual_path
122159 self .config : JwkConfiguration = config
123160 self .skip_userid_check = False
124161
125162 async def __call__ (self , request : Request ) -> AuthTuple :
126- """Authenticate the JWT in the headers against the keys from the JWK url."""
163+ """Authenticate the JWT in the headers against the keys from the JWK url.
164+
165+ If the Authorization header is missing, returns NO_AUTH_TUPLE. On token
166+ verification or validation failures this function raises HTTPException
167+ with appropriate HTTP status codes:
168+ - 401 for unknown signing key/algorithm, bad signature, expired token,
169+ or missing required claims;
170+ - 400 for token decode or other JOSE-related decode/validation errors;
171+ - 500 for unexpected internal errors.
172+
173+ Parameters:
174+ request (Request): The incoming FastAPI request containing the Authorization header.
175+
176+ Returns:
177+ AuthTuple: A tuple (user_id, username, skip_userid_check, token)
178+ extracted from the validated token, or NO_AUTH_TUPLE when no
179+ Authorization header is present.
180+ """
127181 if not request .headers .get ("Authorization" ):
128182 return NO_AUTH_TUPLE
129183
0 commit comments