Защита представлений Django OAuth Toolkit

Мы планируем внедрить Django OAuth на нашем сервере, чтобы интегрировать Alexa и другие сторонние API. Мы следили за руководствами на их сайте (http://django-oauth-toolkit.readthedocs.io/en/latest/tutorial/tutorial.html), но столкнулись с контрольным вопросом, который до сих пор ускользал от нас:

Есть ли проблема безопасности, связанная с тем, что любой пользователь может получить доступ к https://<oursite.com>/o/applications? Если да, то какие шаги необходимо предпринять, чтобы запретить пользователям доступ к этим представлениям?

Единственные релевантные вопросы по SO не были особенно полезны:

Безопасное создание новых приложений в Django OAuth Toolkit

Отключить или ограничить /o/приложения (django rest фреймворк, oauth2)


person Nat Homer    schedule 17.11.2016    source источник


Ответы (3)


Я делаю то же самое, и я считаю, что из соображений безопасности каждый может видеть /o/applications - насколько я могу судить, эта страница предназначена для утилиты разработки, а не для рабочей страницы. Фактически, в документации django-oauth-toolkit , у них есть пример кода с более ограниченным доступом к представлениям.

from django.conf.urls import url
import oauth2_provider.views as oauth2_views
from django.conf import settings
from .views import ApiEndpoint

# OAuth2 provider endpoints
oauth2_endpoint_views = [
    url(r'^authorize/$', oauth2_views.AuthorizationView.as_view(), name="authorize"),
    url(r'^token/$', oauth2_views.TokenView.as_view(), name="token"),
    url(r'^revoke-token/$', oauth2_views.RevokeTokenView.as_view(), name="revoke-token"),
]

if settings.DEBUG:
    # OAuth2 Application Management endpoints
    oauth2_endpoint_views += [
        url(r'^applications/$', oauth2_views.ApplicationList.as_view(), name="list"),
        url(r'^applications/register/$', oauth2_views.ApplicationRegistration.as_view(), name="register"),
        url(r'^applications/(?P<pk>\d+)/$', oauth2_views.ApplicationDetail.as_view(), name="detail"),
        url(r'^applications/(?P<pk>\d+)/delete/$', oauth2_views.ApplicationDelete.as_view(), name="delete"),
        url(r'^applications/(?P<pk>\d+)/update/$', oauth2_views.ApplicationUpdate.as_view(), name="update"),
    ]

    # OAuth2 Token Management endpoints
    oauth2_endpoint_views += [
        url(r'^authorized-tokens/$', oauth2_views.AuthorizedTokensListView.as_view(), name="authorized-token-list"),
        url(r'^authorized-tokens/(?P<pk>\d+)/delete/$', oauth2_views.AuthorizedTokenDeleteView.as_view(),
            name="authorized-token-delete"),
    ]

urlpatterns = [
    # OAuth 2 endpoints:
    url(r'^o/', include(oauth2_endpoint_views, namespace="oauth2_provider")),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^api/hello', ApiEndpoint.as_view()),  # an example resource endpoint
]

Представление отзыва токена является частью RFC, поэтому оно необходимо. Я применил аналогичный подход в своем приложении, включив только AuthorizationView, TokenView и RevokeTokenView.

Надеюсь, это поможет!

person Noah Gilmore    schedule 24.01.2017
comment
docs.djangoproject.com/en/2.0/howto/deployment/checklist говорит, что вы никогда не должны включать отладку в рабочей среде. Поэтому я считаю, что они намекают нам, что мы должны реализовать собственные средства контроля доступа к этим конфиденциальным конечным точкам. - person David Chandler; 13.03.2018
comment
Да, конфиденциальные конечные точки совершенно необязательны и никогда не должны использоваться в производстве. На самом деле, в моем случае было проще просто полностью их исключить и управлять авторизованными приложениями через Django Admin. - person Noah Gilmore; 15.03.2018

Это проблема безопасности, и я предлагаю ограничить доступ только суперпользователям с активными учетными записями, как в следующем коде из urls.py:

from django.contrib.auth.decorators import user_passes_test
import oauth2_provider.views as oauth2_views

def is_super(user):
    return user.is_superuser and user.is_active

oauth2_endpoint_views = [
    url(r'^authorize/$', oauth2_views.AuthorizationView.as_view(), name="authorize"),
    url(r'^token/$', oauth2_views.TokenView.as_view(), name="token"),
    url(r'^revoke-token/$', oauth2_views.RevokeTokenView.as_view(), name="revoke-token"),
    # the above are public but we restrict the following:
    url(r'^applications/$', user_passes_test(is_super)(oauth2_views.ApplicationList.as_view()), name="list"),
    ...
]
urlpatterns = [url(r'^o/', include(oauth2_endpoint_views, namespace="oauth2_provider"))]
person David Chandler    schedule 10.03.2018
comment
Эй, я не совсем уверен, насколько это актуально, тем более что нет контекста для того, чего это достигает. - person Nat Homer; 11.03.2018
comment
Попался. Имеет смысл. Спасибо. - person Nat Homer; 14.03.2018

Чтобы исключить конечную точку 'applications/', импортируйте только необходимые URL вместо использования всего oauth2_provider.urls:

from oauth2_provider.urls import app_name, base_urlpatterns, management_urlpatterns

urlpatterns = [
    ...
    # oauth2
    path('oauth2/', include((base_urlpatterns, app_name), namespace='oauth2_provider'))
]

Будут добавлены только URL-адреса, необходимые для авторизации клиентского приложения:

oauth2/ ^authorize/$ [name='authorize']
oauth2/ ^token/$ [name='token']
oauth2/ ^revoke_token/$ [name='revoke-token']
oauth2/ ^introspect/$ [name='introspect'] 

Чтобы добавить/удалить приложения, вы можете либо использовать сайт администратора Django, либо разрешить management_urlpatterns для пользователей-администраторов, как в ответе @David Chander: https://stackoverflow.com/a/49210935/7709003

person Dmytro Gierman    schedule 01.04.2019