@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.
- package/README.md +16 -0
- package/dist/package.json +3 -3
- package/dist/src/agent-client/agentClient.js +4 -3
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.d.ts +25 -6
- package/dist/src/agent-client/agentResponseHandler.js +16 -55
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/agent-client/createAgentResponseHandler.d.ts +48 -0
- package/dist/src/agent-client/createAgentResponseHandler.js +92 -0
- package/dist/src/agent-client/createAgentResponseHandler.js.map +1 -0
- package/dist/src/agent-client/index.d.ts +1 -0
- package/dist/src/agent-client/index.js +1 -0
- package/dist/src/agent-client/index.js.map +1 -1
- package/dist/src/app/adaptiveCards/activityValueParsers.js +2 -1
- package/dist/src/app/adaptiveCards/activityValueParsers.js.map +1 -1
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js +13 -12
- package/dist/src/app/adaptiveCards/adaptiveCardsActions.js.map +1 -1
- package/dist/src/app/agentApplication.js +8 -8
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/streaming/streamingResponse.d.ts +11 -0
- package/dist/src/app/streaming/streamingResponse.js +23 -2
- package/dist/src/app/streaming/streamingResponse.js.map +1 -1
- package/dist/src/app/turnState.d.ts +0 -1
- package/dist/src/app/turnState.js +15 -14
- package/dist/src/app/turnState.js.map +1 -1
- package/dist/src/app/turnStateProperty.js +4 -2
- package/dist/src/app/turnStateProperty.js.map +1 -1
- package/dist/src/auth/MemoryCache.d.ts +2 -1
- package/dist/src/auth/MemoryCache.js +7 -1
- package/dist/src/auth/MemoryCache.js.map +1 -1
- package/dist/src/auth/authConfiguration.d.ts +1 -1
- package/dist/src/auth/authConfiguration.js +41 -4
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/authConstants.d.ts +7 -7
- package/dist/src/auth/authConstants.js.map +1 -1
- package/dist/src/auth/connectionManager.d.ts +92 -0
- package/dist/src/auth/{msalConnectionManager.js → connectionManager.js} +50 -48
- package/dist/src/auth/connectionManager.js.map +1 -0
- package/dist/src/auth/index.d.ts +5 -3
- package/dist/src/auth/index.js +5 -3
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.d.ts +8 -2
- package/dist/src/auth/jwt-middleware.js +116 -7
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msal/msalConnectionManager.d.ts +17 -0
- package/dist/src/auth/msal/msalConnectionManager.js +50 -0
- package/dist/src/auth/msal/msalConnectionManager.js.map +1 -0
- package/dist/src/auth/msal/msalConnectionSettings.d.ts +68 -0
- package/dist/src/auth/msal/msalConnectionSettings.js +7 -0
- package/dist/src/auth/msal/msalConnectionSettings.js.map +1 -0
- package/dist/src/auth/{msalTokenCredential.d.ts → msal/msalTokenCredential.d.ts} +1 -1
- package/dist/src/auth/{msalTokenCredential.js → msal/msalTokenCredential.js} +2 -2
- package/dist/src/auth/msal/msalTokenCredential.js.map +1 -0
- package/dist/src/auth/{msalTokenProvider.d.ts → msal/msalTokenProvider.d.ts} +23 -3
- package/dist/src/auth/{msalTokenProvider.js → msal/msalTokenProvider.js} +280 -176
- package/dist/src/auth/msal/msalTokenProvider.js.map +1 -0
- package/dist/src/auth/settings.d.ts +142 -133
- package/dist/src/auth/settings.js +49 -5
- package/dist/src/auth/settings.js.map +1 -1
- package/dist/src/auth/sidecar/sidecarAuthProvider.d.ts +74 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js +181 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.d.ts +65 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.js +7 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.d.ts +95 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.js +406 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarModels.d.ts +110 -0
- package/dist/src/auth/sidecar/sidecarModels.js +48 -0
- package/dist/src/auth/sidecar/sidecarModels.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.d.ts +13 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.js +39 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.js.map +1 -0
- package/dist/src/baseAdapter.js +3 -1
- package/dist/src/baseAdapter.js.map +1 -1
- package/dist/src/cloudAdapter.d.ts +2 -2
- package/dist/src/cloudAdapter.js +11 -11
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/createCloudAdapter.d.ts +40 -0
- package/dist/src/createCloudAdapter.js +44 -0
- package/dist/src/createCloudAdapter.js.map +1 -0
- package/dist/src/errorHelper.js +302 -79
- package/dist/src/errorHelper.js.map +1 -1
- package/dist/src/headerPropagation.js +3 -1
- package/dist/src/headerPropagation.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/interfaces/index.d.ts +5 -0
- package/dist/src/interfaces/index.js +22 -0
- package/dist/src/interfaces/index.js.map +1 -0
- package/dist/src/interfaces/webResponse.d.ts +41 -0
- package/dist/src/interfaces/webResponse.js +7 -0
- package/dist/src/interfaces/webResponse.js.map +1 -0
- package/dist/src/middlewareSet.d.ts +0 -1
- package/dist/src/middlewareSet.js +4 -1
- package/dist/src/middlewareSet.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +12 -0
- package/dist/src/oauth/userTokenClient.js +30 -9
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/state/conversationState.js +4 -2
- package/dist/src/state/conversationState.js.map +1 -1
- package/dist/src/state/userState.js +4 -2
- package/dist/src/state/userState.js.map +1 -1
- package/dist/src/storage/memoryStorage.js +5 -3
- package/dist/src/storage/memoryStorage.js.map +1 -1
- package/dist/src/transcript/consoleTranscriptLogger.js +3 -1
- package/dist/src/transcript/consoleTranscriptLogger.js.map +1 -1
- package/dist/src/transcript/fileTranscriptLogger.js +5 -4
- package/dist/src/transcript/fileTranscriptLogger.js.map +1 -1
- package/dist/src/transcript/transcriptLoggerMiddleware.js +2 -1
- package/dist/src/transcript/transcriptLoggerMiddleware.js.map +1 -1
- package/dist/src/turnContext.js +2 -1
- package/dist/src/turnContext.js.map +1 -1
- package/package.json +3 -3
- package/src/agent-client/agentClient.ts +5 -4
- package/src/agent-client/agentResponseHandler.ts +43 -67
- package/src/agent-client/createAgentResponseHandler.ts +133 -0
- package/src/agent-client/index.ts +1 -0
- package/src/app/adaptiveCards/activityValueParsers.ts +3 -2
- package/src/app/adaptiveCards/adaptiveCardsActions.ts +5 -5
- package/src/app/agentApplication.ts +8 -16
- package/src/app/streaming/streamingResponse.ts +26 -3
- package/src/app/turnState.ts +15 -14
- package/src/app/turnStateProperty.ts +4 -2
- package/src/auth/MemoryCache.ts +7 -1
- package/src/auth/authConfiguration.ts +41 -6
- package/src/auth/authConstants.ts +7 -7
- package/src/auth/{msalConnectionManager.ts → connectionManager.ts} +65 -61
- package/src/auth/index.ts +5 -3
- package/src/auth/jwt-middleware.ts +118 -9
- package/src/auth/msal/msalConnectionManager.ts +55 -0
- package/src/auth/msal/msalConnectionSettings.ts +79 -0
- package/src/auth/{msalTokenCredential.ts → msal/msalTokenCredential.ts} +2 -1
- package/src/auth/{msalTokenProvider.ts → msal/msalTokenProvider.ts} +353 -172
- package/src/auth/settings.ts +131 -76
- package/src/auth/sidecar/sidecarAuthProvider.ts +234 -0
- package/src/auth/sidecar/sidecarConnectionSettings.ts +72 -0
- package/src/auth/sidecar/sidecarHttpClient.ts +443 -0
- package/src/auth/sidecar/sidecarModels.ts +153 -0
- package/src/auth/sidecar/sidecarTokenExpiry.ts +35 -0
- package/src/baseAdapter.ts +3 -2
- package/src/cloudAdapter.ts +13 -13
- package/src/createCloudAdapter.ts +56 -0
- package/src/errorHelper.ts +354 -89
- package/src/headerPropagation.ts +4 -1
- package/src/index.ts +3 -1
- package/src/interfaces/index.ts +6 -0
- package/src/interfaces/webResponse.ts +44 -0
- package/src/middlewareSet.ts +3 -1
- package/src/oauth/userTokenClient.ts +46 -11
- package/src/state/conversationState.ts +4 -3
- package/src/state/userState.ts +4 -3
- package/src/storage/memoryStorage.ts +5 -3
- package/src/transcript/consoleTranscriptLogger.ts +3 -2
- package/src/transcript/fileTranscriptLogger.ts +6 -5
- package/src/transcript/transcriptLoggerMiddleware.ts +3 -2
- package/src/turnContext.ts +3 -2
- package/dist/src/auth/msalConnectionManager.d.ts +0 -64
- package/dist/src/auth/msalConnectionManager.js.map +0 -1
- package/dist/src/auth/msalTokenCredential.js.map +0 -1
- 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 '
|
|
8
|
-
import { AuthProvider } from '
|
|
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 '
|
|
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 '
|
|
15
|
+
import { AuthenticationTraceDefinitions } from '../../observability'
|
|
17
16
|
import { ExceptionHelper } from '@microsoft/agents-activity'
|
|
18
|
-
import { Errors } from '
|
|
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
|
|
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
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
96
|
-
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
290
|
-
if (
|
|
291
|
-
return
|
|
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.
|
|
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
|
-
|
|
583
|
+
...userTokenParameters,
|
|
361
584
|
user_federated_identity_credential: instanceToken,
|
|
362
|
-
grant_type: 'user_fic',
|
|
363
585
|
})
|
|
364
586
|
|
|
365
587
|
if (!token) {
|
|
366
|
-
throw
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
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
|
-
|
|
415
|
-
|
|
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
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
877
|
+
throw ExceptionHelper.generateException(Error, Errors.FailedToAcquireExternalTokenForFICClientAssertion)
|
|
697
878
|
}
|
|
698
879
|
return response.accessToken
|
|
699
880
|
}
|