tfranzel/drf-spectacular

Authentication with oauth2

Closed this issue · 4 comments

Hi,
I'm trying to configure drf_spectacular to create SwaggerUI and authorize with OAuth2. Here's my setting for the OAuth2.0 in SPECTACULAR_SETTINGS:

SPECTACULAR_SETTINGS = {
    # ...
    "SERVE_INCLUDE_SCHEMA": True,
    'OAUTH2_FLOWS': ['password'],
    'OAUTH2_AUTHORIZATION_URL': "http://localhost:8081/realms/master/protocol/openid-connect/auth",
    'OAUTH2_TOKEN_URL': "http://localhost:8081/realms/master/protocol/openid-connect/token",
    "SWAGGER_UI_OAUTH2_CONFIG": {
        "clientId": "a_sample_client_id",
        "clientSecret": "this_is_super_secret",
    },
    "SERVE_PUBLIC": False,
    'SWAGGER_UI_SETTINGS': {
        'deepLinking': True,
        'withCredentials': True,
        'persistAuthorization': True
    },
}

I successfully authorize with OAuth2.0 and got the access token from the authorization server (which is in my setting above).
I expect that this access token will be injected to the header of the afterward requests. I continue to hit "Try it out" in the swagger ui and test some requests but none of these requests containt the access token in the header.
Is there anything that I'm missing in the setting or am I doing it all wrong? Please help me :((

Hi, the settings look okay to me. If your endpoints do have the proper authentication_class set, swagger-ui should add the token automatically. There is really nothing we do here, it is all swagger-ui at that point.

The only thing we customize is that after successful authentication, we reload the schema with the token in the request to get a full schema (in case of SERVE_PUBLIC: False):

request.headers["Authorization"] = `Bearer ${authDef.token.access_token}`;

So we do something special for the schema call, but the regular requests are all 100% swagger-ui. Is the oauth method properly set in the endpoints in the schema?

Hi, thank you for replying so fast.
In the viewset, I added: authentication_classes = [OAuth2Authentication]. For example:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User
    serializer_class = UserSerializer
    authentication_classes = [OAuth2Authentication]

I checked the schema file and the oauth method is not set in the endpoints 😞. It looks like this:

security:
- {}

I believe you need a permission_classes, otherwise it is "allow any" aka {}

class TokenHasReadWriteScopeViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = XSerializer
authentication_classes = [OAuth2Authentication]
permission_classes = [TokenHasReadWriteScope]

Hi, thank you for your help. I fixed it.