Проблема с авторизацией через ЕСИА

Проблема конкретно с версией v2. v1 работает корректно но подключиться с второй версии не получается. Не можем получить первый код авторизации. Все вроде по документации, хотя она крайне кривая. Скину код на Python. Кто может подскажите.Ошибка error_description":"ESIA-007053: OAuthErrorEnum.clientSecretWrong

def sign_params_for_v2_by_csptest(client_secret_raw):
    """

    :param client_secret_raw: Сформированный для подписания файл
    :return: 
    """
    thumbprint = ""
    tmp_dir = tempfile.gettempdir()
    source_file = tempfile.NamedTemporaryFile(mode='w', delete=False, dir=tmp_dir)
    source_file.write(client_secret_raw)
    source_file.close()
    source_path = source_file.name
    destination_path = source_path + ".sig"
    cmd = (f'/opt/cprocsp/bin/amd64/csptest -keys -sign GOST12_256 -cont "имя контейнера" -keytype exchange -in {source_path} -out {destination_path}')
    os.system(cmd)
    signed_message = open(destination_path, 'rb').read()
    os.unlink(source_path)

    os.unlink(destination_path)
    """
    Возвращает base64url подписанное значение
    """
    return base64.urlsafe_b64encode(signed_message).decode('utf-8')
TIMESTAMP = get_timestamp()
CLIENT_ID = "имя"
SCOPE = "openid"
SCOPE_ORG = "org_inn"
REDIRECT_URI = "урл"
SERVICE_URL = "https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v2/ac"
STATE = str(uuid.uuid4())
#Формируем client для подписания
client_secret_raw = (
    CLIENT_ID +
    SCOPE.replace(" ", "") +
    SCOPE_ORG +
    TIMESTAMP +
    STATE +
    REDIRECT_URI
)

client_secret = sign_params_for_v2_by_csptest(client_secret_raw)
client_hash = "hash через calc_cert_hash_unix"

params_url = {
    "client_id": CLIENT_ID,
    "scope": SCOPE,
    "scope_org": SCOPE_ORG,
    "timestamp": TIMESTAMP,
    "state": STATE,
    "redirect_uri": REDIRECT_URI,
    "client_secret": client_secret,
    "response_type": "code",
    "access_type": "offline",
    "client_certificate_hash": client_hash,
}

params = urlencode(sorted(params_url.items()))
url = f"{SERVICE_URL}?{params}"
print("URL:", url)

Ответы (1 шт):

Автор решения: supreme1444 вас

Короче кому вдруг пригодится. Кидаю решение сей проблемы в виде рабочего кода. Короче говоря проблем было несколько. Кто будет делать просто берете код прописываете свой 'client_certificate_hash':'Hash' ,'client_id': client_idn,redirect_uri = "Редирект" и имя контейнера cont = f"Имя контейнера" . И все должно работать на получение кода. Главное посмотрите пути где лежит сам f'/opt/cprocsp/bin/amd64/csptest

import base64
import os
import tempfile
import uuid
from datetime import datetime,timezone,timedelta

from urllib import request
from urllib.parse import urlencode
from venv import logger
from flask import jsonify, request
import jwt
from util.redis import save_state_and_client_id_to_redis

API_KEY = "____"

def get_timestamp_v2():
    tz = timezone(timedelta(hours=3))
    now = datetime.now(tz)
    timestamp = now.strftime("%Y.%m.%d %H:%M:%S %z")
    return timestamp
z

async def sign_params_for_v2_by_csptest(client_secret_raw):
    cont = f"Имя контейнера"
    tmp_dir = tempfile.gettempdir()
    source_file = tempfile.NamedTemporaryFile(mode='w', delete=False, dir=tmp_dir)
    source_file.write(client_secret_raw)
    source_file.close()
    source_path = source_file.name
    destination_path = source_path + ".sig"
    cmd = (f'/opt/cprocsp/bin/amd64/csptest -keys -cont {cont} -sign GOST12_256 -in {source_path} -out {destination_path} -keytype exchange')
    os.system(cmd)
    signed_message = open(destination_path, 'rb').read()
    os.unlink(source_path)
    os.unlink(destination_path)
    return base64.urlsafe_b64encode(signed_message[::-1]).decode('utf-8')

async def get_data_sig_v2():
    auth_header = request.headers.get('Authorization')
    if not auth_header:
        return jsonify({'error': 'Authorization header is missing'}), 401
    token = auth_header.split(" ")[1] if " " in auth_header else auth_header

    try:
        decoded_token = jwt.decode(token, API_KEY, algorithms=["HS256"])
        client_id = decoded_token.get('client_id')

    except jwt.InvalidTokenError:
        return jsonify({'error': 'Invalid token'}), 401
    client_type = request.args.get('client_type')
    sign_data = request.args.get('sign_data')
    if client_type not in ['ul', 'fl'] or sign_data not in ['data_str', 'data_file']:
        return jsonify({'error': 'Missing required parameters'}), 400
    if client_type == "fl" and sign_data == 'data_str':
        scope = "openid fullname"
    elif client_type == "ul"  and sign_data == 'data_str':
        scope = "fullname birthdate  inn id_doc birthplace email mobile addresses org_inf"
    else:
        raise ValueError(f"Unknow client_type: {client_type}. expected 'fl' или 'ul'.")
    state = str(uuid.uuid4())
    params_to_redis={state:client_id}
    redirect_uri = "Редирект"
    time = get_timestamp_v2()
    client_idn = "Клиент ID"
    plaintext = (client_idn + scope + time + state + redirect_uri)
    client_secret = await sign_params_for_v2_by_csptest(plaintext)
    await save_state_and_client_id_to_redis(params_to_redis)
    try:
        params = {
            'client_id': client_idn,
            'scope': scope,
            'timestamp': time,
            'state': state,
            'redirect_uri':redirect_uri,
            'client_secret':client_secret,
            'response_type': 'code',
            'access_type': 'offline',
            'client_certificate_hash':'Hash'
        }
        params_encoded = urlencode(params)
        auth_url = f'https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v2/ac?{params_encoded}'
        logger.error(f"URL: {auth_url}")
        return jsonify({'auth_url': auth_url}), 200
    except Exception as e:
        logger.error(f"error generation auth URL: {str(e)}")
        return jsonify({'error': 'Error generation'}), 500







→ Ссылка