@microsoft/agents-hosting 1.6.1 → 1.7.0-beta.5.g67b2005119

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +16 -0
  2. package/dist/package.json +3 -3
  3. package/dist/src/agent-client/agentClient.js +4 -3
  4. package/dist/src/agent-client/agentClient.js.map +1 -1
  5. package/dist/src/agent-client/agentResponseHandler.d.ts +25 -6
  6. package/dist/src/agent-client/agentResponseHandler.js +16 -55
  7. package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
  8. package/dist/src/agent-client/createAgentResponseHandler.d.ts +48 -0
  9. package/dist/src/agent-client/createAgentResponseHandler.js +92 -0
  10. package/dist/src/agent-client/createAgentResponseHandler.js.map +1 -0
  11. package/dist/src/agent-client/index.d.ts +1 -0
  12. package/dist/src/agent-client/index.js +1 -0
  13. package/dist/src/agent-client/index.js.map +1 -1
  14. package/dist/src/app/adaptiveCards/activityValueParsers.js +2 -1
  15. package/dist/src/app/adaptiveCards/activityValueParsers.js.map +1 -1
  16. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +13 -12
  17. package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
  18. package/dist/src/app/agentApplication.js +8 -8
  19. package/dist/src/app/agentApplication.js.map +1 -1
  20. package/dist/src/app/streaming/streamingResponse.d.ts +11 -0
  21. package/dist/src/app/streaming/streamingResponse.js +23 -2
  22. package/dist/src/app/streaming/streamingResponse.js.map +1 -1
  23. package/dist/src/app/turnState.d.ts +0 -1
  24. package/dist/src/app/turnState.js +15 -14
  25. package/dist/src/app/turnState.js.map +1 -1
  26. package/dist/src/app/turnStateProperty.js +4 -2
  27. package/dist/src/app/turnStateProperty.js.map +1 -1
  28. package/dist/src/auth/MemoryCache.d.ts +2 -1
  29. package/dist/src/auth/MemoryCache.js +7 -1
  30. package/dist/src/auth/MemoryCache.js.map +1 -1
  31. package/dist/src/auth/authConfiguration.d.ts +1 -1
  32. package/dist/src/auth/authConfiguration.js +41 -4
  33. package/dist/src/auth/authConfiguration.js.map +1 -1
  34. package/dist/src/auth/authConstants.d.ts +7 -7
  35. package/dist/src/auth/authConstants.js.map +1 -1
  36. package/dist/src/auth/connectionManager.d.ts +92 -0
  37. package/dist/src/auth/{msalConnectionManager.js → connectionManager.js} +50 -48
  38. package/dist/src/auth/connectionManager.js.map +1 -0
  39. package/dist/src/auth/index.d.ts +5 -3
  40. package/dist/src/auth/index.js +5 -3
  41. package/dist/src/auth/index.js.map +1 -1
  42. package/dist/src/auth/jwt-middleware.d.ts +8 -2
  43. package/dist/src/auth/jwt-middleware.js +116 -7
  44. package/dist/src/auth/jwt-middleware.js.map +1 -1
  45. package/dist/src/auth/msal/msalConnectionManager.d.ts +17 -0
  46. package/dist/src/auth/msal/msalConnectionManager.js +50 -0
  47. package/dist/src/auth/msal/msalConnectionManager.js.map +1 -0
  48. package/dist/src/auth/msal/msalConnectionSettings.d.ts +68 -0
  49. package/dist/src/auth/msal/msalConnectionSettings.js +7 -0
  50. package/dist/src/auth/msal/msalConnectionSettings.js.map +1 -0
  51. package/dist/src/auth/{msalTokenCredential.d.ts → msal/msalTokenCredential.d.ts} +1 -1
  52. package/dist/src/auth/{msalTokenCredential.js → msal/msalTokenCredential.js} +2 -2
  53. package/dist/src/auth/msal/msalTokenCredential.js.map +1 -0
  54. package/dist/src/auth/{msalTokenProvider.d.ts → msal/msalTokenProvider.d.ts} +23 -3
  55. package/dist/src/auth/{msalTokenProvider.js → msal/msalTokenProvider.js} +280 -176
  56. package/dist/src/auth/msal/msalTokenProvider.js.map +1 -0
  57. package/dist/src/auth/settings.d.ts +142 -133
  58. package/dist/src/auth/settings.js +49 -5
  59. package/dist/src/auth/settings.js.map +1 -1
  60. package/dist/src/auth/sidecar/sidecarAuthProvider.d.ts +74 -0
  61. package/dist/src/auth/sidecar/sidecarAuthProvider.js +181 -0
  62. package/dist/src/auth/sidecar/sidecarAuthProvider.js.map +1 -0
  63. package/dist/src/auth/sidecar/sidecarConnectionSettings.d.ts +65 -0
  64. package/dist/src/auth/sidecar/sidecarConnectionSettings.js +7 -0
  65. package/dist/src/auth/sidecar/sidecarConnectionSettings.js.map +1 -0
  66. package/dist/src/auth/sidecar/sidecarHttpClient.d.ts +95 -0
  67. package/dist/src/auth/sidecar/sidecarHttpClient.js +406 -0
  68. package/dist/src/auth/sidecar/sidecarHttpClient.js.map +1 -0
  69. package/dist/src/auth/sidecar/sidecarModels.d.ts +110 -0
  70. package/dist/src/auth/sidecar/sidecarModels.js +48 -0
  71. package/dist/src/auth/sidecar/sidecarModels.js.map +1 -0
  72. package/dist/src/auth/sidecar/sidecarTokenExpiry.d.ts +13 -0
  73. package/dist/src/auth/sidecar/sidecarTokenExpiry.js +39 -0
  74. package/dist/src/auth/sidecar/sidecarTokenExpiry.js.map +1 -0
  75. package/dist/src/baseAdapter.js +3 -1
  76. package/dist/src/baseAdapter.js.map +1 -1
  77. package/dist/src/cloudAdapter.d.ts +2 -2
  78. package/dist/src/cloudAdapter.js +11 -11
  79. package/dist/src/cloudAdapter.js.map +1 -1
  80. package/dist/src/createCloudAdapter.d.ts +40 -0
  81. package/dist/src/createCloudAdapter.js +44 -0
  82. package/dist/src/createCloudAdapter.js.map +1 -0
  83. package/dist/src/errorHelper.js +302 -79
  84. package/dist/src/errorHelper.js.map +1 -1
  85. package/dist/src/headerPropagation.js +3 -1
  86. package/dist/src/headerPropagation.js.map +1 -1
  87. package/dist/src/index.d.ts +3 -1
  88. package/dist/src/index.js +4 -1
  89. package/dist/src/index.js.map +1 -1
  90. package/dist/src/interfaces/index.d.ts +5 -0
  91. package/dist/src/interfaces/index.js +22 -0
  92. package/dist/src/interfaces/index.js.map +1 -0
  93. package/dist/src/interfaces/webResponse.d.ts +41 -0
  94. package/dist/src/interfaces/webResponse.js +7 -0
  95. package/dist/src/interfaces/webResponse.js.map +1 -0
  96. package/dist/src/middlewareSet.d.ts +0 -1
  97. package/dist/src/middlewareSet.js +4 -1
  98. package/dist/src/middlewareSet.js.map +1 -1
  99. package/dist/src/oauth/userTokenClient.d.ts +12 -0
  100. package/dist/src/oauth/userTokenClient.js +30 -9
  101. package/dist/src/oauth/userTokenClient.js.map +1 -1
  102. package/dist/src/state/conversationState.js +4 -2
  103. package/dist/src/state/conversationState.js.map +1 -1
  104. package/dist/src/state/userState.js +4 -2
  105. package/dist/src/state/userState.js.map +1 -1
  106. package/dist/src/storage/memoryStorage.js +5 -3
  107. package/dist/src/storage/memoryStorage.js.map +1 -1
  108. package/dist/src/transcript/consoleTranscriptLogger.js +3 -1
  109. package/dist/src/transcript/consoleTranscriptLogger.js.map +1 -1
  110. package/dist/src/transcript/fileTranscriptLogger.js +5 -4
  111. package/dist/src/transcript/fileTranscriptLogger.js.map +1 -1
  112. package/dist/src/transcript/transcriptLoggerMiddleware.js +2 -1
  113. package/dist/src/transcript/transcriptLoggerMiddleware.js.map +1 -1
  114. package/dist/src/turnContext.js +2 -1
  115. package/dist/src/turnContext.js.map +1 -1
  116. package/package.json +3 -3
  117. package/src/agent-client/agentClient.ts +5 -4
  118. package/src/agent-client/agentResponseHandler.ts +43 -67
  119. package/src/agent-client/createAgentResponseHandler.ts +133 -0
  120. package/src/agent-client/index.ts +1 -0
  121. package/src/app/adaptiveCards/activityValueParsers.ts +3 -2
  122. package/src/app/adaptiveCards/adaptiveCardsActions.ts +5 -5
  123. package/src/app/agentApplication.ts +8 -16
  124. package/src/app/streaming/streamingResponse.ts +26 -3
  125. package/src/app/turnState.ts +15 -14
  126. package/src/app/turnStateProperty.ts +4 -2
  127. package/src/auth/MemoryCache.ts +7 -1
  128. package/src/auth/authConfiguration.ts +41 -6
  129. package/src/auth/authConstants.ts +7 -7
  130. package/src/auth/{msalConnectionManager.ts → connectionManager.ts} +65 -61
  131. package/src/auth/index.ts +5 -3
  132. package/src/auth/jwt-middleware.ts +118 -9
  133. package/src/auth/msal/msalConnectionManager.ts +55 -0
  134. package/src/auth/msal/msalConnectionSettings.ts +79 -0
  135. package/src/auth/{msalTokenCredential.ts → msal/msalTokenCredential.ts} +2 -1
  136. package/src/auth/{msalTokenProvider.ts → msal/msalTokenProvider.ts} +353 -172
  137. package/src/auth/settings.ts +131 -76
  138. package/src/auth/sidecar/sidecarAuthProvider.ts +234 -0
  139. package/src/auth/sidecar/sidecarConnectionSettings.ts +72 -0
  140. package/src/auth/sidecar/sidecarHttpClient.ts +443 -0
  141. package/src/auth/sidecar/sidecarModels.ts +153 -0
  142. package/src/auth/sidecar/sidecarTokenExpiry.ts +35 -0
  143. package/src/baseAdapter.ts +3 -2
  144. package/src/cloudAdapter.ts +13 -13
  145. package/src/createCloudAdapter.ts +56 -0
  146. package/src/errorHelper.ts +354 -89
  147. package/src/headerPropagation.ts +4 -1
  148. package/src/index.ts +3 -1
  149. package/src/interfaces/index.ts +6 -0
  150. package/src/interfaces/webResponse.ts +44 -0
  151. package/src/middlewareSet.ts +3 -1
  152. package/src/oauth/userTokenClient.ts +46 -11
  153. package/src/state/conversationState.ts +4 -3
  154. package/src/state/userState.ts +4 -3
  155. package/src/storage/memoryStorage.ts +5 -3
  156. package/src/transcript/consoleTranscriptLogger.ts +3 -2
  157. package/src/transcript/fileTranscriptLogger.ts +6 -5
  158. package/src/transcript/transcriptLoggerMiddleware.ts +3 -2
  159. package/src/turnContext.ts +3 -2
  160. package/dist/src/auth/msalConnectionManager.d.ts +0 -64
  161. package/dist/src/auth/msalConnectionManager.js.map +0 -1
  162. package/dist/src/auth/msalTokenCredential.js.map +0 -1
  163. package/dist/src/auth/msalTokenProvider.js.map +0 -1
