Приложение Microsoft Bot Framework выдает ошибку «Несанкционированный доступ. Запрос не авторизован» при попытке отправить сообщение с помощью «Тест в веб-чате»

Я пытаюсь создать простой эхо-бот, используя SDK платформы ботов Python. Мой бот без проблем работает локально с помощью эмулятора. Я использовал ngrok для создания туннеля https для своего приложения, а затем зарегистрировал бота с помощью службы ботов Azure (тип бота: мультитенантный). Я добавил app_id и секрет из службы бота в свое приложение, и когда я тестирую отправку сообщений из службы бота с помощью функции «Тестирование в веб-чате», я получаю ошибку «Несанкционированный доступ. Запрос не авторизован» в журнале приложения.

Я тестировал эмулятор без учетных данных, и он работает, также я могу успешно получить токен с тем же app_id и паролем, когда тестирую, используя: «curl -k -X POST https://login.microsoftonline.com/botframework.com/ oauth2/v2.0/token -d "grant_type=client_credentials&client_id=my_app_id_here&client_secret=my_app_secret_here&scope=https%3A%2F%2Fapi.botframework.com%2F.default"

Но когда я пытаюсь отправить сообщение из бот-сервиса Test в веб-чат, я получаю сообщение «Несанкционированный доступ. Запрос не авторизован» в приложении.

Трассировки стека:

    [2024-05-23 22:27:15,827] ERROR in app: Exception on /api/messages [POST]
    Traceback (most recent call last):
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 1473, in wsgi_app
        response = self.full_dispatch_request()
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 882, in full_dispatch_request
        rv = self.handle_user_exception(e)
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 880, in full_dispatch_request
        rv = self.dispatch_request()
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 865, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/app.py", line 30, in messages
        loop.run_until_complete(task)
    File "/home/metalmlover/.pyenv/versions/3.8.16/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
        return future.result()
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/botbuilder/core/bot_framework_adapter.py", line 442, in process_activity
        identity = await self._authenticate_request(activity, auth_header)
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/botbuilder/core/bot_framework_adapter.py", line 551, in _authenticate_request
        claims = await JwtTokenValidation.authenticate_request(
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/botframework/connector/auth/jwt_token_validation.py", line 49, in authenticate_request
        raise PermissionError("Unauthorized Access. Request is not authorized")
    PermissionError: Unauthorized Access. Request is not authorized
    127.0.0.1 - - [23/May/2024 22:27:15] "POST /api/messages HTTP/1.1" 500 -
    127.0.0.1 - - [23/May/2024 22:27:25] "OPTIONS /api/messages HTTP/1.1" 200 -
    127.0.0.1 - - [23/May/2024 22:34:59] "OPTIONS /api/messages HTTP/1.1" 200 -
    127.0.0.1 - - [23/May/2024 22:35:04] "OPTIONS /api/messages HTTP/1.1" 200 -
    [2024-05-23 22:35:08,763] ERROR in app: Exception on /api/messages [POST]
    Traceback (most recent call last):
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 1473, in wsgi_app
        response = self.full_dispatch_request()
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 882, in full_dispatch_request
        rv = self.handle_user_exception(e)
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 880, in full_dispatch_request
        rv = self.dispatch_request()
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/flask/app.py", line 865, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/app.py", line 30, in messages
        loop.run_until_complete(task)
    File "/home/metalmlover/.pyenv/versions/3.8.16/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
        return future.result()
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/botbuilder/core/bot_framework_adapter.py", line 442, in process_activity
        identity = await self._authenticate_request(activity, auth_header)
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/botbuilder/core/bot_framework_adapter.py", line 551, in _authenticate_request
        claims = await JwtTokenValidation.authenticate_request(
    File "/home/metalmlover/dev/microsoft bot framework/BotTutorialSample/Python_tutorial/01-EchoBot/venv/lib/python3.8/site-packages/botframework/connector/auth/jwt_token_validation.py", line 49, in authenticate_request
        raise PermissionError("Unauthorized Access. Request is not authorized")
    PermissionError: Unauthorized Access. Request is not authorized

Мой код приложения:

    from flask import Flask,request,Response
    from botbuilder.schema import Activity
    from botbuilder.core import BotFrameworkAdapter,BotFrameworkAdapterSettings
    import asyncio    
    from echobot import EchoBot    
    app = Flask(__name__)
    loop = asyncio.get_event_loop()    
    botadaptersettings = BotFrameworkAdapterSettings("my_app_id_here","my_app_secret_here")
    botadapter = BotFrameworkAdapter(botadaptersettings)    
    ebot = EchoBot()    
    @app.route("/api/messages",methods=["POST"])
    def messages():    
        if "application/json" in request.headers["content-type"]:
        jsonmessage = request.json
        else:
        return Response(status=415)
    
        activity = Activity().deserialize(jsonmessage)
    
        async def turn_call(turn_context):
            await ebot.on_turn(turn_context)
    
        task = loop.create_task(botadapter.process_activity(activity,"",turn_call))
        loop.run_until_complete(task)
        return "200"
    
    if __name__ == '__main__':
        app.run('localhost',3978)

Мой бот:

    from botbuilder.core import TurnContext

    class EchoBot:
        async def on_turn(self,turn_context:TurnContext):
            await turn_context.send_activity(turn_context.activity.text)

Конфигурация бота Azure:

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обратитесь в MSDOC. для создания эхо-бота с использованием SDK платформы Python.

app.py:

import sys
import traceback
from datetime import datetime

from aiohttp import web
from aiohttp.web import Request, Response, json_response
from botbuilder.core import (BotFrameworkAdapter, BotFrameworkAdapterSettings,
                             TurnContext)
from botbuilder.core.integration import aiohttp_error_middleware
from botbuilder.schema import Activity, ActivityTypes

from bot import MyBot
from config import DefaultConfig

CONFIG = DefaultConfig()

SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD)
ADAPTER = BotFrameworkAdapter(SETTINGS)

async def on_error(context: TurnContext, error: Exception):

    print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr)
    traceback.print_exc()

    await context.send_activity("The bot encountered an error or bug.")
    await context.send_activity(
        "To continue to run this bot, please fix the bot source code."
    )

    if context.activity.channel_id == "emulator":

        trace_activity = Activity(
            label = "TurnError",
            name = "on_turn_error Trace",
            timestamp=datetime.utcnow(),
            type=ActivityTypes.trace,
            value=f"{error}",
            value_type = "https://www.botframework.com/schemas/error",
        )

        await context.send_activity(trace_activity)


