Django REST Swagger: How to use security section in Swagger settings?

1.7k Views Asked by At

I'm trying to build the Swagger settings for SecurityDefinition in order to get the following result in openapi.json:

"securityDefinitions": {
  "password": {
    "type": "oauth2",
    "tokenUrl": "http://example.com/oauth/token",
    "flow": "password",
    "scopes": {
      "write": "allows modifying resources",
      "read": "allows reading resources"
    }
  }
},
"security": [{
  "password": ["read", "write"]
}]

In my settings.py I have addded the following swagger settings:

# Swagger settings
SWAGGER_SETTINGS = {
  "SECURITY_DEFINITIONS": {
    "password": {
        "type": "oauth2",
        "tokenUrl": "http://example.com/oauth/token",
        "flow": "password",
        "scopes": {
            "write": "allows modifying resources",
            "read": "allows reading resources"
        }
     }
  },
  "SECURITY": [{
    "password": ["read", "write"]
  }]
}

The issue is that in the openapi.json which generated by Swagger there is not the security dict and I have no clue how it is generated.

Below, presented the generated openapi.json:

{
   "info": {
       "title": "Example Service API",
       "version": ""
   },
   "host": "http://example.com",
   "swagger": "2.0",
   "securityDefinitions": {
       "password": {
           "type": "oauth2",
           "scopes": {
               "write": "allows modifying resources",
               "read": "allows reading resources"
           },
           "tokenUrl": "http://example.com/oauth/token",
           "flow": "password"
       }
   },
   "paths": {...}
}

Is there any better way to describe this concept in my Swagger settings? Or can you describe me which is the process and how it is working in order to generate the openapi.json file?

1

There are 1 best solutions below

2
On BEST ANSWER

When in doubt, check the code. You can see the definition of OpenAPIRenderer here:

class OpenAPIRenderer(BaseRenderer):
    media_type = 'application/openapi+json'
    charset = None
    format = 'openapi'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        if renderer_context['response'].status_code != status.HTTP_200_OK:
            return JSONRenderer().render(data)
        extra = self.get_customizations()

        return OpenAPICodec().encode(data, extra=extra)

    def get_customizations(self):
        """
        Adds settings, overrides, etc. to the specification.
        """
        data = {}
        if swagger_settings.SECURITY_DEFINITIONS:
            data['securityDefinitions'] = swagger_settings.SECURITY_DEFINITIONS

        return data

So one way to do this is to subclass, for example:

class MyOpenAPIRenderer(OpenAPIRenderer):
    def get_customizations(self):
        data = super().get_customizations()

        # your customizations
        data["security"] = swagger_settings.SECURITY

        return data

Then you can use this renderer class for your view. Hope it helps!