@@ -3,19 +3,18 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ConfidentialClientApplication, LogLevel, ManagedIdentityApplication, NodeSystemOptions } from '@azure/msal-node'
7
- import { AuthConfiguration, AuthType, resolveAuthority as resolveAuthorityUtil } from './authConfiguration'
8
- import { AuthProvider } from './authProvider'
6
+ import { AuthenticationResult, ConfidentialClientApplication, LogLevel, ManagedIdentityApplication, NodeSystemOptions } from '@azure/msal-node'
7
+ import { AuthConfiguration, AuthType, resolveAuthority, resolveAuthority as resolveAuthorityUtil, resolveAuthType } from '../authConfiguration'
8
+ import { AuthProvider } from '../authProvider'
9
9
  import { debug, trace } from '@microsoft/agents-telemetry'
10
10
  import { randomUUID } from 'crypto'
11
- import { MemoryCache } from './MemoryCache'
12
- import jwt from 'jsonwebtoken'
13
-
11
+ import { MemoryCache } from '../MemoryCache'
12
+ import jwt, { JwtPayload } from 'jsonwebtoken'
14
13
  import fs from 'fs'
15
14
  import crypto from 'crypto'
16
- import { AuthenticationTraceDefinitions } from '../observability'
15
+ import { AuthenticationTraceDefinitions } from '../../observability'
17
16
  import { ExceptionHelper } from '@microsoft/agents-activity'
