Skip to content

Teams SSO Flow #276

Closed
Closed

Description

@RahulKumble

I am building a conversational chatbot for microsoft teams using the new Agents SDK in python, I built a different bot using the 0.2.0 release of the framework in the past where I would handle user consent and SSO in my messaging endpoint like so:

@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _: TurnState) -> None:
    user_id: str = context.activity.from_property.aad_object_id
    token = None

    typing_indicator = TypingIndicator(interval=800)
    await typing_indicator.start(context)

    if token_cache.does_valid_token_exist(user_id):
        token: Optional[str] = token_cache.get_token(user_id)

    if not token:
        token_response: Optional[TokenResponse] = await AGENT_APP.auth.get_token(
            context, "GRAPH"
        )
        if token_response and token_response.token:
            token: str = token_response.token
            token_cache.add_user_token(user_id, token)
        else:
            async with AGENT_APP.auth.open_flow(context, "GRAPH") as flow:
                flow_response: FlowResponse = await flow.begin_or_continue_flow(
                    context.activity
                )

                if flow_response.sign_in_resource:
                    await context.send_activity(
                        create_oauth_signin_activity(flow_response)
                    )
                    return

    if user_id not in message_cache.cache:
        hist: List[Dict[str, str]] = await get_n_message_history(context, token, 10)
        message_cache.add_history(user_id, hist)

    message_cache.add_new_message(user_id, context.activity.text)

    async with httpx.AsyncClient() as client:
        agent_response: Response = await client.post(
            f"{API_BASE_URL}/v1/agent/messages",
            json={
                "user": context.activity.from_property.name,
                "history": message_cache.get_user_history(user_id),
            },
            timeout=30.0,
        )
        response: Dict = agent_response.json()

    bot_message: Optional[str] = response.get("message")

    if bot_message not in tools:
        message_cache.add_new_message(user_id, bot_message, True)
        await context.send_activity(f"{bot_message}")
        typing_indicator.stop()
    else:
        await context.send_activity(tools.get(bot_message)())
        typing_indicator.stop()

however since then, the open_flow() and access to FlowResponse or really any way to control the oauth flow has been removed according to this Pull Request . Since the framework is almost completely undocumented I would like to know what the new way of doing this is.

My main goal here is:

  1. On user message, check if there is a valid token in my cache, if not send an oauth sso card and cache the new token

I would like to know the idiomatic way to handle this issue, because all the stuff I was relying on has either been made private or removed entirely. I tried using the get_token() and exchange_token() functions in the Authorization class however it appears they will always fail because get_token() just calls exchange_token() which only attempts to get a new token if there is already a token that has been cached internally by the framework, since I do not have this token at startup these functions are functionally useless.

Thank you.

Activity

  1. rodrigobr-msft commented on Dec 3, 2025

    @rodrigobr-msft
    Contributor

    Hi, you can specify a list of authorization handlers when registering the route with auth_handlers=["GRAPH"]. This will have the SDK handle the auth flow for you:

    @AGENT_APP.activity("message", auth_handlers=["GRAPH"])
    async def on_message(context: TurnContext, _: TurnState) -> None:
        user_id: str = context.activity.from_property.aad_object_id
        token_response: TokenResponse = await AGENT_APP.auth.get_token(context, "GRAPH")
        token: Optional[str] = None
    
        if token_response:
            token = token_response.token
    
        typing_indicator = TypingIndicator(interval=800)
        await typing_indicator.start(context)
    
        if token_cache.does_valid_token_exist(user_id):
            token: Optional[str] = token_cache.get_token(user_id)
    
        # remainder of your code here

    Let us know if that helps or if you have any more questions.

  2. RahulKumble commented on Dec 4, 2025

    @RahulKumble
    Author

    Rodrigo Brandão (@rodrigobr-msft) thanks for the prompt response but I have tried that before, the reason I chose to do it manually in the earlier bot is because adding the auth handler to the message handler led to rather strange and unreliable behavior if the user had provided consent earlier and then quit teams, on restarting teams it made it so that when the user sent a new message for the bot whether it would reply or not was essentially random because sometimes it would just not send the card as if the user were already authenticated but would not post a reply back. doing it manually was the only reliable solution at the time. since I do not control the teams client I would like the ability to have some control over this process, is that still possible or has it been removed?

  3. RahulKumble commented on Dec 4, 2025

    @RahulKumble
    Author

    also side note but while I understand this sdk is still in preview, I am curious to know when we can expect good documentation for it since from what I understand this is the new way of building applications for microsoft platforms now that bot framework is reaching EOL because it is rather frustrating to have to piece together an understanding of the framework from library source and disparate pieces of documentation for versions of the SDK for other languages and sometimes older documentation for bot framework.

  4. rodrigobr-msft commented on Dec 4, 2025

    @rodrigobr-msft
    Contributor

    @rodrigobr-msft thanks for the prompt response but I have tried that before, the reason I chose to do it manually in the earlier bot is because adding the auth handler to the message handler led to rather strange and unreliable behavior if the user had provided consent earlier and then quit teams, on restarting teams it made it so that when the user sent a new message for the bot whether it would reply or not was essentially random because sometimes it would just not send the card as if the user were already authenticated but would not post a reply back. doing it manually was the only reliable solution at the time. since I do not control the teams client I would like the ability to have some control over this process, is that still possible or has it been removed?

    For which version(s) did you observe this behavior? Auth flows in the SDK have changed a lot, as you know, over the past few months. This is definitely something we would like to address if that issue still exists in the SDK.

  5. rodrigobr-msft commented on Dec 4, 2025

    @rodrigobr-msft
    Contributor

    also side note but while I understand this sdk is still in preview, I am curious to know when we can expect good documentation for it since from what I understand this is the new way of building applications for microsoft platforms now that bot framework is reaching EOL because it is rather frustrating to have to piece together an understanding of the framework from library source and disparate pieces of documentation for versions of the SDK for other languages and sometimes older documentation for bot framework.

    We are currently working to overhaul our developer docs across all languages, but for the time being, the samples in the parent repo might be helpful. I'll point you to this sample: https://github.com/microsoft/Agents/tree/main/samples/python/obo-authorization.

    In the meantime, feel free to reach out with any further questions!

  6. RahulKumble commented on Dec 5, 2025

    @RahulKumble
    Author

    @rodrigobr-msft thanks for the prompt response but I have tried that before, the reason I chose to do it manually in the earlier bot is because adding the auth handler to the message handler led to rather strange and unreliable behavior if the user had provided consent earlier and then quit teams, on restarting teams it made it so that when the user sent a new message for the bot whether it would reply or not was essentially random because sometimes it would just not send the card as if the user were already authenticated but would not post a reply back. doing it manually was the only reliable solution at the time. since I do not control the teams client I would like the ability to have some control over this process, is that still possible or has it been removed?

    For which version(s) did you observe this behavior? Auth flows in the SDK have changed a lot, as you know, over the past few months. This is definitely something we would like to address if that issue still exists in the SDK.

    versions 0.2.0 and 0.3.0 I think, not quite sure what patch version though

  7. jkshan commented on Jun 14, 2026

    @jkshan

    I think that the finding I have on #414 might be causing the issue. As I still encounter the issue (v0.9.1 and v1.0.0) Do let me know this is addressed already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions