Защитите все вызовы XML-RPC с помощью базовой аутентификации HTTP, кроме одного
Я настроил проект Django для смартфона, обслуживающего методы XML-RPC через HTTPS и использующего базовую аутентификацию. Все методы XML-RPC требуют имени пользователя и пароля.
Я хотел бы реализовать метод XML-RPC для обеспечения регистрации в системе.
Очевидно, что этот метод не должен требовать имени пользователя и пароля. Ниже приведен раздел Apache Conf, отвечающий за базовую аутентификацию:
<Location /RPC2>
AuthType Basic
AuthName "Login Required"
Require valid-user
AuthBasicProvider wsgi
WSGIAuthUserScript /path/to/auth.wsgi
</Location>
Это мой auth.wsgi:
import os
import sys
sys.stdout = sys.stderr
sys.path.append('/path/to/project')
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'
from django.contrib.auth.models import User
from django import db
def check_password(environ, user, password):
"""
Authenticates apache/mod_wsgi against Django's auth database.
"""
db.reset_queries()
kwargs = {'username': user, 'is_active': True}
try:
# checks that the username is valid
try:
user = User.objects.get(**kwargs)
except User.DoesNotExist:
return None
# verifies that the password is valid for the user
if user.check_password(password):
return True
else:
return False
finally:
db.connection.close()
Есть два грязных способа достичь моей цели в сложившейся ситуации:
- Иметь фиктивное имя пользователя / пароль, которые будут использоваться при попытке зарегистрироваться в системе
- Создайте отдельное приложение Django/XML-RPC по другому URL-адресу (например, / register), который не защищен базовой аутентификацией
Оба они очень уродливы, так как я также хотел бы определить стандартный протокол, который будет использоваться для таких сервисов, как мой (это открытая архитектура Dynamic Ridesharing Architecture)
Есть ли способ снять защиту одного вызова XML-RPC (т.е. определенного запроса POST), даже если все вызовы XML-RPC через /RPC2 защищены?
1 ответ
Это может звучать как сумасшедший разговор, но может ли ваша функция check_password() увидеть, что ей нужно для выполнения своей работы, и просто вернуть "ок", если целью является та, которую вы хотите снять защиту?
Я вообще не знаю Django, поэтому возможно, что ваш check_password() даже не вызывается, если нет имени пользователя / пароля, если Django его перехватит, прежде чем вызовет ваш код.