18
- import { Errors } from '../errorHelper'
17
+ import { Errors } from '../../errorHelper'
19
18
 
20
19
  const audience = 'api://AzureADTokenExchange'
21
20
  const logger = debug('agents:msal')
@@ -33,14 +32,237 @@ function createTokenRequestTimeoutError (timeoutMs: number): Error {
33
32
  * Provides tokens using MSAL.
34
33
  */
35
34
  export class MsalTokenProvider implements AuthProvider {
36
- private readonly _agenticTokenCache: MemoryCache<string>
35
+ private static readonly _accessTokenCache = new MemoryCache<string>()
36
+ private static readonly _agenticTokenCache = new MemoryCache<string>()
37
+ private static readonly _confidentialClients = new Map<string, ConfidentialClientApplication>()
38
+ private static readonly _maxConfidentialClients = 100
37
39
  public readonly connectionSettings?: AuthConfiguration
38
40
 
39
41
  constructor (connectionSettings?: AuthConfiguration) {
40
- this._agenticTokenCache = new MemoryCache<string>()
41
42
  this.connectionSettings = connectionSettings
42
43
  }
43
44
 
45
+ /**
46
+ * Clears process-wide auth caches.
47
+ */
48
+ public static clearSharedCaches (): void {
49
+ MsalTokenProvider._accessTokenCache.clear()
50
+ MsalTokenProvider._agenticTokenCache.clear()
51
+ MsalTokenProvider._confidentialClients.clear()
52
+ }
53
+
54
+ private static cacheKey (...parts: Array<string | number | boolean | undefined | null>): string {
55
+ return JSON.stringify(parts.map(part => part ?? ''))
56
+ }
57
+
58
+ private static digest (value: string | Buffer | undefined): string {
59
+ return value ? crypto.createHash('sha256').update(value).digest('base64url') : ''
60
+ }
61
+
62
+ private getOrCreateConfidentialClient (
63
+ cacheKey: string,
64
+ createClient: () => ConfidentialClientApplication
65
+ ): ConfidentialClientApplication {
66
+ const existing = MsalTokenProvider._confidentialClients.get(cacheKey)
67
+ if (existing) {
68
+ MsalTokenProvider._confidentialClients.delete(cacheKey)
69
+ MsalTokenProvider._confidentialClients.set(cacheKey, existing)
70
+ return existing
71
+ }
72
+
73
+ const created = createClient()
74
+ MsalTokenProvider._confidentialClients.set(cacheKey, created)
75
+ while (MsalTokenProvider._confidentialClients.size > MsalTokenProvider._maxConfidentialClients) {
76
+ const oldestKey = MsalTokenProvider._confidentialClients.keys().next().value
77
+ if (oldestKey === undefined) {
78
+ break
79
+ }
80
+ MsalTokenProvider._confidentialClients.delete(oldestKey)
81
+ }
82
+ return created
83
+ }
84
+
85
+ private getFileCacheIdentity (path?: string): string {
86
+ if (!path) {
87
+ return ''
88
+ }
89
+
90
+ try {
91
+ const stat = fs.statSync(path)
92
+ return `${path}:${stat.size}:${stat.mtimeMs}`
93
+ } catch {
94
+ return path
95
+ }
96
+ }
97
+
98
+ private getAccessTokenCacheKey (authConfig: AuthConfiguration, scope: string): string {
99
+ const authType = resolveAuthType(authConfig)
100
+ let authority = resolveAuthorityUtil(authConfig.authorityEndpoint ?? authConfig.authority, authConfig.tenantId)
101
+ let credentialIdentity = ''
102
+
103
+ switch (authType) {
104
+ case AuthType.ClientSecret:
105
+ credentialIdentity = MsalTokenProvider.digest(authConfig.clientSecret)
106
+ break
107
+ case AuthType.Certificate:
108
+ case AuthType.CertificateSubjectName:
109
+ credentialIdentity = MsalTokenProvider.cacheKey(
110
+ this.getFileCacheIdentity(authConfig.certPemFile),
111
+ this.getFileCacheIdentity(authConfig.certKeyFile),
112
+ authConfig.sendX5C
113
+ )
114
+ break
115
+ case AuthType.WorkloadIdentity:
116
+ authority = `https://login.microsoftonline.com/${authConfig.tenantId}`
117
+ credentialIdentity = this.getFileCacheIdentity(authConfig.federatedTokenFile ?? authConfig.WIDAssertionFile)
118
+ break
119
+ case AuthType.FederatedCredentials:
120
+ credentialIdentity = authConfig.federatedClientId ?? authConfig.FICClientId ?? ''
121
+ break
122
+ case AuthType.UserManagedIdentity:
123
+ authority = 'managed-identity'
124
+ credentialIdentity = authConfig.clientId ?? ''
125
+ break
126
+ case AuthType.SystemManagedIdentity:
127
+ authority = 'managed-identity'
128
+ credentialIdentity = 'system'
129
+ break
130
+ default:
131
+ credentialIdentity = 'unknown'
132
+ }
133
+
134
+ return MsalTokenProvider.cacheKey(
135
+ 'access-token',
136
+ authType,
137
+ authority,
138
+ authConfig.clientId,
139
+ scope,
140
+ authConfig.azureRegion,
141
+ credentialIdentity
142
+ )
143
+ }
144
+
145
+ private cacheAccessToken (cacheKey: string, token: string, expiresOn?: Date | null): void {
146
+ const ttlSeconds = this.getTokenCacheTtlSeconds(token, expiresOn)
147
+ if (ttlSeconds > 0) {
148
+ MsalTokenProvider._accessTokenCache.set(cacheKey, token, ttlSeconds)
149
+ }
150
+ }
151
+
152
+ private cacheAgenticToken (cacheKey: string, token: string, ttlSeconds: number): void {
153
+ const safeTtlSeconds = Math.floor(ttlSeconds) - 300
154
+ if (safeTtlSeconds > 0) {
155
+ MsalTokenProvider._agenticTokenCache.set(cacheKey, token, safeTtlSeconds)
156
+ }
157
+ }
158
+
159
+ private cacheAgenticAuthenticationResult (cacheKey: string, token: AuthenticationResult): void {
160
+ const ttlSeconds = this.getTokenCacheTtlSeconds(token.accessToken, token.expiresOn)
161
+ if (ttlSeconds > 0) {
162
+ MsalTokenProvider._agenticTokenCache.set(cacheKey, token.accessToken, ttlSeconds)
163
+ }
164
+ }
165
+
166
+ private getAgenticTokenCacheKey (
167
+ tenantId: string,
168
+ clientId: string,
169
+ scopes: string[],
170
+ tokenBodyParameters: { [key: string]: any }
171
+ ): string {
172
+ const bodyKey = Object.keys(tokenBodyParameters)
173
+ .sort()
174
+ .filter(key => key !== 'user_federated_identity_credential')
175
+ .map(key => `${key}=${MsalTokenProvider.digest(String(tokenBodyParameters[key]))}`)
176
+ .join('&')
177
+
178
+ return MsalTokenProvider.cacheKey(
179
+ 'agentic-token',
180
+ this.resolveAuthority(tenantId),
181
+ clientId,
182
+ scopes.join(' '),
183
+ bodyKey
184
+ )
185
+ }
186
+
187
+ private getTokenCacheTtlSeconds (token: string, expiresOn?: Date | null): number {
188
+ const expiresAtMs = expiresOn?.getTime() ?? this.getJwtExpiresAtMs(token)
189
+ if (!expiresAtMs) {
190
+ return 0
191
+ }
192
+
193
+ return Math.floor((expiresAtMs - Date.now()) / 1000) - 300
194
+ }
195
+
196
+ private getJwtExpiresAtMs (token: string): number | undefined {
197
+ const payload = jwt.decode(token) as JwtPayload | string | null
198
+ if (!payload || typeof payload === 'string' || typeof payload.exp !== 'number') {
199
+ return undefined
200
+ }
201
+
202
+ return payload.exp * 1000
203
+ }
204
+
205
+ private getClientSecretClient (authConfig: AuthConfiguration): ConfidentialClientApplication {
206
+ const cacheKey = MsalTokenProvider.cacheKey(
207
+ 'confidential-client',
208
+ AuthType.ClientSecret,
209
+ authConfig.clientId,
210
+ resolveAuthorityUtil(authConfig.authorityEndpoint ?? authConfig.authority, authConfig.tenantId),
211
+ MsalTokenProvider.digest(authConfig.clientSecret)
212
+ )
213
+
214
+ return this.getOrCreateConfidentialClient(cacheKey, () => new ConfidentialClientApplication({
215
+ auth: {
216
+ clientId: authConfig.clientId as string,
217
+ authority: resolveAuthorityUtil(authConfig.authorityEndpoint ?? authConfig.authority, authConfig.tenantId),
218
+ clientSecret: authConfig.clientSecret
219
+ },
220
+ system: this.sysOptions
221
+ }))
222
+ }
223
+
224
+ private getCertificateClient (authConfig: AuthConfiguration): ConfidentialClientApplication {
225
+ const cacheKey = MsalTokenProvider.cacheKey(
226
+ 'confidential-client',
227
+ authConfig.authType ?? AuthType.Certificate,
228
+ authConfig.clientId,
229
+ resolveAuthorityUtil(authConfig.authorityEndpoint ?? authConfig.authority, authConfig.tenantId),
230
+ this.getFileCacheIdentity(authConfig.certPemFile),
231
+ this.getFileCacheIdentity(authConfig.certKeyFile),
232
+ authConfig.sendX5C
233
+ )
234
+
235
+ return this.getOrCreateConfidentialClient(cacheKey, () => {
236
+ const privateKeySource = fs.readFileSync(authConfig.certKeyFile as string)
237
+
238
+ const privateKeyObject = crypto.createPrivateKey({
239
+ key: privateKeySource,
240
+ format: 'pem'
241
+ })
242
+
243
+ const privateKey = privateKeyObject.export({
244
+ format: 'pem',
245
+ type: 'pkcs8'
246
+ })
247
+
248
+ const pemFile = fs.readFileSync(authConfig.certPemFile as string)
249
+ const pubKeyObject = new crypto.X509Certificate(pemFile)
250
+
251
+ return new ConfidentialClientApplication({
252
+ auth: {
253
+ clientId: authConfig.clientId || '',
254
+ authority: resolveAuthority(authConfig.authorityEndpoint ?? authConfig.authority, authConfig.tenantId),
255
+ clientCertificate: {
256
+ privateKey: privateKey as string,
257
+ thumbprint: pubKeyObject.fingerprint.replaceAll(':', ''),
258
+ x5c: pemFile.toString()
259
+ }
260
+ },
261
+ system: this.sysOptions
262
+ })
263
+ })
264
+ }
265
+
44
266
  /**
45
267
  * Gets an access token using the auth configuration from the MsalTokenProvider instance and the provided scope.
46
268
  * @param scope The scope for the token.
@@ -62,7 +284,7 @@ export class MsalTokenProvider implements AuthProvider {
62
284
  if (typeof authConfigOrScope === 'string') {
63
285
  // Called as getAccessToken(scope)
64
286
  if (!this.connectionSettings) {
65
- throw new Error('Connection settings must be provided to constructor when calling getAccessToken(scope)')
287
+ throw ExceptionHelper.generateException(Error, Errors.ConnectionSettingsRequiredForGetAccessTokenScope)
66
288
  }
67
289
  authConfig = this.connectionSettings
68
290
  actualScope = authConfigOrScope
@@ -79,80 +301,64 @@ export class MsalTokenProvider implements AuthProvider {
79
301
  return ''
80
302
  }
81
303
 
304
+ const accessTokenCacheKey = this.getAccessTokenCacheKey(authConfig, actualScope)
305
+ const cachedAccessToken = MsalTokenProvider._accessTokenCache.get(accessTokenCacheKey)
306
+ if (cachedAccessToken) {
307
+ logger.debug('getAccessToken cache hit clientId=%s scope=%s', authConfig.clientId, actualScope)
308
+ return cachedAccessToken
309
+ }
310
+
82
311
  let token
83
- if (authConfig.authType) {
84
- record({ method: authConfig.authType })
85
- logger.debug(`getAccessToken via ${authConfig.authType} clientId=${authConfig.clientId} scope=${actualScope}`)
86
- switch (authConfig.authType) {
87
- case AuthType.WorkloadIdentity: {
88
- const tokenFilePath = authConfig.federatedTokenFile ?? authConfig.WIDAssertionFile
89
- if (!tokenFilePath) {
90
- throw ExceptionHelper.generateException(Error, Errors.WorkloadIdentityTokenFileRequired)
91
- }
92
- token = await this.acquireAccessTokenViaWID(authConfig, actualScope)
93
- break
312
+ const authType = resolveAuthType(authConfig)
313
+ record({ method: authType })
314
+ logger.debug('getAccessToken via method=%s clientId=%s scope=%s', authType, authConfig.clientId, actualScope)
315
+
316
+ switch (authType) {
317
+ case AuthType.WorkloadIdentity: {
318
+ const tokenFilePath = authConfig.federatedTokenFile ?? authConfig.WIDAssertionFile
319
+ if (!tokenFilePath) {
320
+ throw ExceptionHelper.generateException(Error, Errors.WorkloadIdentityTokenFileRequired)
94
321
  }
95
- case AuthType.FederatedCredentials:
96
- if (!authConfig.federatedClientId && !authConfig.FICClientId) {
97
- throw ExceptionHelper.generateException(Error, Errors.FICClientIdRequired)
98
- }
99
- token = await this.acquireAccessTokenViaFIC(authConfig, actualScope)
100
- break
101
- case AuthType.ClientSecret:
102
- if (!authConfig.clientSecret) {
103
- throw ExceptionHelper.generateException(Error, Errors.ClientSecretRequired)
104
- }
105
- token = await this.acquireAccessTokenViaSecret(authConfig, actualScope)
106
- break
107
- case AuthType.Certificate:
108
- case AuthType.CertificateSubjectName:
109
- if (!authConfig.certPemFile || !authConfig.certKeyFile) {
110
- throw ExceptionHelper.generateException(Error, Errors.CertificateFilesRequired)
111
- }
112
- token = await this.acquireTokenWithCertificate(authConfig, actualScope)
113
- break
114
- case AuthType.UserManagedIdentity:
115
- if (!authConfig.clientId) {
116
- throw ExceptionHelper.generateException(Error, Errors.ClientIdRequiredForUserManagedIdentity)
117
- }
118
- token = await this.acquireTokenWithUserAssignedIdentity(authConfig, actualScope)
119
- break
120
- case AuthType.SystemManagedIdentity:
121
- token = await this.acquireTokenWithSystemAssignedIdentity(authConfig, actualScope)
122
- break
123
- default:
124
- throw ExceptionHelper.generateException(Error, Errors.UnsupportedAuthType, undefined, { authType: authConfig.authType })
322
+ token = await this.acquireAccessTokenViaWID(authConfig, actualScope)
323
+ break
125
324
  }
126
- } else if (authConfig.WIDAssertionFile !== undefined) {
127
- record({ method: AuthType.WorkloadIdentity })
128
- logger.debug('getAccessToken via method=%s clientId=%s scope=%s', AuthType.WorkloadIdentity, authConfig.clientId, actualScope)
129
- token = await this.acquireAccessTokenViaWID(authConfig, actualScope)
130
- } else if (authConfig.federatedClientId !== undefined || authConfig.FICClientId !== undefined) {
131
- record({ method: AuthType.FederatedCredentials })
132
- logger.debug('getAccessToken via method=%s clientId=%s scope=%s', AuthType.FederatedCredentials, authConfig.clientId, actualScope)
133
- token = await this.acquireAccessTokenViaFIC(authConfig, actualScope)
134
- } else if (authConfig.clientSecret !== undefined) {
135
- record({ method: AuthType.ClientSecret })
136
- logger.debug('getAccessToken via method=%s clientId=%s scope=%s', AuthType.ClientSecret, authConfig.clientId, actualScope)
137
- token = await this.acquireAccessTokenViaSecret(authConfig, actualScope)
138
- } else if (authConfig.certPemFile !== undefined &&
139
- authConfig.certKeyFile !== undefined) {
140
- record({ method: AuthType.Certificate })
141
- logger.debug('getAccessToken via method=%s clientId=%s scope=%s', AuthType.Certificate, authConfig.clientId, actualScope)
142
- token = await this.acquireTokenWithCertificate(authConfig, actualScope)
143
- } else if (authConfig.clientSecret === undefined &&
144
- authConfig.certPemFile === undefined &&
145
- authConfig.certKeyFile === undefined) {
146
- record({ method: AuthType.UserManagedIdentity })
147
- logger.debug('getAccessToken via method=%s clientId=%s scope=%s', AuthType.UserManagedIdentity, authConfig.clientId, actualScope)
148
- token = await this.acquireTokenWithUserAssignedIdentity(authConfig, actualScope)
149
- } else {
150
- throw ExceptionHelper.generateException(Error, Errors.InvalidAuthConfig)
325
+ case AuthType.FederatedCredentials:
326
+ if (!authConfig.federatedClientId && !authConfig.FICClientId) {
327
+ throw ExceptionHelper.generateException(Error, Errors.FICClientIdRequired)
328
+ }
329
+ token = await this.acquireAccessTokenViaFIC(authConfig, actualScope)
330
+ break
331
+ case AuthType.ClientSecret:
332
+ if (!authConfig.clientSecret) {
333
+ throw ExceptionHelper.generateException(Error, Errors.ClientSecretRequired)
334
+ }
335
+ token = await this.acquireAccessTokenViaSecret(authConfig, actualScope)
336
+ break
337
+ case AuthType.Certificate:
338
+ case AuthType.CertificateSubjectName:
339
+ if (!authConfig.certPemFile || !authConfig.certKeyFile) {
340
+ throw ExceptionHelper.generateException(Error, Errors.CertificateFilesRequired)
341
+ }
342
+ token = await this.acquireTokenWithCertificate(authConfig, actualScope)
343
+ break
344
+ case AuthType.UserManagedIdentity:
345
+ if (!authConfig.clientId) {
346
+ throw ExceptionHelper.generateException(Error, Errors.ClientIdRequiredForUserManagedIdentity)
347
+ }
348
+ token = await this.acquireTokenWithUserAssignedIdentity(authConfig, actualScope)
349
+ break
350
+ case AuthType.SystemManagedIdentity:
351
+ token = await this.acquireTokenWithSystemAssignedIdentity(authConfig, actualScope)
352
+ break
353
+ default:
354
+ throw ExceptionHelper.generateException(Error, Errors.UnsupportedAuthType, undefined, { authType })
151
355
  }
356
+
152
357
  if (token === undefined) {
153
358
  throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireToken)
154
359
  }
155
360
 
361
+ this.cacheAccessToken(accessTokenCacheKey, token)
156
362
  return token
157
363
  })
158
364
  }
@@ -172,7 +378,7 @@ export class MsalTokenProvider implements AuthProvider {
172
378
  if (Array.isArray(authConfigOrScopes)) {
173
379
  // Called as acquireTokenOnBehalfOf(scopes, oboAssertion)
174
380
  if (!this.connectionSettings) {
175
- throw new Error('Connection settings must be provided to constructor when calling acquireTokenOnBehalfOf(scopes, oboAssertion)')
381
+ throw ExceptionHelper.generateException(Error, Errors.ConnectionSettingsRequiredForAcquireTokenOnBehalfOf)
176
382
  }
177
383
  authConfig = this.connectionSettings
178
384
  actualScopes = authConfigOrScopes
@@ -187,20 +393,13 @@ export class MsalTokenProvider implements AuthProvider {
187
393
  record({ scopes: actualScopes })
188
394
  logger.debug('acquireTokenOnBehalfOf clientId=%s scopes=%o', authConfig.clientId, actualScopes)
189
395
 
190
- const cca = new ConfidentialClientApplication({
191
- auth: {
192
- clientId: authConfig.clientId as string,
193
- authority: `${authConfig.authorityEndpoint ?? authConfig.authority}/${authConfig.tenantId || 'botframework.com'}`,
194
- clientSecret: authConfig.clientSecret
195
- },
196
- system: this.sysOptions
197
- })
396
+ const cca = this.getClientSecretClient(authConfig)
198
397
  const token = await cca.acquireTokenOnBehalfOf({
199
398
  oboAssertion: actualOboAssertion,
200
399
  scopes: actualScopes
201
400
  })
202
401
  if (!token?.accessToken) {
203
- throw new Error('Failed to acquire token on behalf of user')
402
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireTokenOnBehalfOf)
204
403
  }
205
404
 
206
405
  return token.accessToken
@@ -213,8 +412,21 @@ export class MsalTokenProvider implements AuthProvider {
213
412
  record({ agenticInstanceId: agentAppInstanceId })
214
413
 
215
414
  if (!this.connectionSettings) {
216
- throw new Error('Connection settings must be provided when calling getAgenticInstanceToken')
415
+ throw ExceptionHelper.generateException(Error, Errors.ConnectionSettingsRequiredForGetAgenticInstanceToken)
217
416
  }
417
+
418
+ const instanceTokenCacheKey = MsalTokenProvider.cacheKey(
419
+ 'agentic-instance-token',
420
+ this.resolveAuthority(tenantId),
421
+ agentAppInstanceId,
422
+ this.connectionSettings.clientId,
423
+ this.connectionSettings.azureRegion
424
+ )
425
+ const cachedInstanceToken = MsalTokenProvider._agenticTokenCache.get(instanceTokenCacheKey)
426
+ if (cachedInstanceToken) {
427
+ return cachedInstanceToken
428
+ }
429
+
218
430
  const appToken = await this.getAgenticApplicationToken(tenantId, agentAppInstanceId)
219
431
  const cca = new ConfidentialClientApplication({
220
432
  auth: {
@@ -232,9 +444,10 @@ export class MsalTokenProvider implements AuthProvider {
232
444
  })
233
445
 
234
446
  if (!token?.accessToken) {
235
- throw new Error(`Failed to acquire instance token for agent instance: ${agentAppInstanceId}`)
447
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireInstanceTokenForAgentInstance, undefined, { agentAppInstanceId })
236
448
  }
237
449
 
450
+ this.cacheAgenticAuthenticationResult(instanceTokenCacheKey, token)
238
451
  return token.accessToken
239
452
  })
240
453
  }
@@ -281,14 +494,14 @@ export class MsalTokenProvider implements AuthProvider {
281
494
  */
282
495
  private async acquireTokenForAgenticScenarios (tenantId: string, clientId: string, clientAssertion: string | undefined, scopes: string[], tokenBodyParameters: { [key: string]: any }): Promise<string | null> {
283
496
  if (!this.connectionSettings) {
284
- throw new Error('Connection settings must be provided when calling getAgenticInstanceToken')
497
+ throw ExceptionHelper.generateException(Error, Errors.ConnectionSettingsRequiredForGetAgenticInstanceToken)
285
498
  }
286
499
 
287
500
  logger.debug('acquireTokenForAgenticScenarios clientId=%s tenantId=%s scopes=%o grant_type=%s', clientId, tenantId, scopes, tokenBodyParameters.grant_type)
288
501
  // Check cache first
289
- const cacheKey = `${clientId}/${Object.keys(tokenBodyParameters).map(key => key !== 'user_federated_identity_credential' ? `${key}=${tokenBodyParameters[key]}` : '').join('&')}/${scopes.join(';')}`
290
- if (this._agenticTokenCache.get(cacheKey)) {
291
- return this._agenticTokenCache.get(cacheKey) as string
502
+ const cacheKey = this.getAgenticTokenCacheKey(tenantId, clientId, scopes, tokenBodyParameters)
503
+ if (MsalTokenProvider._agenticTokenCache.get(cacheKey)) {
504
+ return MsalTokenProvider._agenticTokenCache.get(cacheKey) as string
292
505
  }
293
506
 
294
507
  const url = `${this.resolveAuthority(tenantId)}/oauth2/v2.0/token`
@@ -344,7 +557,7 @@ export class MsalTokenProvider implements AuthProvider {
344
557
  })
345
558
 
346
559
  // capture token, expire local cache 5 minutes early
347
- this._agenticTokenCache.set(cacheKey, token.access_token, token.expires_in - 300)
560
+ this.cacheAgenticToken(cacheKey, token.access_token, token.expires_in)
348
561
  return token.access_token
349
562
  }
350
563
 
@@ -353,17 +566,26 @@ export class MsalTokenProvider implements AuthProvider {
353
566
  logger.debug('getAgenticUserToken tenantId=%s agentAppInstanceId=%s scopes=%o', tenantId, agentAppInstanceId, scopes)
354
567
  record({ agenticInstanceId: agentAppInstanceId, agenticUserId, scopes })
355
568
 
569
+ const userTokenParameters = {
570
+ user_id: agenticUserId,
571
+ grant_type: 'user_fic',
572
+ }
573
+ const userTokenCacheKey = this.getAgenticTokenCacheKey(tenantId, agentAppInstanceId, scopes, userTokenParameters)
574
+ const cachedUserToken = MsalTokenProvider._agenticTokenCache.get(userTokenCacheKey)
575
+ if (cachedUserToken) {
576
+ return cachedUserToken
577
+ }
578
+
356
579
  const agentToken = await this.getAgenticApplicationToken(tenantId, agentAppInstanceId)
357
580
  const instanceToken = await this.getAgenticInstanceToken(tenantId, agentAppInstanceId)
358
581
 
359
582
  const token = await this.acquireTokenForAgenticScenarios(tenantId, agentAppInstanceId, agentToken, scopes, {
360
- user_id: agenticUserId,
583
+ ...userTokenParameters,
361
584
  user_federated_identity_credential: instanceToken,
362
- grant_type: 'user_fic',
363
585
  })
364
586
 
365
587
  if (!token) {
366
- throw new Error(`Failed to acquire instance token for user token: ${agentAppInstanceId}`)
588
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireInstanceTokenForUserToken, undefined, { agentAppInstanceId })
367
589
  }
368
590
 
369
591
  return token
@@ -372,16 +594,18 @@ export class MsalTokenProvider implements AuthProvider {
372
594
 
373
595
  public async getAgenticApplicationToken (tenantId: string, agentAppInstanceId: string): Promise<string> {
374
596
  if (!this.connectionSettings?.clientId) {
375
- throw new Error('Connection settings must be provided when calling getAgenticApplicationToken')
597
+ throw ExceptionHelper.generateException(Error, Errors.ConnectionSettingsRequiredForGetAgenticApplicationToken)
376
598
  }
377
599
  logger.debug('getAgenticApplicationToken clientId=%s tenantId=%s agentAppInstanceId=%s', this.connectionSettings.clientId, tenantId, agentAppInstanceId)
378
600
 
379
- if (this.connectionSettings.authType === AuthType.IdentityProxyManager) {
601
+ const authType = resolveAuthType(this.connectionSettings)
602
+
603
+ if (authType === AuthType.IdentityProxyManager) {
380
604
  let resource: string
381
605
  if (!this.connectionSettings.idpmResource) {
382
606
  resource = 'api://AzureAdTokenExchange/.default'
383
607
  } else if (!URL.canParse(this.connectionSettings.idpmResource)) {
384
- throw new Error('idpmResource must be a valid absolute URI')
608
+ throw ExceptionHelper.generateException(Error, Errors.IdpmResourceAbsoluteUriRequired)
385
609
  } else {
386
610
  resource = this.connectionSettings.idpmResource
387
611
  }
@@ -393,7 +617,7 @@ export class MsalTokenProvider implements AuthProvider {
393
617
  })
394
618
  const tokenResult = await msiApp.acquireToken({ resource })
395
619
  if (!tokenResult?.accessToken) {
396
- throw new Error(`Failed to acquire token via IdentityProxyManager for agent instance: ${agentAppInstanceId}`)
620
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireTokenViaIdentityProxyManagerForAgentInstance, undefined, { agentAppInstanceId })
397
621
  }
398
622
  logger.debug('getAgenticApplicationToken via IdentityProxyManager clientId=%s resource=%s', this.connectionSettings.clientId, resource)
399
623
  return tokenResult.accessToken
@@ -401,38 +625,28 @@ export class MsalTokenProvider implements AuthProvider {
401
625
 
402
626
  let clientAssertion
403
627
 
404
- if (this.connectionSettings.authType) {
405
- switch (this.connectionSettings.authType) {
406
- case AuthType.WorkloadIdentity: {
407
- const tokenFilePath = this.connectionSettings.federatedTokenFile ?? this.connectionSettings.WIDAssertionFile
408
- if (tokenFilePath === undefined) {
409
- throw ExceptionHelper.generateException(Error, Errors.WorkloadIdentityTokenFileRequired)
410
- }
411
- clientAssertion = fs.readFileSync(tokenFilePath as string, 'utf8')
412
- break
628
+ switch (authType) {
629
+ case AuthType.WorkloadIdentity: {
630
+ const tokenFilePath = this.connectionSettings.federatedTokenFile ?? this.connectionSettings.WIDAssertionFile
631
+ if (tokenFilePath === undefined) {
632
+ throw ExceptionHelper.generateException(Error, Errors.WorkloadIdentityTokenFileRequired)
413
633
  }
414
- case AuthType.FederatedCredentials:
415
- if (!this.connectionSettings.federatedClientId && !this.connectionSettings.FICClientId) {
416
- throw ExceptionHelper.generateException(Error, Errors.FICClientIdRequired)
417
- }
418
- clientAssertion = await this.fetchExternalToken(this.connectionSettings.federatedClientId as string || this.connectionSettings.FICClientId as string)
419
- break
420
- case AuthType.Certificate:
421
- case AuthType.CertificateSubjectName:
422
- if (!this.connectionSettings.certPemFile || !this.connectionSettings.certKeyFile) {
423
- throw ExceptionHelper.generateException(Error, Errors.CertificateFilesRequired)
424
- }
425
- clientAssertion = this.getAssertionFromCert(this.connectionSettings)
426
- break
634
+ clientAssertion = fs.readFileSync(tokenFilePath as string, 'utf8')
635
+ break
427
636
  }
428
- } else if (this.connectionSettings.WIDAssertionFile !== undefined) {
429
- const tokenFilePath = this.connectionSettings.federatedTokenFile ?? this.connectionSettings.WIDAssertionFile
430
- clientAssertion = fs.readFileSync(tokenFilePath as string, 'utf8')
431
- } else if (this.connectionSettings.federatedClientId !== undefined || this.connectionSettings.FICClientId !== undefined) {
432
- clientAssertion = await this.fetchExternalToken(this.connectionSettings.federatedClientId as string || this.connectionSettings.FICClientId as string)
433
- } else if (this.connectionSettings.certPemFile !== undefined &&
434
- this.connectionSettings.certKeyFile !== undefined) {
435
- clientAssertion = this.getAssertionFromCert(this.connectionSettings)
637
+ case AuthType.FederatedCredentials:
638
+ if (!this.connectionSettings.federatedClientId && !this.connectionSettings.FICClientId) {
639
+ throw ExceptionHelper.generateException(Error, Errors.FICClientIdRequired)
640
+ }
641
+ clientAssertion = await this.fetchExternalToken(this.connectionSettings.federatedClientId as string || this.connectionSettings.FICClientId as string)
642
+ break
643
+ case AuthType.Certificate:
644
+ case AuthType.CertificateSubjectName:
645
+ if (!this.connectionSettings.certPemFile || !this.connectionSettings.certKeyFile) {
646
+ throw ExceptionHelper.generateException(Error, Errors.CertificateFilesRequired)
647
+ }
648
+ clientAssertion = this.getAssertionFromCert(this.connectionSettings)
649
+ break
436
650
  }
437
651
 
438
652
  const token = await this.acquireTokenForAgenticScenarios(tenantId, this.connectionSettings.clientId, clientAssertion, ['api://AzureAdTokenExchange/.default'], {
@@ -441,7 +655,7 @@ export class MsalTokenProvider implements AuthProvider {
441
655
  })
442
656
 
443
657
  if (!token) {
444
- throw new Error(`Failed to acquire token for agent instance: ${agentAppInstanceId}`)
658
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireInstanceTokenForAgentInstance, undefined, { agentAppInstanceId })
445
659
  }
446
660
 
447
661
  return token
@@ -559,40 +773,14 @@ export class MsalTokenProvider implements AuthProvider {
559
773
  * @returns A promise that resolves to the access token.
560
774
  */
561
775
  private async acquireTokenWithCertificate (authConfig: AuthConfiguration, scope: string) {
562
- const privateKeySource = fs.readFileSync(authConfig.certKeyFile as string)
563
-
564
- const privateKeyObject = crypto.createPrivateKey({
565
- key: privateKeySource,
566
- format: 'pem'
567
- })
568
-
569
- const privateKey = privateKeyObject.export({
570
- format: 'pem',
571
- type: 'pkcs8'
572
- })
573
-
574
- const pemFile = fs.readFileSync(authConfig.certPemFile as string)
575
- const pubKeyObject = new crypto.X509Certificate(pemFile)
576
-
577
- const cca = new ConfidentialClientApplication({
578
- auth: {
579
- clientId: authConfig.clientId || '',
580
- authority: `${authConfig.authorityEndpoint ?? authConfig.authority}/${authConfig.tenantId || 'botframework.com'}`,
581
- clientCertificate: {
582
- privateKey: privateKey as string,
583
- thumbprint: pubKeyObject.fingerprint.replaceAll(':', ''),
584
- x5c: pemFile.toString()
585
- }
586
- },
587
- system: this.sysOptions
588
- })
776
+ const cca = this.getCertificateClient(authConfig)
589
777
  const token = await cca.acquireTokenByClientCredential({
590
778
  scopes: [`${scope}/.default`],
591
779
  correlationId: randomUUID(),
592
780
  azureRegion: authConfig.azureRegion
593
781
  })
594
782
  if (!token?.accessToken) {
595
- throw new Error('Failed to acquire token using certificate')
783
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireTokenUsingCertificate)
596
784
  }
597
785
  return token.accessToken
598
786
  }
@@ -604,21 +792,14 @@ export class MsalTokenProvider implements AuthProvider {
604
792
  * @returns A promise that resolves to the access token.
605
793
  */
606
794
  private async acquireAccessTokenViaSecret (authConfig: AuthConfiguration, scope: string) {
607
- const cca = new ConfidentialClientApplication({
608
- auth: {
609
- clientId: authConfig.clientId as string,
610
- authority: `${authConfig.authorityEndpoint ?? authConfig.authority}/${authConfig.tenantId || 'botframework.com'}`,
611
- clientSecret: authConfig.clientSecret
612
- },
613
- system: this.sysOptions
614
- })
795
+ const cca = this.getClientSecretClient(authConfig)
615
796
  const token = await cca.acquireTokenByClientCredential({
616
797
  scopes: [`${scope}/.default`],
617
798
  correlationId: randomUUID(),
618
799
  azureRegion: authConfig.azureRegion
619
800
  })
620
801
  if (!token?.accessToken) {
621
- throw new Error('Failed to acquire token using client secret')
802
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireTokenUsingClientSecret)
622
803
  }
623
804
  return token.accessToken
624
805
  }
@@ -643,7 +824,7 @@ export class MsalTokenProvider implements AuthProvider {
643
824
  const token = await cca.acquireTokenByClientCredential({ scopes, azureRegion: authConfig.azureRegion })
644
825
  logger.debug('got token using FIC client assertion')
645
826
  if (!token?.accessToken) {
646
- throw new Error('Failed to acquire token using FIC client assertion')
827
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireTokenUsingFICClientAssertion)
647
828
  }
648
829
  return token.accessToken
649
830
  }
@@ -669,7 +850,7 @@ export class MsalTokenProvider implements AuthProvider {
669
850
  const token = await cca.acquireTokenByClientCredential({ scopes, azureRegion: authConfig.azureRegion })
670
851
  logger.debug('got token using WID client assertion')
671
852
  if (!token?.accessToken) {
672
- throw new Error('Failed to acquire token using WID client assertion')
853
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireTokenUsingWIDClientAssertion)
673
854
  }
674
855
  return token.accessToken
675
856
  }
@@ -693,7 +874,7 @@ export class MsalTokenProvider implements AuthProvider {
693
874
  })
694
875
  logger.debug('got token for FIC')
695
876
  if (!response?.accessToken) {
696
- throw new Error('Failed to acquire external token for FIC client assertion')
877
+ throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireExternalTokenForFICClientAssertion)
697
878
  }
698
879
  return response.accessToken
699
880
  }