Search code examples
pythonflaskswaggerconnexion

any workaround to add token authorization decorator to endpoint at swagger python server stub


I know how to secure endpoint in flask, and I want to do the same thing to swagger generated python server stub. I am wondering how I can integrate flask token authentication works for the swagger python server, so the endpoint will be secured. I could easily add token authentication decorator to endpoint in flask. This is how things works in flask-restplus and this one below is totally working:

from flask import Flask, request, jsonify
from flask_restplus import Api, Resource

app = Flask(__name__)

authorizations = {
    'apikey' : {
        'type' : 'apiKey',
        'in' : 'header',
        'name' : 'X-API-KEY'
    },
}

api = Api(app, security = 'apikey',authorizations=authorizations)

def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        if 'X-API-KEY' in request.headers:
            token = request.headers['X-API-KEY']
        if not token:
            return {'message' : 'Token is missing.'}, 401
        if token != 'mytoken':
            return {'message' : 'Your token is wrong, wrong, wrong!!!'}, 401
        print('TOKEN: {}'.format(token))
        return f(*args, **kwargs)
    return decorated


 class classResource(Resource):
    @api.doc(security='apikey')
    @token_required
    def get(self):
        return "this is test"

how to make Bearer Authentication at swagger generated server stub:

I am wondering how am I gonna integrate this authentication to swagger generated python server stub. Here is how spec file begins:

openapi: 3.0.2
info:
    title: test api
    version: 1.0.0
servers:
- url: /api/v1/
  description: Example API Service
paths:
    /about:
        get:
            summary: general summary
            description: get current version
            responses:
                '200':
                    description: About information
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/version'
                '401':
                    description: Authorization information is missing or invalid.
components:
    securitySchemes:
        BearerAuth:
            scheme: bearer
            type: http
security:
    - BearerAuth: []

controller at swagger python server stub:

update: my new attempt:

here is default_controller that generated by swagger python server stub and I tried as follow:

import connexion
import six

@api.doc(security='apikey')
@token_required
def about_get():  # noqa: E501
    return 'do some magic!'

but authorize button is missing. why?

in swagger python server stub, I have also authorization_controller which has following code logic:

from typing import List

def check_BearerAuth(token):
    return {'test_key': 'test_value'}

update:

here in swagger python server stub. about_get() is one endpoint and it is not secured right now. How can we secured that like what we did in flask? any thought?

how can I add above flask token authentication to about_get() in swagger python server stub? Is there any way of doing this? any idea?


Solution

  • Update

    Here is a example yaml to use JWT as bearer format: https://github.com/zalando/connexion/blob/master/examples/openapi3/jwt/openapi.yaml

    After you generate the flask server, on the swagger-ui you can find the 'Authorize' button. And if you execute /secret before 'Authorize' you will get a 401 error.

    So for your situation, you have to change it into:

    openapi: 3.0.2
    info:
        title: test api
        version: 1.0.0
    servers:
    - url: /api/v1/
      description: Example API Service
    paths:
        /about:
            get:
                summary: general summary
                description: get current version
                security:
                - jwt: ['secret']
                responses:
                    '200':
                        description: About information
                        content:
                            application/json:
                                schema:
                                    type: string
    
    
    components:
      securitySchemes:
        jwt:
          type: http
          scheme: bearer
          bearerFormat: JWT
          x-bearerInfoFunc: app.decode_token
    

    Hence, after you have installed connexion[swagger-ui] and start the server by python -m swagger_server. Then, navigate to http://0.0.0.0:8080/api/v1/ui/, you can test the auth works properly. If you call the /about before authorize, it will hit a 401 error.


    To add auth from code:

    from flask_restx import Api
    authorizations = {
        'Bearer Auth': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'Authorization'
        },
    }
    api = Api(app, security='Bearer Auth', authorizations=authorizations)
    

    Btw, better migrate the flask_restplus into flask_restx, as flask_restplus is no longer be maintained.

    Source

    https://github.com/noirbizarre/flask-restplus/issues/398#issuecomment-444336893