ADAPTER.on_turn_error = on_error

# Create the Bot
BOT = MyBot()

# Listen for incoming requests on /api/messages
async def messages(req: Request) -> Response:
    # Main bot message handler.
    if "application/json" in req.headers["Content-Type"]:
        body = await req.json()
    else:
        return Response(status=415)

    activity = Activity().deserialize(body)
    auth_header = req.headers["Authorization"] if "Authorization" in req.headers else ""

    response = await ADAPTER.process_activity(activity, auth_header, BOT.on_turn)
    if response:
        return json_response(data=response.body, status=response.status)
    return Response(status=201)


def init_func(argv):
    APP = web.Application(middlewares=[aiohttp_error_middleware])
    APP.router.add_post("/api/messages", messages)
    return APP
if __name__ == "__main__":
    APP = init_func(None)

    try:
        web.run_app(APP, host = "0.0.0.0", port=CONFIG.PORT)
    except Exception as error:
        raise error

config.py:

  • Обновите идентификатор и пароль приложения Microsoft.
class DefaultConfig:
    """ Bot Configuration """

    PORT = 3978
    APP_ID = os.environ.get("MicrosoftAppId", "<AppID>")
    APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "<Password>")
  • Создайте новый туннель с помощью команды ngrok.
ngrok http 3978 --host-header rewrite
  • Веб-интерфейс http://127.0.0.1:4040
  • Переадресация https://b437-2402-8100-2844-2f53-1181-ffb7-df6c-560d.ngrok-free.app -> http://localhost:3978

Перейдите к разделу «Конфигурация» в Azure Bot=>Settings, вставьте сгенерированный ngrok forwarding URL в поле «Конечная точка обмена сообщениями», добавив «/api/messages» в конце URL-адреса.

Протестируйте бота в веб-чате:

Консольный вывод:

Я следовал инструкциям, и это сработало, большое спасибо, ура.

metalmlover 24.05.2024 12:41

Другие вопросы по теме