通过BotFramework-WebChat向微软聊天机器人传递ID Token认证咨询
回答
Q:能不能不用Azure AD/B2C等服务,仅用ID Token完成机器人认证?
当然可以!你完全不需要依赖第三方认证提供商,只要你的机器人后端能自定义实现ID Token的验证逻辑(比如解析Token内容、验证签名合法性、检查过期时间、匹配用户身份信息等),就可以完成用户身份认证,跳过机器人的登录流程。
Q:怎么通过botframework-webchat把ID Token发送给机器人?
你之前用普通event activity传递Token的方式确实不规范,这里给你两种更合理的实现方式,结合你的代码修改:
方式1:通过Direct Line连接的自定义头部传递(推荐)
这种方式会让Web Chat发送的每一个请求都自动携带ID Token,机器人可以通过中间件统一读取验证,非常适合需要全程验证身份的场景。
修改你创建directLine的代码:
const directLine = useMemo( () => createDirectLine({ token: '<你的Direct Line服务Token>', locale: 'sv-se', // 添加自定义HTTP头部,携带用户的ID Token headers: { 'X-User-Auth-Token': '<从应用登录状态获取的用户ID Token>' } }), [] );
方式2:在初始化会话的Activity的channelData中传递
如果只需要在会话启动时传递一次Token,可以把Token放在channelData字段里——这是Bot Framework官方指定的用于传递自定义业务数据的字段,比普通的value更规范。
修改你的useEffect代码:
useEffect(() => { // 从你的应用登录状态中获取用户的ID Token const userIDToken = localStorage.getItem('user-id-token'); const activity = { from: { id: '001', name: 'noviral' }, name: 'startConversation', type: 'event', // 将ID Token放入channelData channelData: { userAuthToken: userIDToken }, locale: language === 'en' ? 'en-US' : 'sv-se' }; directLine.postActivity(activity).subscribe(id => { console.log('Welcome message sent to health bot'); }); }, []);
关键:机器人端的验证逻辑
不管用哪种方式传递Token,机器人都需要添加对应的验证步骤:
- 获取Token:
- 如果用自定义头部:从请求头部读取
X-User-Auth-Token(不同语言的Bot SDK获取方式略有不同,比如C#可以通过TurnContext.Activity.GetHttpRequest().Headers获取) - 如果用
channelData:直接从TurnContext.Activity.ChannelData.userAuthToken中提取
- 如果用自定义头部:从请求头部读取
- 验证Token:用你的应用生成Token时使用的密钥解析Token,检查签名是否合法、Token是否过期、用户ID是否匹配等
- 跳过登录:验证通过后,机器人就可以确认用户已登录,直接进入业务流程,不再要求用户重复登录
小提示
- 务必确保Token的传输是通过HTTPS加密的,避免敏感信息泄露
- 不要把ID Token放在普通的
value或自定义字段里,channelData是官方推荐的标准方式 - 机器人端要做好Token过期的处理逻辑,如果Token过期,可以引导用户重新在应用中登录
内容的提问来源于stack exchange,提问作者Ayesh Nipun




