Commit 0684f6f
committed
Fix thread-safety race in CustomChainedCredential credential initialization
The ??= compound assignment is not atomic in C#. Under concurrent
GetToken / GetTokenAsync calls before the credential chain was
initialized (e.g. parallel tool calls on server startup in HTTP mode),
two threads could both observe _credential == null, construct separate
ChainedTokenCredential instances, and have one silently discarded. The
two chains may hold diverged MSAL token cache handles, causing
intermittent authentication failures.
Fix: replace the nullable field + ??= pattern with Lazy<TokenCredential>
using LazyThreadSafetyMode.ExecutionAndPublication, which provides
guaranteed single initialization under concurrent access with no
manual locking required.
Also adds GetToken_ConcurrentCalls_InitializesCredentialExactlyOnce
test to verify the Lazy<T>.IsValueCreated post-concurrent access.
Closes #3981 parent 6393ea8 commit 0684f6f
3 files changed
Lines changed: 61 additions & 10 deletions
File tree
- core
- Azure.Mcp.Core/tests/Azure.Mcp.Core.Tests/Services/Azure/Authentication
- Microsoft.Mcp.Core/src/Services/Azure/Authentication
- servers/Azure.Mcp.Server/changelog-entries
Lines changed: 46 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
456 | 456 | | |
457 | 457 | | |
458 | 458 | | |
459 | | - | |
460 | | - | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
461 | 467 | | |
462 | 468 | | |
463 | 469 | | |
| |||
469 | 475 | | |
470 | 476 | | |
471 | 477 | | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
472 | 516 | | |
473 | 517 | | |
474 | 518 | | |
| |||
Lines changed: 12 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
| 87 | + | |
88 | 88 | | |
89 | | - | |
90 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
91 | 97 | | |
92 | 98 | | |
93 | 99 | | |
| |||
102 | 108 | | |
103 | 109 | | |
104 | 110 | | |
105 | | - | |
106 | | - | |
| 111 | + | |
107 | 112 | | |
108 | 113 | | |
109 | 114 | | |
110 | 115 | | |
111 | | - | |
112 | | - | |
| 116 | + | |
113 | 117 | | |
114 | 118 | | |
115 | 119 | | |
| |||
266 | 270 | | |
267 | 271 | | |
268 | 272 | | |
269 | | - | |
| 273 | + | |
270 | 274 | | |
271 | 275 | | |
272 | 276 | | |
| |||
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
0 commit comments