Bug 56132 - Ошибка invalid_client ответом на запрос авторизации OAuth c использованием client_secret
Summary: Ошибка invalid_client ответом на запрос авторизации OAuth c использованием cl...
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: python3-module-django-oauth-toolkit (show other bugs)
Version: unstable
Hardware: x86_64 Linux
: P5 normal
Assignee: thatman@altlinux.org
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-09-24 17:28 MSK by Макаров Игорь Иванович
Modified: 2025-12-09 02:07 MSK (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Макаров Игорь Иванович 2025-09-24 17:28:18 MSK
Платформы (Обновлены до Sisyphus): 
Alt Workstation K 11.1 x86_64
Alt Education 11.0 KDE x86_64
Alt Education 11 x86_64
Alt Server 11 x86_64

Версия пакета: python3-module-django-oauth-toolkit 2.3.0-alt1

Не могли бы, пожалуйста, уточнить по вопросу:
 В ходе настройки приложение OAuth внести изменения получилось, только через веб интерфейс и запрос к серверу c client_secret происходит с ошибкой invalid_client как можно сделать основную проверку, корректности работы client secret и как применить настройки приложения без входа на страничку администратора?

Шаги по которым выполнял настройку:

1. Установить пакеты необходимые для запуска OAuth приложения.
# apt-get install python3 python3-module-django python3-module-django-dbbackend-sqlite3 python3-module-django-oauth-toolkit

2. Создать приложение myapp
$ python3 manage.py startapp myapp

3. Создать хранимку для пользователей
$ python3 manage.py startapp users

4. Проверка для моделей пользователей
$ cat > users/models.py << EOF
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass
EOF

5. Добавить поддержку пользователй в настройки
$ sed -i "s|'django.contrib.staticfiles',|'django.contrib.staticfiles',\n\t'users',|g" myproject/settings.py

6. Добавить настройки моделей
$ sed -i "s|DEBUG = True|DEBUG = True\nAUTH_USER_MODEL = 'users.User'|g" myproject/settings.py

7. Добавляем в настройки компонент oauth2_provider
$ sed -i "s|'django.contrib.staticfiles',|'django.contrib.staticfiles',\n\t'oauth2_provider',|g" myproject/settings.py

8.$ cat >> myproject/settings.py << EOF
OAUTH2_PROVIDER = {
    'HASH_CLIENT_SECRET': False,
    'ACCESS_TOKEN_EXPIRE_SECONDS': 36000,
    'REFRESH_TOKEN_EXPIRE_SECONDS': 864000,
    'SCOPES': {
        'read': 'Read scope',
        'write': 'Write scope',
    }
}
EOF

9. Настройки URLs и смигрировать
$ cat > myproject/urls.py << EOF
from django.contrib import admin
from django.urls import include, path
from oauth2_provider import urls as oauth2_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('o/', include(oauth2_urls)),
]
EOF

10. Страничка авторизации admin
$ sed -i "s|DEBUG = True|DEBUG = True\nLOGIN_URL = '/admin/login/'|g" myproject/settings.py

11. Создать супер пользователя admin, admin@admin.ru, admin и выполнить миграцию
$ python3 manage.py makemigrations && python3 manage.py migrate && python3 manage.py createsuperuser

12. Запустить сервер
$ cd myproject/ && python3 -W all manage.py runserver --verbosity 3

13. Создать приложение в новой вкладке под пользователем
$ cd myproject/
$ python3 manage.py shell -c "
from oauth2_provider.models import Application
from django.contrib.auth import get_user_model
usermodel = get_user_model()
admin = usermodel.objects.get(username='admin')
app = Application.objects.create(
     name='My App',
     user=admin,
     client_type='confidential',
     authorization_grant_type='authorization-code',
     redirect_uris='http://127.0.0.1:8000/noexist/callback',
    )
print(app.client_id) #сохранить вывод
print(app.client_secret) #сохранить вывод
app.save()
" -v 2

14. Создать code_challenge
import random
import string
import base64
import hashlib

code_verifier = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(43, 128)))

code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8').replace('=', '')

15. Открыть приложение в веб интерфейсе, проверить значения для чек-бокса hash client secret.
Фактический результат:
Чекбокс хешировать секретный код - установлен
Ожидаемый результат:
Чекбокс будет разселекчен, секрет код не хешируется в бд

