microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3ddf9fa76ec1801a0e3ca312c6d9855879571ac1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/docs/sso/oauthflowbot-trace-2026-04-22-summary.md

355lines ยท modecode

1# ๐Ÿ” OAuthFlowBot Trace Summary (Popup Fallback)
2
3**Date**: 2026-04-22 03:12:00 UTC
4**Bot**: my-bot-sso (AppID: `e3cb1c84-14e3-419c-b39c-1c06097b55fd`)
5**User**: Rido (aadObjectId: `03500558-e554-416c-90c3-a061cdcd012b`)
6**Connection**: `teamsgraph` (Azure AD v2, no SSO โ€” popup fallback)
7**Platform**: ๐ŸŒ Web (Teams)
8**SDK Version**: `0.0.1-alpha-0107-g1c503584a7`
9**Result**: โœ… SUCCESS (login graph + my ad user + logout graph)
10
11> **Key difference from SsoBot**: This connection does not have `tokenExchangeResource` (SSO not configured).
12> Login completes via **popup sign-in** + `signin/verifyState` instead of silent `signin/tokenExchange`.
13
14### ๐Ÿ†” Identity Reference
15
16| Identity | MRI / Value |
17|----------|-------------|
18| User MRI | `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` |
19| User AAD ObjectId | `03500558-e554-416c-90c3-a061cdcd012b` |
20| Bot MRI | `28:e3cb1c84-14e3-419c-b39c-1c06097b55fd` |
21| Bot AppId | `e3cb1c84-14e3-419c-b39c-1c06097b55fd` |
22| Tenant Id | `3f3d1cea-7a18-41af-872b-cfbbd5140984` |
23| Conversation Id | `a:1xH4HncZ6lyZnMVYp9rTKoRyS44qDCikYZ1u-Q0VNmZqyceL6nKfe5ZKG9CqOi2WuXNDJyLBAaDgVChKMxKFPlAZ5bsy0_8RhvPYYi5ZJJKCiia_SEd_e8WJVlSHOIM3Z` |
24| Service URL | `https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/` |
25
26---
27
28## ๐Ÿ”‘ Login Flow (Popup Fallback โ€” no SSO)
29
30### Step 1 โ€” User sends "login graph" message
31
32๐Ÿ“ฅ **INCOMING** `POST http://localhost:3978/api/messages`
33- **Activity**:
34 - `type`: `message`
35 - `id`: `1776827520098`
36 - `channelId`: `msteams`
37 - `text`: `"login graph"`
38 - `textFormat`: `plain`
39 - `timestamp`: `2026-04-22T03:12:00.1176725Z`
40 - `from.id`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
41 - `from.name`: `Rido`
42 - `from.aadObjectId`: `03500558-e554-416c-90c3-a061cdcd012b`
43 - `recipient.id`: `28:e3cb1c84-14e3-419c-b39c-1c06097b55fd` *(Bot MRI)*
44 - `recipient.name`: `my-bot-sso`
45 - `conversation.id`: `a:1xH4HncZ6ly...OIM3Z`
46 - `conversation.conversationType`: `personal`
47 - `conversation.tenantId`: `3f3d1cea-7a18-41af-872b-cfbbd5140984`
48 - `serviceUrl`: `https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/`
49 - `entities[0]`: `{ locale: "en-US", country: "US", platform: "Web", timezone: "America/Los_Angeles", type: "clientInfo" }`
50 - `MSCV`: `4+YxTIufBEq78SeAVHsSdQ.1.1.1.485196365.1.1`
51- ๐Ÿ›ก๏ธ JWT validated (AzureAd scheme)
52- ๐Ÿ”€ Route: `message/(?i)^login graph$`
53
54### Step 2 โ€” Silent token check (no cached token)
55
56๐Ÿ“ค **OUTGOING** `GET https://token.botframework.com/api/usertoken/GetToken`
57- **Query Parameters**:
58 - `userid`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
59 - `connectionName`: `teamsgraph`
60 - `channelId`: `msteams`
61- **Request Body**: `(null)`
62- **Auth**: ๐Ÿ”‘ MSAL AcquireTokenForClient (source: IdentityProvider) โ€” first token from AAD
63- โŒ **Response**: `404` โ€” no cached user token
64
65### Step 3 โ€” Get sign-in resource
66
67๐Ÿ“ค **OUTGOING** `GET https://token.botframework.com/api/botsignin/GetSignInResource`
68- **Query Parameters**:
69 - `state`: base64-encoded JSON:
70 ```json
71 {
72 "ConnectionName": "teamsgraph",
73 "Conversation": {
74 "ActivityId": "1776827520098",
75 "Bot": { "Id": "28:e3cb1c84-14e3-419c-b39c-1c06097b55fd" },
76 "ChannelId": "msteams",
77 "Conversation": { "Id": "a:1xH4HncZ6ly...OIM3Z" },
78 "ServiceUrl": "https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/",
79 "User": { "Id": "29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ" }
80 },
81 "MsAppId": "e3cb1c84-14e3-419c-b39c-1c06097b55fd"
82 }
83 ```
84- **Request Body**: `(null)`
85- **Auth**: ๐Ÿ”‘ MSAL from cache
86- โœ… **Response**: `200` โ€” returns signInLink + tokenPostResource, **โš ๏ธ NO tokenExchangeResource** (SSO not configured)
87
88### Step 4 โ€” Send OAuthCard to user (popup only, no SSO)
89
90๐Ÿ“ค **OUTGOING** `POST https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/v3/conversations/a%3A1xH4HncZ6ly...OIM3Z/activities/1776827520098`
91- **Auth**: ๐Ÿ”‘ MSAL from cache
92- **Request Body**:
93 ```json
94 {
95 "from": {
96 "id": "28:e3cb1c84-14e3-419c-b39c-1c06097b55fd",
97 "name": "my-bot-sso"
98 },
99 "recipient": {
100 "id": "29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ",
101 "name": "Rido",
102 "aadObjectId": "03500558-e554-416c-90c3-a061cdcd012b"
103 },
104 "conversation": {
105 "tenantId": "3f3d1cea-7a18-41af-872b-cfbbd5140984",
106 "conversationType": "personal",
107 "id": "a:1xH4HncZ6ly...OIM3Z"
108 },
109 "attachments": [{
110 "contentType": "application/vnd.microsoft.card.oauth",
111 "content": {
112 "text": "Please Sign In",
113 "connectionName": "teamsgraph",
114 "buttons": [{
115 "type": "signin",
116 "title": "Sign In",
117 "value": "https://token.botframework.com/api/oauth/signin?signin=02706e367e884e8ea4e86472cbd71932"
118 }],
119 "tokenPostResource": {
120 "SasUrl": "https://token.botframework.com/api/sas/postToken?expiry=1776827583&id=key2&state=02706e367e884e8ea4e86472cbd71932&hmac=..."
121 }
122 }
123 }],
124 "type": "message",
125 "channelId": "msteams",
126 "serviceUrl": "https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/",
127 "replyToId": "1776827520098"
128 }
129 ```
130 > **Note**: `tokenExchangeResource` is **omitted** (not sent as null). This is the fix applied in this run โ€” previously it was serialized as `"tokenExchangeResource": null` which caused Teams to reject with `BadRequest`.
131- โœ… **Response**: `200`
132
133๐Ÿ **HTTP Response to Teams**: `200`
134
135### Step 5 โ€” User completes popup sign-in, Teams sends signin/verifyState
136
137๐Ÿ“ฅ **INCOMING** `POST http://localhost:3978/api/messages`
138- **Activity**:
139 - `type`: `invoke`
140 - `name`: `signin/verifyState`
141 - `id`: `f:7d1e8ec2-5897-396e-aa7b-f579ad2fac9f`
142 - `channelId`: `msteams`
143 - `timestamp`: `2026-04-22T03:12:09.445Z`
144 - `from.id`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
145 - `from.name`: `Rido`
146 - `from.aadObjectId`: `03500558-e554-416c-90c3-a061cdcd012b`
147 - `recipient.id`: `28:e3cb1c84-14e3-419c-b39c-1c06097b55fd` *(Bot MRI)*
148 - `recipient.name`: `my-bot-sso`
149 - `conversation.id`: `a:1xH4HncZ6ly...OIM3Z`
150 - `conversation.conversationType`: `personal`
151 - `conversation.tenantId`: `3f3d1cea-7a18-41af-872b-cfbbd5140984`
152 - `serviceUrl`: `https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/`
153 - `replyToId`: `1776827524158`
154 - `channelData.source.name`: `message`
155 - `channelData.legacy.replyToId`: `1:1m2Cdy7qBU0p3417d81g04kt7MXJrjQC-X21CRiZVWzk`
156 - `value`: `{ "state": "745254" }` *(verification code from popup)*
157 - `MSCV`: `FvSbzMYrUE+OReNyK+4lyg.1.3`
158- ๐Ÿ›ก๏ธ JWT validated (AzureAd scheme)
159- ๐Ÿ”€ Route: `invoke/signin/verifyState`
160
161### Step 6 โ€” Verify state and get token
162
163๐Ÿ“ค **OUTGOING** `GET https://token.botframework.com/api/usertoken/GetToken`
164- **Query Parameters**:
165 - `userid`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
166 - `connectionName`: `teamsgraph`
167 - `channelId`: `msteams`
168 - `code`: `745254` *(verification code from verifyState)*
169- **Request Body**: `(null)`
170- **Auth**: ๐Ÿ”‘ MSAL from cache
171- โœ… **Response**: `200` โ€” user token returned
172
173### Step 7 โ€” ๐ŸŽ‰ OnSignInComplete fires, bot sends confirmation
174
175๐Ÿ“ค **OUTGOING** `POST https://smba.trafficmanager.net/amer/.../v3/conversations/a%3A1xH4HncZ6ly...OIM3Z/activities/f:7d1e8ec2-5897-396e-aa7b-f579ad2fac9f`
176- **Auth**: ๐Ÿ”‘ MSAL from cache
177- **Request Body**:
178 ```json
179 {
180 "from": { "id": "28:e3cb1c84-14e3-419c-b39c-1c06097b55fd", "name": "my-bot-sso" },
181 "conversation": { "tenantId": "3f3d1cea-...", "conversationType": "personal", "id": "a:1xH4HncZ6ly...OIM3Z" },
182 "type": "message",
183 "channelId": "msteams",
184 "serviceUrl": "https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/",
185 "replyToId": "f:7d1e8ec2-5897-396e-aa7b-f579ad2fac9f",
186 "text": "Connected to Microsoft Graph (teamsgraph)!",
187 "textFormat": "plain"
188 }
189 ```
190- โœ… **Response**: `201 Created`
191
192๐Ÿ **Invoke Response**: `200` (body: null)
193
194---
195
196## ๐Ÿ‘ค "my ad user" Flow (token cached)
197
198### Step 8 โ€” User sends "my ad user" message
199
200๐Ÿ“ฅ **INCOMING** `POST http://localhost:3978/api/messages`
201- **Activity**:
202 - `type`: `message`
203 - `id`: `1776827541160`
204 - `text`: `"my ad user"`
205 - `textFormat`: `plain`
206 - `timestamp`: `2026-04-22T03:12:21.179708Z`
207 - `from.id`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
208 - `from.aadObjectId`: `03500558-e554-416c-90c3-a061cdcd012b`
209 - `recipient.id`: `28:e3cb1c84-14e3-419c-b39c-1c06097b55fd` *(Bot MRI)*
210 - `attachments[0]`: `{ contentType: "text/html", content: "<div><span style=\"font-size:inherit\">my ad user</span></div>" }`
211 - `MSCV`: `eTD3PgxXhEiK0mFFc7QunQ.1.1.1.485974193.1.1`
212- ๐Ÿ”€ Route: `message/(?i)^my ad user`
213
214### Step 9 โ€” Silent token check (token exists)
215
216๐Ÿ“ค **OUTGOING** `GET https://token.botframework.com/api/usertoken/GetToken`
217- **Query Parameters**:
218 - `userid`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
219 - `connectionName`: `teamsgraph`
220 - `channelId`: `msteams`
221- **Request Body**: `(null)`
222- **Auth**: ๐Ÿ”‘ MSAL from cache
223- โœ… **Response**: `200` โ€” cached user token returned
224
225### Step 10 โ€” Call Graph API with token
226
227๐Ÿ“ค **OUTGOING** `GET https://graph.microsoft.com/v1.0/me`
228- **Auth**: `Authorization: Bearer {user_token}`
229- โœ… **Response**: `200` โ€” `{ displayName: "Rido", mail: "rido@teamssdk.onmicrosoft.com", id: "03500558-e554-416c-90c3-a061cdcd012b" }`
230
231### Step 11 โ€” Send profile result
232
233๐Ÿ“ค **OUTGOING** `POST https://smba.trafficmanager.net/amer/.../v3/conversations/a%3A1xH4HncZ6ly...OIM3Z/activities/1776827541160`
234- **Auth**: ๐Ÿ”‘ MSAL from cache
235- **Request Body**:
236 ```json
237 {
238 "from": { "id": "28:e3cb1c84-14e3-419c-b39c-1c06097b55fd", "name": "my-bot-sso" },
239 "conversation": { "tenantId": "3f3d1cea-...", "conversationType": "personal", "id": "a:1xH4HncZ6ly...OIM3Z" },
240 "type": "message",
241 "channelId": "msteams",
242 "serviceUrl": "https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/",
243 "replyToId": "1776827541160",
244 "text": "Your Azure AD user :\n```json\n{\"displayName\":\"Rido\",\"givenName\":\"Rido\",\"jobTitle\":\"Not an architect\",\"mail\":\"rido@teamssdk.onmicrosoft.com\",...}\n```",
245 "textFormat": "plain"
246 }
247 ```
248- โœ… **Response**: `201 Created`
249
250---
251
252## ๐Ÿšช Logout Flow
253
254### Step 12 โ€” User sends "logout graph" message
255
256๐Ÿ“ฅ **INCOMING** `POST http://localhost:3978/api/messages`
257- **Activity**:
258 - `type`: `message`
259 - `id`: `1776827548949`
260 - `text`: `"logout graph"`
261 - `textFormat`: `plain`
262 - `timestamp`: `2026-04-22T03:12:28.9762671Z`
263 - `from.id`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
264 - `from.aadObjectId`: `03500558-e554-416c-90c3-a061cdcd012b`
265 - `recipient.id`: `28:e3cb1c84-14e3-419c-b39c-1c06097b55fd` *(Bot MRI)*
266 - `MSCV`: `ymRk2x/XZ0CFG0QGeNHrOg.1.1.1.486335532.1.1`
267- ๐Ÿ”€ Route: `message/(?i)^logout graph$`
268
269### Step 13 โ€” Sign out user
270
271๐Ÿ“ค **OUTGOING** `DELETE https://token.botframework.com/api/usertoken/SignOut`
272- **Query Parameters**:
273 - `userid`: `29:1cgsv1oFLAoTflZ-AxCZ_erWK6f4AqDSzZGpJOS7FuyfB8gn-g9bWmVM8usvvrv2e0atWV6wxZOQCn-xntjVrrQ` *(User MRI)*
274 - `connectionName`: `teamsgraph`
275 - `channelId`: `msteams`
276- **Request Body**: `(null)`
277- **Auth**: ๐Ÿ”‘ MSAL from cache
278- โœ… **Response**: `200` โ€” token revoked
279
280### Step 14 โ€” Send confirmation
281
282๐Ÿ“ค **OUTGOING** `POST https://smba.trafficmanager.net/amer/.../v3/conversations/a%3A1xH4HncZ6ly...OIM3Z/activities/1776827548949`
283- **Auth**: ๐Ÿ”‘ MSAL from cache
284- **Request Body**:
285 ```json
286 {
287 "from": { "id": "28:e3cb1c84-14e3-419c-b39c-1c06097b55fd", "name": "my-bot-sso" },
288 "conversation": { "tenantId": "3f3d1cea-...", "conversationType": "personal", "id": "a:1xH4HncZ6ly...OIM3Z" },
289 "type": "message",
290 "channelId": "msteams",
291 "serviceUrl": "https://smba.trafficmanager.net/amer/3f3d1cea-7a18-41af-872b-cfbbd5140984/",
292 "replyToId": "1776827548949",
293 "text": "Signed out from Graph.",
294 "textFormat": "plain"
295 }
296 ```
297- โœ… **Response**: `201 Created`
298
299---
300
301## ๐Ÿ“Š Request Summary Table
302
303| # | Direction | Method | Endpoint | Status | Purpose |
304|---|-----------|--------|----------|--------|---------|
305| 1 | ๐Ÿ“ฅ โฌ‡๏ธ IN | POST | `/api/messages` | โœ… 200 | ๐Ÿ’ฌ "login graph" message |
306| 2 | ๐Ÿ“ค โฌ†๏ธ OUT | GET | `token.botframework.com/api/usertoken/GetToken` | โŒ 404 | ๐Ÿ” Silent token check (miss) |
307| 3 | ๐Ÿ“ค โฌ†๏ธ OUT | GET | `token.botframework.com/api/botsignin/GetSignInResource` | โœ… 200 | ๐Ÿ”— Get sign-in resource (no tokenExchangeResource) |
308| 4 | ๐Ÿ“ค โฌ†๏ธ OUT | POST | `smba.trafficmanager.net/.../activities` | โœ… 200 | ๐Ÿƒ Send OAuthCard (popup only, no SSO) |
309| 5 | ๐Ÿ“ฅ โฌ‡๏ธ IN | POST | `/api/messages` | โœ… 200 | ๐Ÿ”„ signin/verifyState invoke (code=745254) |
310| 6 | ๐Ÿ“ค โฌ†๏ธ OUT | GET | `token.botframework.com/api/usertoken/GetToken` | โœ… 200 | ๐Ÿ” Verify state + get token (code=745254) |
311| 7 | ๐Ÿ“ค โฌ†๏ธ OUT | POST | `smba.trafficmanager.net/.../activities` | โœ… 201 | ๐ŸŽ‰ "Connected to Microsoft Graph!" |
312| 8 | ๐Ÿ“ฅ โฌ‡๏ธ IN | POST | `/api/messages` | โœ… 200 | ๐Ÿ’ฌ "my ad user" message |
313| 9 | ๐Ÿ“ค โฌ†๏ธ OUT | GET | `token.botframework.com/api/usertoken/GetToken` | โœ… 200 | ๐Ÿ” Silent token check (hit) |
314| 10 | ๐Ÿ“ค โฌ†๏ธ OUT | GET | `graph.microsoft.com/v1.0/me` | โœ… 200 | ๐Ÿ‘ค Graph API call |
315| 11 | ๐Ÿ“ค โฌ†๏ธ OUT | POST | `smba.trafficmanager.net/.../activities` | โœ… 201 | ๐Ÿ“„ Profile response |
316| 12 | ๐Ÿ“ฅ โฌ‡๏ธ IN | POST | `/api/messages` | โœ… 200 | ๐Ÿ’ฌ "logout graph" message |
317| 13 | ๐Ÿ“ค โฌ†๏ธ OUT | DELETE | `token.botframework.com/api/usertoken/SignOut` | โœ… 200 | ๐Ÿšช Revoke token |
318| 14 | ๐Ÿ“ค โฌ†๏ธ OUT | POST | `smba.trafficmanager.net/.../activities` | โœ… 201 | ๐Ÿ’ฌ "Signed out from Graph." |
319
320## ๐Ÿ†” User MRI Usage Across Requests
321
322| Request | Where User MRI appears | Format |
323|---------|----------------------|--------|
324| Step 1 (incoming message) | `activity.from.id` | `29:1cgsv1oFLAoTflZ-...` |
325| Step 2 (GetToken) | `?userid=` query param | URL-encoded: `29%3A1cgsv1oFLAoTflZ-...` |
326| Step 3 (GetSignInResource) | `state.Conversation.User.Id` (base64 JSON) | `29:1cgsv1oFLAoTflZ-...` |
327| Step 4 (Send OAuthCard) | `recipient.id` (reply to user) | `29:1cgsv1oFLAoTflZ-...` |
328| Step 5 (verifyState invoke) | `activity.from.id` | `29:1cgsv1oFLAoTflZ-...` |
329| Step 6 (GetToken + code) | `?userid=` query param | URL-encoded: `29%3A1cgsv1oFLAoTflZ-...` |
330| Step 9 (GetToken cached) | `?userid=` query param | URL-encoded: `29%3A1cgsv1oFLAoTflZ-...` |
331| Step 13 (SignOut) | `?userid=` query param | URL-encoded: `29%3A1cgsv1oFLAoTflZ-...` |
332
333> **Note**: The User MRI (`29:...`) is the Teams-specific identifier. It is used as `userid` in all Token Bot Service calls (GetToken, SignOut) and appears in `from.id` on incoming activities and `recipient.id` on outgoing replies. The AAD ObjectId (`03500558-...`) appears separately in `from.aadObjectId` and in the outgoing `recipient.aadObjectId`.
334
335---
336
337## ๐Ÿ”‘ vs SsoBot: Key Differences
338
339| Aspect | SsoBot (`sso` connection) | OAuthFlowBot (`teamsgraph` connection) |
340|--------|--------------------------|----------------------------------------|
341| SSO support | โœ… `tokenExchangeResource` present | โŒ `tokenExchangeResource` omitted |
342| Sign-in invoke | `signin/tokenExchange` (silent) | `signin/verifyState` (popup + code) |
343| Token acquisition | `POST /api/usertoken/exchange` with SSO JWT | `GET /api/usertoken/GetToken` with `code` param |
344| User interaction | None (fully silent) | Popup window + consent |
345| OAuthFlow API | Context API (`context.SignIn()`) | Instance API (`graphAuth.SignInAsync(context)`) |
346| verifyState value | N/A | `{ "state": "745254" }` |
347| tokenExchange value | `{ id, connectionName, token }` | N/A |
348
349## ๐Ÿ› Bug Fixed During This Run
350
351**Issue**: `OAuthCard` serialized `"tokenExchangeResource": null` explicitly in JSON. Teams rejected this with `BadRequest: {"error":{"code":"ServiceError","message":"Unknown"}}`.
352
353**Fix**: Added `[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]` to `TokenExchangeResource` and `TokenPostResource` properties in `OAuthCard.cs`. When null, these properties are now omitted from the JSON instead of being sent as explicit nulls.
354
355**File**: `src/Microsoft.Teams.Apps/Schema/OAuthCard.cs`
356