Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Token Auth "Token" is not being respected #205

Closed
rahuldroy opened this issue Nov 20, 2020 · 11 comments
Closed

Token Auth "Token" is not being respected #205

rahuldroy opened this issue Nov 20, 2020 · 11 comments
Labels
bug Something isn't working enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending

Comments

@rahuldroy
Copy link

Describe the bug
By default, if you use token authentication i.e. "rest_framework.authentication.TokenAuthentication", the header is required to look something like "Authorization: Token xxxxx". drf-spectacular pick up the token auth but it is putting in "Bearer" instead of token.

To Reproduce
In settings.py:

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.TokenAuthentication"
    ),

In views.py:

from rest_framework import authentication, ...

...

class FooListApiView(generics.ListAPIView):
    authentication_classes = [authentication.TokenAuthentication]
    ...

In Swagger UI, press the "Authorize" button and input your Token -
image

Then try doing a sample call using the "Try it out" button:
image

Note how the Authorization header is using "Bearer" instead of the default "Token"

Expected behavior
It should use whatever the "keyword" is set to in the TokenAuthentication class

@tfranzel
Copy link
Owner

sadly, this can only be approximately fixed.

one could construct this manually like this

type: apiKey
name: Authorization
in: header

but you would have to type Token ... in the SwaggerUI input field, which is also not optimal. I currently see no way with OpenApi 3.0.3 to satisfactorily model DRFs standard behaviour.

Honestly, i would change the keyword to Bearer in the TokenAuthentication, which is more compliant and predictable. I don't know why they chose to do this in DRF.

@tfranzel
Copy link
Owner

hey @rahuldroy, so i gave it another thought and well, it is not good that the schema is basically unusable with vanilla TokenAuthentication. this workaround must include the keyword but it is explicitly stated in description. not pretty but usable.

i think given OpenApi 3.0.3 limits and the DRF's weird default choice, this is the best we can do. Old behavior is in effect if keyword is changed to Bearer.

@tfranzel tfranzel added fix confirmation pending issue has been fixed and confirmation from issue reporter is pending bug Something isn't working enhancement New feature or request labels Nov 24, 2020
@rahuldroy
Copy link
Author

Hey @tfranzel,

Yeah that is not an optimal solution unfortunately but there isn't much we can do either. What I have done in my local project is to start using "Bearer" instead of Token by overriding the code. I think the fix for this might just a prominant documentation warning users about this... Thoughts?

@tfranzel
Copy link
Owner

well, generally i agree. the problem is finding a good spot to put that in the doc. this is a very specific detail and does not fit anywhere, at least not in a prominent way. there are dozens of tiny tweaks like this, we would have a lot of distracting warning boxes. with the fix, at least its doing the right thing depending on the TokenAuthentication configuration.

the best thing i can do is put it in the FAQ

@rahuldroy
Copy link
Author

Hey @tfranzel,

That sounds good to me! I am happy to close this issue and I'll leave this upto you to decide if we are going to keep this issue open (just incase Swagger UI/OAS3 adds support for it)..

Cheers for your help with this!

@tfranzel
Copy link
Owner

there is a new OpenApi spec version in the making but i don't know when this will happen or if the feature is in there. will close this for now to keep the issue list manageble.

@matthewsheeran
Copy link

drf-specacular sends 'Authorization: {{token}}' in my case instead using 'Bearer" I think for Basic sessions or something else so I modified my own custom auth code using default DRF rest tokens and UserPassesTestMixins to also accept 'Authorization: {{token}}' as well as 'Authorization: Token {{token}}'. Still a bit glitchy if the Browser prompts for (Basic or CSRF?) session login itself but works form the Swagger Authorization button for me.. (Too many cooks have spoilt the security broth over time methinks!)

@tfranzel
Copy link
Owner

tfranzel commented Feb 8, 2023

@matthewsheeran, this is a combination of a weird design decision in DRF and unnecessary limitation in OpenAPI 3.0.3

DRF uses Authorization: Token XXX by default which is not easily doable in OpenAPI. OpenAPI only allows Bearer as a prefix in this auth method. Anything other that Bearer will be a hack. Meaning SwaggerUI will have a free-form text field in which you have to put Token XXX and not just XXX.

I usually circumvent this dreadful situation by overriding the token name to Bearer in the auth class, then everything works without hacks.

drf-specacular sends 'Authorization: {{token}}' in my case instead using 'Bearer"

You have to prefix Token in the SwaggerUI prompt as described above. I mean there should be a hint that explicitly states that you need to prefix it yourself. Note that this all works as you would expect it with keyword = "Bearer". The hint will also go away.

I modified my own custom auth code

not really necessary here.

@matthewsheeran
Copy link

Yeah strictly speaking I am not a security guy. I'll have to browse the standards. But the default Token is actually a long term Api-Key and I will have to change the default auth and use a short term session token <60 mins instead. So I'll have to look up what "Bearer" is truly supposed to represent. In any case Django seems to have a database table auth bug so the/my default Token needs replacing with another Django auth extension anyway. The default Token being long lived makes it also unsuitable to be provided as a URL parameter (with another extension) as it will get logged: it is ok security wise to log short lived <60 min session tokens though as apps like ESRI ArcGIS do. That's my two bits worth for now anyways..

@tfranzel
Copy link
Owner

tfranzel commented Feb 9, 2023

Well, simply speaking there is basic, digest, and bearer authentication mentioned in HTTP. I think it is not strictly required by the standard, but it is most commonly Authentication: Bearer XXX. Using Token - or anything else for that matter - as keyword instead, has exactly the same semantics, just with less ecosystem support (as can be seen in SwaggerUI/OpenAPI).

Bearer/Token itself makes no assertion about lifetime and JWT is just a hipster bearer token.

fyi: I have written another lib that has a more flexible token auth: https://github.com/tfranzel/django-seriously that might be of interest to you.

@matthewsheeran
Copy link

matthewsheeran commented Mar 28, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending
Projects
None yet
Development

No branches or pull requests

3 participants