You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bot Framework实现Teams中用户完全登出的问题

彻底实现Teams机器人登出并清除令牌缓存的方法

核心问题分析

你遇到的自动重新登录,本质是Bot Framework的令牌缓存(包括服务器端和Teams客户端的OAuth会话)未完全清除,即便调用了SignOutUserAsync,仍存在缓存残留或会话状态未重置导致的静默自动登录。

完整解决方案步骤

1. 全面清除服务器端令牌与会话状态

除现有代码外,需补充清除用户状态和会话状态的逻辑,确保服务器端无残留令牌数据:

// 获取UserTokenClient实例
var userTokenClient = innerDc.Context.TurnState.Get<UserTokenClient>();
var userId = innerDc.Context.Activity.From.Id;
var channelId = innerDc.Context.Activity.ChannelId;

// 1. 清除服务器端存储的用户令牌
await userTokenClient.SignOutUserAsync(userId, _connectionName, channelId, cancellationToken).ConfigureAwait(false);

// 2. 清空本地用户状态中的令牌相关数据(如果使用了UserState)
var userState = innerDc.Context.TurnState.Get<UserState>();
var userProfileProperty = userState.CreateProperty<UserProfile>("UserProfile");
var userProfile = await userProfileProperty.GetAsync(innerDc.Context, () => new UserProfile());
userProfile.Token = null; // 重置令牌字段
await userState.SaveChangesAsync(innerDc.Context, false, cancellationToken).ConfigureAwait(false);

// 3. 取消所有对话框并重置对话状态
await innerDc.CancelAllDialogsAsync(cancellationToken);
var conversationState = innerDc.Context.TurnState.Get<ConversationState>();
await conversationState.ClearStateAsync(innerDc.Context, cancellationToken).ConfigureAwait(false);

// 4. 发送登出确认消息
await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);

2. 强制Teams客户端清除OAuth会话缓存

Teams客户端会缓存OAuth授权会话,需通过专用卡片触发客户端缓存清除:

// 创建带登出操作的卡片,触发客户端会话清除
var signOutCard = new HeroCard
{
    Text = "You have been signed out. Click below to clear your session completely.",
    Buttons = new List<CardAction>
    {
        new CardAction(ActionTypes.Signout, "Clear Session", value: _connectionName)
    }
};

await innerDc.Context.SendActivityAsync(MessageFactory.Attachment(signOutCard.ToAttachment()), cancellationToken);

该Signout类型按钮会直接清除Teams客户端中当前用户与机器人的OAuth会话缓存,从根源避免自动登录。

3. 配置OAuthPrompt禁用自动登录

确保OAuthPrompt不依赖自动令牌获取,每次交互主动触发登录验证:

// 初始化OAuthPrompt时明确配置登录提示
var oauthPrompt = new OAuthPrompt(
    "OAuthPrompt",
    new OAuthPromptSettings
    {
        ConnectionName = _connectionName,
        Title = "Sign In",
        Text = "Please sign in to continue.",
        Timeout = 300000 // 设置5分钟超时
    });

// 在对话逻辑中主动检查令牌状态,无令牌则触发登录
if (!await oauthPrompt.HasTokenAsync(innerDc.Context, cancellationToken))
{
    await innerDc.BeginDialogAsync("OAuthPrompt", null, cancellationToken);
    return DialogTurnResult.Waiting;
}

4. 检查Azure Bot Service缓存配置(若使用)

如果机器人部署在Azure,需确认OAuth连接的缓存策略:

  • 进入Azure门户的Bot资源,导航到配置 -> OAuth连接设置
  • 确认令牌过期时间设置合理,未启用不必要的持久化缓存

验证流程

  1. 用户发送log me out指令,机器人执行登出逻辑并发送清除会话卡片
  2. 用户点击卡片上的Clear Session按钮
  3. 用户发送下一条消息,机器人自动弹出OAuth登录对话框,要求手动登录

内容的提问来源于stack exchange,提问作者Gaurav Mantri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:47:12