Checklist
- [x] Does your title concisely summarize the problem?
- [x] Did you include a minimal, reproducible example?
- [x] What OS are you using?
- [x] What version of molten are you using?
- [x] What did you do?
- [x] What did you expect would happen?
- [x] What happened?
What OS are you using?
macOS 10.13.6
What version of molten are you using?
0.5.2
What did you do?
I enabled APIKeySecurityScheme
in the petstore example using the following modified petstore.app
(see both variations of security_schemes
):
"""An example **molten** application that automatically exposes an
OpenAPI document to represent its structure.
"""
from typing import Any, Callable, Optional, Tuple
from molten import (
App, Header, Include, ResponseRendererMiddleware, Route, annotate,
Request, HTTP_200, HTTPError, HTTP_401)
from molten.openapi import Metadata, OpenAPIHandler, OpenAPIUIHandler, APIKeySecurityScheme
from . import categories, pets, tags
from .database import DatabaseComponent
def auth_middleware(handler: Callable[..., Any]) -> Callable[..., Any]:
def middleware(x_api_key: Optional[Header]) -> Callable[..., Any]:
if x_api_key == '58be92dd-61a9-4a27-8efa-b6a0e025439e' or getattr(handler, "no_auth", False):
return handler()
else:
raise HTTPError(HTTP_401, {"error": "bad credentials"})
return middleware
def u(request: Request) -> Tuple[str, dict]:
return HTTP_200, {"req": f"{request.headers!r}"}
def setup_app():
get_schema = OpenAPIHandler(
metadata=Metadata(
title="Pet Store",
description=__doc__,
version="0.0.0",
),
# Option 1
security_schemes=[APIKeySecurityScheme(name="X-API-KEY", in_="header")],
# Option 2
security_schemes=[APIKeySecurityScheme(name="apiKey", in_="header")],
default_security_scheme="apiKey",
)
get_schema = annotate(no_auth=True)(get_schema)
get_docs = annotate(no_auth=True)(OpenAPIUIHandler())
return App(
components=[
DatabaseComponent(),
categories.CategoryManagerComponent(),
tags.TagManagerComponent(),
pets.PetManagerComponent(),
],
middleware=[
ResponseRendererMiddleware(),
auth_middleware,
],
routes=[
Include("/v1/categories", categories.routes),
Include("/v1/pets", pets.routes),
Include("/v1/tags", tags.routes),
Route("/u", u),
Route("/_docs", get_docs),
Route("/_schema", get_schema),
],
)
What did you expect would happen?
For either "Option 1" or "Option 2" above I expected that the apiKey would be used to authenticate calls to secure routes. Instead 'X-API-KEY' is absent from the headers and a "bad credentials" error is returned.
Option 1 results in an empty "Authorizers available" dialogue box when clicking on the lock icon for a path but I'd expect that dialogue to offer a place to put the "X-API-KEY". The main authorize box does offer the expected dialogue box but it is not applied when executing calls from the docs.
Option 2 results in the expected dialogue boxes but the apiKey is not applied to calls to routes.
When I exercise the api outside of swagger (e.g. http :8000/v1/categories X-API-KEY:58be92dd-61a9-4a27-8efa-b6a0e025439e
) authentication functions properly. So, only within swagger is the header not being properly applied.
What happened?
I noticed that the security schemes in openapi have, effectively, two names. The name of the security and the name of the header:
components:
securitySchemes:
ApiKeyAuth: # arbitrary name for the security scheme
type: apiKey
in: header # can be "header", "query" or "cookie"
name: X-API-KEY # name of the header, query parameter or cookie
When the arbitraty name is "apiKey" the dialogue boxes in the docs function as expected.
To get the arbitrary name set in APIKeySecurityScheme the name
attribute must be set to "apiKey" but that results in an incorrect header name.
bug