I am using the Django Rest Framework in my Python-Django app, and am using a Custom authentication for the api.
If I work just with my custom authentication method, works correctly.
@authentication_classes((CustomAuthentication, ))
But If I try to have basic authentication and my custom authentication, in that order, my custom authentication never executes. I mean, I want that if the Basic authentication fails, then try with the custom authentication. The Basic Authentication is executes and then ends.
@authentication_classes((SessionAuthentication, BasicAuthentication, CustomAuthentication ))
Is possible to have at the same time this three authentication methods, and execute them in that order?
@Arpit Goyal's answer makes the workflow clear.
If you INDEED want to go through all the authentication classes,
here's a work around solution you can try. I hope it can help you.
@authentication_classes((AuthencationWrapper, ))
add a AuthencationWrapper
class AuthencationWrapper(BaseAuthentication):
authenication_classes = (
BasicAuthentication,
SessionAuthentication,
CustomAuthentication,
)
def authenticate(self, request):
exc = None
ret = None
for auth in self.authentication_classes:
try:
ret = auth().authenticate(request)
# if success, we will break, else we will continue to call next one
break
except exceptions.AuthenticationFailed as e:
# we only record the first failed exception
if exc is None:
exc = e
self.first_failed_auth = auth()
if ret is None:
raise exc
# one of the authentication_classes is passed
return ret
def authenticate_header(self, request):
# actualy this way breaks what django-rest-framework doing now
return self.first_failed_auth.authenticate_header(request)
# the one follows what django-rest-framework doing now
# choose the first authentication class header
## if self.authentication_classes:
## return self.authentication_classes[0].authenticate_header(request)