microsoft / botbuilder-python

The Microsoft Bot Framework provides what you need to build and connect intelligent bots that interact naturally wherever your users are talking, from text/sms to Skype, Slack, Office 365 mail and other popular services.
http://botframework.com
MIT License
672 stars 271 forks source link

Error while trying to use JwtTokenValidation.authenticate_request #2114

Open Loprock opened 1 month ago

Loprock commented 1 month ago

Github issues should be used for bugs and feature requests. Use Stack Overflow for general "how-to" questions.

Version

botbuilder-schema==4.11.0 botframework-connector==4.11.0

Describe the bug

Using python. After using the following request 'JwtTokenValidation.authenticate_request' we started getting the error: [Errno Unauthorized. Invalid AppId passed on token: ] b****-4-4-8-a*** this issue started occurring from ~March 2024

To Reproduce

Steps to reproduce the behavior: the whole flow is represented in the code snippet. after the main init we try to setup a webhook which is failing

Expected behavior

we want the auth to get approved and manage to communicate

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

adding a code snippet to show the flow (only relevant for this issue)

 class MicrosoftTeamsMainloop(FrameworkMainloop):
    def __init__(self, config):
        super().__init__(config)
        self.client = MicrosoftTeamsClient(config.bot_id, config.app_password)
        self.user_cache = TeamsUsersCache(self.client)
        self.app = Flask(__name__)
        self.setup_webhook_app()
        self._maybe_setup_global_proxy_for_process()

    def setup_webhook_app(self):
        @self.app.route("/", methods=["POST"])
        def webhook():
            # pass on the flask global request object
            return self.handle_post(request)

    def authenticate_webhook(self, current_request: Request, activity: Activity):
        logger = get_algobot_logger()
        loop = asyncio.new_event_loop()
        try:
            loop.run_until_complete(
                JwtTokenValidation.authenticate_request(
                    activity,
                    current_request.headers.get("Authorization"),
                    self.credential_provider,
                )
            )
            return True
        except Exception as e:
            logger.error('exception {} thrown while trying to authenticate webhook.'.format(e))
            return False
        finally:
            loop.close()
tracyboehrer commented 1 month ago

@Loprock That error indicates the token the bot received does not contain the correct audience claim. The expectation is that the audience claim matches the bots AppId. Is 4.11.0 correct? That was released in Nov 2020. If accurate, this is ually because the config for the bot is wrong.

Loprock commented 1 week ago

The config was correct.. i verified it multiple times. but the issue persists

tracyboehrer commented 1 week ago

As a start, I would recommend updating to the latest released version, and review what changed around March. But if you've been using this bot without changes, and it started happening in March, this would lead to some other change outside the bot happening.

Loprock commented 1 week ago

Tried doing it on multiple bots, each with a different AppId, getting the same error every time, with the new AppId in the logs. getting the exact same error - > [Errno Unauthorized. Invalid AppId passed on token: ] I can try and upgrade the whole project but the code I'm using didn't change since it was written as far as I can tell from what I saw in the repo (the whole Auth section)

tracyboehrer commented 1 week ago

The exact cause is the 'aud' claim in the token the bot received doesn't match the bots appId in config. This is part of token validation. If your bot hasn't changed then this is a config issue elsewhere. Did your Azure resources change? If you run the bot in debug, and break in your app.py, 'messages' function. Take the token in the 'Authorization' header and decode it (search for 'JWT token decoder'). You'll be able to see what 'aud' claim is being sent.

Loprock commented 1 week ago

I actually run the bot from within a script that runs on a VM I use (as part of a bigger product), when I do that I can't really break the code in that exact spot since it's a production environment so I can only throw logs outside while it's active. is there any way to see this 'aud' claim without a breakpoint? can I get it through a field within the class? or add it to the exception data somehow?

tracyboehrer commented 1 week ago

You could log it. I would recommend removing that log message when done though.

tracyboehrer commented 1 week ago

Actually... the error message should have the appId it received in it.

Loprock commented 1 week ago

The AppID I got matches exactly to the one I have in my Azure app and the same one I set over the .conf file over the machine

Loprock commented 1 week ago

@tracyboehrer I also saw this thread, which was magically solved one day, I think the issue isn't on my end, is it possible that it's on Microsoft's end? https://github.com/microsoft/botbuilder-python/issues/1983