diff --git a/rest_framework/views.py b/rest_framework/views.py index c13e74447..41d108e53 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -162,7 +162,7 @@ class APIView(View): """ If request is not permitted, determine what kind of exception to raise. """ - if not request.successful_authenticator: + if request.authenticators and not request.successful_authenticator: raise exceptions.NotAuthenticated() raise exceptions.PermissionDenied(detail=message) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 285a3210c..70eea3132 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -321,3 +321,28 @@ class FailingAuthAccessedInRenderer(TestCase): response = self.view(request) content = response.render().content self.assertEqual(content, b'not authenticated') + + +class NoAuthenticationClassesTests(TestCase): + def test_permission_message_with_no_authentication_classes(self): + """ + An unauthenticated request made against a view that containes no + `authentication_classes` but do contain `permissions_classes` the error + code returned should be 403 with the exception's message. + """ + + class DummyPermission(permissions.BasePermission): + message = 'Dummy permission message' + + def has_permission(self, request, view): + return False + + request = factory.get('/') + view = MockView.as_view( + authentication_classes=(), + permission_classes=(DummyPermission,), + ) + response = view(request) + self.assertEqual(response.status_code, + status.HTTP_403_FORBIDDEN) + self.assertEqual(response.data, {'detail': 'Dummy permission message'})