Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

APIKeySecuritySchema not functioning in openapi docs #17

Closed
7 tasks done
dgonzo opened this issue Oct 1, 2018 · 2 comments
Closed
7 tasks done

APIKeySecuritySchema not functioning in openapi docs #17

dgonzo opened this issue Oct 1, 2018 · 2 comments
Labels
bug Something isn't working
Milestone

Comments

@dgonzo
Copy link

dgonzo commented Oct 1, 2018

Checklist

  • Does your title concisely summarize the problem?
  • Did you include a minimal, reproducible example?
  • What OS are you using?
  • What version of molten are you using?
  • What did you do?
  • What did you expect would happen?
  • 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.

@Bogdanp Bogdanp added the bug Something isn't working label Oct 1, 2018
@Bogdanp
Copy link
Owner

Bogdanp commented Oct 1, 2018

This stems from me misreading/misinterpreting the spec. I would like to keep using name to refer to the name of the security scheme so I'll have to come up with another keyword that works for the header/param name (maybe param_name?). What would make the most sense to you here?

@dgonzo
Copy link
Author

dgonzo commented Oct 1, 2018

@Bogdanp I'm with you on keeping the arbitrary name == name. For the other name param_name works. It's general enough for 'header', 'query', or 'cookie'. Thanks.

@Bogdanp Bogdanp added this to the v0.6.0 milestone Oct 6, 2018
@Bogdanp Bogdanp closed this as completed in f836284 Oct 6, 2018
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants