Django Rest Framework {"detail":"Authentication credentials were not provided."}
Asked Answered
P

4

12

I have tried to add authentication to my Rest API using OAuth Toolkit. I get to the login page and enter in my username and password then redirect to my api. I then get a message {"detail":"Authentication credentials were not provided."} I have tried looking into this and most people who have the problem seem to have missed something out of the Rest_Framework settings. I dont think I have though.

Heres my code:

Settings.py

LOGIN_REDIRECT_URL = '/api/users/'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'oauth2_provider.ext.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser',
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.JSONParser',
    ),
}

url.py

urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)),
                       url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}),

                       url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
                       url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token'),
                       url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),

                       url(r'^api/users/$', api.UserList.as_view()),
                       url(r'^api/users/(?P<pk>[0-9+]+)/$', api.UserDetail.as_view()),
                       )

api.py

@receiver(post_save, sender=User)
def init_new_user(sender, instance, signal, created, **kwargs):
    if created:
        Token.objects.create(user=instance)


class APIEndpoint(ProtectedResourceView):
    def get(self, request, *args, **kwargs):
        return HttpResponse('Protected with OAuth2!')


class UserViewSet(viewsets.ModelViewSet):
    model = User
    serializer_class = UserSerializer

    def retrieve(self, request, pk=None):
        if pk == 'me':
            return Response(UserSerializer(request.user).data)
        return super(UserViewSet, self).retrieve(request, pk)


class UserList(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
Palmy answered 7/12, 2014 at 14:11 Comment(6)
do any of these solutions help: stackoverflow.com/questions/14877249Bergman
I looked at those and still no luck. The only thing from there i didn't try was the WSGIPassAuthorization On as to my understanding thats if your running on a Apache server when i'm just running just virtualenv. If I'm wrong I don't know where to put the WSGIPassAuthorization OnPalmy
You are correct, that is an Apache specific config option. Do you have oauth2_provider listing in INSTALLED_APPS in your settings file?Bergman
Hmm, the only other thing I can think of is to try switching the order of DEFAULT_AUTHENTICATION_CLASSES so that OAuth2 is first.Bergman
What is the response code that you are getting?Ancel
Had the same issue with oauth toolkit. Check your access token if its validAlleviate
A
22

In my case token authentication was working fine on development server and not on Apache. The reason was exactly the missing WSGIPassAuthorization On

http://www.django-rest-framework.org/api-guide/authentication/#apache-mod_wsgi-specific-configuration

Anaximander answered 3/3, 2015 at 19:17 Comment(0)
E
6

see your settings.py, if you have

'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),

in REST_FRAMEWORK like this, it will Authenticate each time when you post.

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.TokenAuthentication',
)}

so, delete it.

Everick answered 3/11, 2016 at 2:45 Comment(0)
M
0

In my case, I used a permissions.IsAuthenticatedOrReadOnly permission class in my viewset, but sending a post request without login:

class MemberViewSet(viewsets.ModelViewSet):

    queryset = Member.objects.all()
    serializer_class = MemberSerializer

    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
    )

    @list_route(methods=['post'])
    def check_activation_code(self, request):
        # my custom action which do not need login
        # I met the error in this action
        do_something()

So the permission checking for that permission class is failed.

Everything goes well after I remove the IsAuthenticatedOrReadOnly permission class.

Mechelle answered 12/9, 2015 at 9:30 Comment(0)
C
0

In my case, I had the following in my settings.py and deleting it solved the problem :

SIMPLE_JWT = {
     # Use JWT 
     'AUTH_HEADER_TYPES': ('JWT',),
}
Cacilia answered 4/8 at 23:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.