pythonazureoauth-2.0botframeworkbot-emulator

Bot Framework Python SDK ErrorResponseException: Operation returned an invalid status code 'Unauthorized'


I am looking for some help implementing AAD authentication in a bot framework project with the Python SDK.

What I have done:

I have checked my app reg by calling it directly and it does work flawlessly returning a 200 response and access token: enter image description here

In VS Code, I have a python 3.11 venv. I successfully start my bot web app and open it in the emulator by also providing the app id and client secret: enter image description here However, when the flow starts executing the authentication logic I get this error in the console, essentially telling me something is Unauthorized. At this point I am confused and have no further ideas how to debug this considering my resources and configurations appear to be correctly set. I am working in a client's tenant where I have contributor role and have created all stated resources on my own. Is it still possible an admin needs to authorize something? What am I missing?


 [on_turn_error] unhandled error: Operation returned an invalid status code 'Unauthorized'
Traceback (most recent call last):
  File "working_dir\.venv\Lib\site-packages\botbuilder\core\bot_adapter.py", line 174, in run_pipeline
    return await self._middleware.receive_activity_with_status(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\core\middleware_set.py", line 69, in receive_activity_with_status
    return await self.receive_activity_internal(context, callback)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\core\middleware_set.py", line 79, in receive_activity_internal  
    return await callback(context)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\bot\bots\dialog_bot.py", line 31, in on_turn
    await super().on_turn(turn_context)
  File "working_dir\.venv\Lib\site-packages\botbuilder\core\activity_handler.py", line 70, in on_turn
    await self.on_message_activity(turn_context)
  File "working_dir\bot\bots\dialog_bot.py", line 38, in on_message_activity
    await DialogHelper.run_dialog(
  File "working_dir\bot\helpers\dialog_helper.py", line 16, in run_dialog
    await dialog_context.begin_dialog(dialog.id)
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\dialog_context.py", line 121, in begin_dialog
    return await dialog.begin_dialog(self, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\component_dialog.py", line 67, in begin_dialog
    turn_result = await self.on_begin_dialog(inner_dc, options)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\bot\dialogs\logout_dialog.py", line 21, in on_begin_dialog
    return await super().on_begin_dialog(inner_dc, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\component_dialog.py", line 221, in on_begin_dialog      
    return await inner_dc.begin_dialog(self.initial_dialog_id, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\dialog_context.py", line 121, in begin_dialog
    return await dialog.begin_dialog(self, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\waterfall_dialog.py", line 64, in begin_dialog
    return await self.run_step(dialog_context, 0, DialogReason.BeginCalled, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\waterfall_dialog.py", line 154, in run_step
    return await self.on_step(step_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\waterfall_dialog.py", line 130, in on_step
    return await self._steps[step_context.index](step_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\bot\dialogs\main_dialog.py", line 51, in prompt_step
    return await step_context.begin_dialog(OAuthPrompt.__name__)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\dialog_context.py", line 121, in begin_dialog
    return await dialog.begin_dialog(self, options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\prompts\oauth_prompt.py", line 168, in begin_dialog     
    output = await _UserTokenAccess.get_user_token(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botbuilder\dialogs\_user_token_access.py", line 27, in get_user_token      
    return await user_token_client.get_user_token(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botframework\connector\auth\_user_token_client_impl.py", line 44, in get_user_token
    result = await self._client.user_token.get_token(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "working_dir\.venv\Lib\site-packages\botframework\connector\token_api\aio\operations_async\_user_token_operations_async.py", line 100, in get_token
    raise models.ErrorResponseException(self._deserialize, response)
botframework.connector.token_api.models._models_py3.ErrorResponseException: Operation returned an invalid status code 'Unauthorized'
Datetime with no tzinfo will be considered UTC.

Solution

  • I solved the issue by changing the bot data residency from "Europe" to "Global" and the related redirect URI's. Unclear what was the root cause though.