Django rest - Custom authentication backend with browsable api - python

I am using Django 1.11 and Django rest framework 3.6.2
I created a custom authentication backend:
MyAuthBackend(rest_framework.authentication.BasicAuthentication):
# ...
and added it to the settings.py file:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES' : ('path.to.MyAuthBackend',)
}
I also tried to extend SessionAuthentication without success
My issue is that users are trying to log in via the browsable api and it looks like the authentication backend that the browsable api is using is not the default one.
Where can I change that? I have to use my own auth backend in the browsable api,
Thank you.

I don't think it's possible to use BasicAuthentication in the browseable api (without changing a whole bunch of its internals).
Consider keeping the SessionAuthentication alongside your new one, you can use basic authentication in your app and session authentication in the browsable api:
'DEFAULT_AUTHENTICATION_CLASSES': (
'path.to.MyAuthBackend',
'rest_framework.authentication.SessionAuthentication',
),

Related

How to use django-oauth-toolkit to protect a package's API

I'm developing a web API using "django-scim2" package.
As a development requirement, bearer token authentication is required when accessing the django-scim2 API via http.
The django-scim2 documentation (https://django-scim2.readthedocs.io/en/latest/) says "This app does not implement authorization and authentication. Such tasks are left for other apps such as Django OAuth Toolkit to implement."
And as I check the django-oauth-toolkit docs, I can see how to protect it when you create a function or class,
https://django-oauth-toolkit.readthedocs.io/en/2.1.0/views/function_based.html
https://django-oauth-toolkit.readthedocs.io/en/2.1.0/views/class_based.html
but django-scim2 is loaded from config/urls.py as it is (like below), so I have nothing to do and I don't know how to implement it.
[config/urls.py]
urlpatterns = [
path('admin/', admin.site.urls),
path('scim/v2/', include('django_scim.urls', namespace='scim')),
...
I would be grateful if you could give me some good advice.

Why isn't Django Rest Framework Token Authentication working?

I am currently using Django rest framework and trying to implement a Token Authentication system. Currently, my settings.py looks like this:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication'
]
}
and rest_framework.authtoken is in installed_apps.
My urls.py looks like this:
urlpatterns = [
...
url('^v1/users/$', views.users_view),
...
]
My views.py looks like this:
#authentication_classes((TokenAuthentication,))
#api_view(['PUT', 'POST'])
def users_view(request):
...
I'm working in postman to test the API and regardless of whether I put the token in the authorization field, the API works as intended. What do I need to change for the token authentication to work as intended?
Update:
Reqbin is also giving me the same functionality so I don't think it's a problem with postman.
You need to add permission class as well.
#authentication_classes((TokenAuthentication,))
#permission_classes((IsAuthenticated,))
#api_view(['PUT', 'POST'])
def users_view(request):
...
It appears there is a bug in Django that won't allow some authentications to work with function based views. I can confirm it doesn't work for TokenAuthentication and needed to use class based views.

Django - accessing Django Rest endpoint on AWS Elastic Beanstalk

Very new to AWS and deploying my own projects/services in general. I deployed my first Django Rest API on Beanstalk.
I can access the application URL in the browser (http://myappenv.someid.us-west-2.elasticbeanstalk.com/, no problem.
However when I use that base url in my application on localhost, I get a 403: Authentication credentials were not provided.
I am passing the DRF Token in the header, just like I normally would to access each endpoint. ie http://myappenv.someid.us-west-2.elasticbeanstalk.com/mentions.
When I switch back to a local version of the API in my application, I can access it normally.
My application is hitting the endpoint but, for some reason, even with the token passing, its returning the 403
my DRF is setup in settings.py as follows:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
#'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication'
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
) ,
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
}
Any ideas? Would appreciate any feedback.
After going through the DRF documentation, I have to adjust my DEFAULT_PERMISSION_CLASSES

adding extra permission checks to django-rest-framework browsable api login

Currently I've extended the standard Django user class by linking it to a profile class. The profile model is partially used for account activation through email, and includes an account_activated boolean. I'd like to require that accounts be activated in order to login in any way, including using the login button that is added to the django rest framework browsable api by adding
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
from the tutorial here http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/
to the project urls. Is there any way to do this?
I think this is a classical example where permissions work fine. What you need to do:
Create a permission class that will check for a user if her account
is activated. For more see drf documentation;
Add your new permission class to the set of default permissions in settings.py in drf settings:
settings.py
REST_FRAMEWORK = {
...,
'DEFAULT_PERMISSION_CLASSES': [
...,
'your.permission.class',
...,
],
...
}

Django REST Framework TokenAuthentication to authenticate in Django generally

We're using rest_framework.authentication.TokenAuthentication to authenticate API users in Django REST Framework using an access token.
Is there a way to use this same class to authenticate users for Django generally?
I've tried adding it straight in to AUTHENTICATION_BACKENDS but it doesn't work:
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
"django.contrib.auth.backends.ModelBackend",
# `allauth` specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend",
'rest_framework.authentication.TokenAuthentication',
)
Is there a quick way to do this or do I need to write a custom authentication backend?
Django REST framework authentication and permission classes require the use of Django REST framework views, as the authentication is done on the view level [1]. This is different from Django authentication backends, where the authentication is done through the middleware.
Is there a way to use this same class to authenticate users for Django generally?
No, Django REST framework authentication backends are distinctly separate from Django authentication backends, and the reverse is technically true [2].
[1]: There has been discussion of moving this to the middleware level, but this is not currently planned.
[2]: Django authentication backends can be used through SessionAuthentication and other comparable DRF backends.
You can use SessionAuthentication.
AUTHENTICATION_BACKENDS = (
# Use Django's session framework for authentication.
'rest_framework.authentication.SessionAuthentication',
....
'rest_framework.authentication.TokenAuthentication',
)

Categories