16. Авторизовать клиента с помощью code_challenge и client_id. Происходит ошибка client_invalid. 
Ожидаемый результат:
Для клиентского Grants access_token устанавливается expiration date с значением из setting.py 
Фактический результат:
Для авторизации клиента увеличиваем в ручную expiration date и проводим авторизацию клиента.
Comment 1 Alexander Burmatov 2025-09-25 22:15:48 MSK
Для начала необходимо убедиться, что HASH_CLIENT_SECRET=False действительно применяется при создании приложения.
Сделать это можно, дописав в shell перед импортом Application, следующее:
> from django.conf import settings
> print(settings.OAUTH2_PROVIDER.get('HASH_CLIENT_SECRET'))
Comment 2 igmk 2025-09-25 22:43:13 MSK
(In reply to Alexander Burmatov from comment #1)
> Для начала необходимо убедиться, что HASH_CLIENT_SECRET=False действительно
> применяется при создании приложения.
> Сделать это можно, дописав в shell перед импортом Application, следующее:
> > from django.conf import settings
> > print(settings.OAUTH2_PROVIDER.get('HASH_CLIENT_SECRET'))

Эта проверка после создания приложения.
Проводил такую проверку, но слегка отличным способом.
Значение не применялось.
Comment 3 Alexander Burmatov 2025-09-25 23:23:58 MSK
Тогда прежде всего необходимо применить настройки.
В shell, в первую очередь:
> import django
> django.setup()

Также проблема может быть в отсутствии DJANGO_SETTINGS_MODULE.
Comment 4 Макаров Игорь Иванович 2025-09-26 11:56:23 MSK
(Ответ для Alexander Burmatov на комментарий #3)
> Тогда прежде всего необходимо применить настройки.
> В shell, в первую очередь:
> > import django
> > django.setup()
> 
> Также проблема может быть в отсутствии DJANGO_SETTINGS_MODULE.

Я раскрою этот вопрос с .setup(), хотя в документации написано использовать app_name.save() 

И, из документации можно применить настройки отдельно для приложения, а можно глобально. И так, и так не получилось применить настройки для приложения, только через веб админку.

Другой вопрос, с нехешированным client_secret (до записи его в БД) реквест с ним для авторизации клиента (получить access_token) происходит с ошибкой client_invalid. Если не трудно можно мне чуть пояснить, про этот мало для меня знакомый MVT
Comment 5 Alexander Burmatov 2025-09-26 16:22:30 MSK
> Я раскрою этот вопрос с .setup(), хотя в документации написано использовать
> app_name.save() 
Это разные вещи.

> И, из документации можно применить настройки отдельно для приложения, а
> можно глобально. И так, и так не получилось применить настройки для
> приложения, только через веб админку.
Из вот этой: https://django-oauth-toolkit.readthedocs.io/en/2.3.0/getting_started.html ?

> Другой вопрос, с нехешированным client_secret (до записи его в БД) реквест с
> ним для авторизации клиента (получить access_token) происходит с ошибкой
> client_invalid. Если не трудно можно мне чуть пояснить, про этот мало для
> меня знакомый MVT
Скорее всего, проблема в том же (не применены настройки).
Comment 6 Макаров Игорь Иванович 2025-09-26 16:39:30 MSK
(Ответ для Alexander Burmatov на комментарий #5)
> > Я раскрою этот вопрос с .setup(), хотя в документации написано использовать
> > app_name.save() 
> Это разные вещи.
> 
> > И, из документации можно применить настройки отдельно для приложения, а
> > можно глобально. И так, и так не получилось применить настройки для
> > приложения, только через веб админку.
> Из вот этой:
> https://django-oauth-toolkit.readthedocs.io/en/2.3.0/getting_started.html ?
> 
> > Другой вопрос, с нехешированным client_secret (до записи его в БД) реквест с
> > ним для авторизации клиента (получить access_token) происходит с ошибкой
> > client_invalid. Если не трудно можно мне чуть пояснить, про этот мало для
> > меня знакомый MVT
> Скорее всего, проблема в том же (не применены настройки).

> Скорее всего, проблема в том же (не применены настройки).
Я выполнил проверку с применением настроек через веб интерфейс и получаю ошибку invalid_client 
Не получаю эту ошибку, если стираю данные client_secret руками
Comment 7 Макаров Игорь Иванович 2025-09-26 16:40:47 MSK
(Ответ для Alexander Burmatov на комментарий #5)
> > Я раскрою этот вопрос с .setup(), хотя в документации написано использовать
> > app_name.save() 
> Это разные вещи.
> 
> > И, из документации можно применить настройки отдельно для приложения, а
> > можно глобально. И так, и так не получилось применить настройки для
> > приложения, только через веб админку.
> Из вот этой:
> https://django-oauth-toolkit.readthedocs.io/en/2.3.0/getting_started.html ?
> 
> > Другой вопрос, с нехешированным client_secret (до записи его в БД) реквест с
> > ним для авторизации клиента (получить access_token) происходит с ошибкой
> > client_invalid. Если не трудно можно мне чуть пояснить, про этот мало для
> > меня знакомый MVT
> Скорее всего, проблема в том же (не применены настройки).

Использовал эту инструкцию https://django-oauth-toolkit.readthedocs.io/en/2.3.0/getting_started.html
Comment 8 Alexander Burmatov 2025-09-26 17:04:47 MSK
> > Скорее всего, проблема в том же (не применены настройки).
> Я выполнил проверку с применением настроек через веб интерфейс и получаю
> ошибку invalid_client 
Это разные настройки, я про Django settings.
> Не получаю эту ошибку, если стираю данные client_secret руками
Ваши настройки из setings.py не применены, дело в этом.