@microsoft/agents-hosting 1.1.0-alpha.2 → 1.1.0-alpha.58
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/dist/package.json +10 -6
- package/dist/src/activityWireCompat.js +8 -3
- package/dist/src/activityWireCompat.js.map +1 -1
- package/dist/src/agent-client/agentClient.js +7 -3
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.js +6 -2
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/app/agentApplication.d.ts +26 -11
- package/dist/src/app/agentApplication.js +94 -86
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/agentApplicationBuilder.d.ts +2 -2
- package/dist/src/app/agentApplicationBuilder.js.map +1 -1
- package/dist/src/app/agentApplicationOptions.d.ts +9 -2
- package/dist/src/app/appRoute.d.ts +7 -0
- package/dist/src/app/attachmentDownloader.d.ts +13 -3
- package/dist/src/app/attachmentDownloader.js +16 -3
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/{authorization.d.ts → auth/authorization.d.ts} +33 -139
- package/dist/src/app/auth/authorization.js +188 -0
- package/dist/src/app/auth/authorization.js.map +1 -0
- package/dist/src/app/auth/authorizationManager.d.ts +71 -0
- package/dist/src/app/auth/authorizationManager.js +170 -0
- package/dist/src/app/auth/authorizationManager.js.map +1 -0
- package/dist/src/app/auth/handlerStorage.d.ts +36 -0
- package/dist/src/app/auth/handlerStorage.js +62 -0
- package/dist/src/app/auth/handlerStorage.js.map +1 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.d.ts +97 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.js +145 -0
- package/dist/src/app/auth/handlers/agenticAuthorization.js.map +1 -0
- package/dist/src/app/auth/handlers/azureBotAuthorization.d.ts +222 -0
- package/dist/src/app/auth/handlers/azureBotAuthorization.js +428 -0
- package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -0
- package/dist/src/app/auth/handlers/index.d.ts +2 -0
- package/dist/src/app/auth/handlers/index.js +19 -0
- package/dist/src/app/auth/handlers/index.js.map +1 -0
- package/dist/src/app/auth/index.d.ts +2 -0
- package/dist/src/app/auth/index.js +19 -0
- package/dist/src/app/auth/index.js.map +1 -0
- package/dist/src/app/auth/types.d.ts +104 -0
- package/dist/src/app/auth/types.js +24 -0
- package/dist/src/app/auth/types.js.map +1 -0
- package/dist/src/app/index.d.ts +2 -3
- package/dist/src/app/index.js +2 -3
- package/dist/src/app/index.js.map +1 -1
- package/dist/src/app/inputFileDownloader.d.ts +10 -3
- package/dist/src/app/routeList.d.ts +1 -1
- package/dist/src/app/routeList.js +22 -5
- package/dist/src/app/routeList.js.map +1 -1
- package/dist/src/app/streaming/streamingResponse.d.ts +11 -1
- package/dist/src/app/streaming/streamingResponse.js +17 -2
- package/dist/src/app/streaming/streamingResponse.js.map +1 -1
- package/dist/src/app/turnState.d.ts +2 -38
- package/dist/src/app/turnState.js +1 -46
- package/dist/src/app/turnState.js.map +1 -1
- package/dist/src/auth/MemoryCache.d.ts +16 -0
- package/dist/src/auth/MemoryCache.js +58 -0
- package/dist/src/auth/MemoryCache.js.map +1 -0
- package/dist/src/auth/authConfiguration.d.ts +44 -2
- package/dist/src/auth/authConfiguration.js +218 -53
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/authConstants.d.ts +11 -0
- package/dist/src/auth/authConstants.js +15 -0
- package/dist/src/auth/authConstants.js.map +1 -0
- package/dist/src/auth/authProvider.d.ts +23 -0
- package/dist/src/auth/connections.d.ts +40 -0
- package/dist/src/auth/connections.js +7 -0
- package/dist/src/auth/connections.js.map +1 -0
- package/dist/src/auth/index.d.ts +2 -0
- package/dist/src/auth/index.js +2 -0
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.js +31 -18
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msalConnectionManager.d.ts +63 -0
- package/dist/src/auth/msalConnectionManager.js +124 -0
- package/dist/src/auth/msalConnectionManager.js.map +1 -0
- package/dist/src/auth/msalTokenProvider.d.ts +31 -0
- package/dist/src/auth/msalTokenProvider.js +167 -16
- package/dist/src/auth/msalTokenProvider.js.map +1 -1
- package/dist/src/baseAdapter.d.ts +10 -25
- package/dist/src/baseAdapter.js +2 -15
- package/dist/src/baseAdapter.js.map +1 -1
- package/dist/src/cloudAdapter.d.ts +40 -23
- package/dist/src/cloudAdapter.js +132 -56
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +9 -0
- package/dist/src/connector-client/connectorClient.js +39 -9
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/oauth/index.d.ts +0 -1
- package/dist/src/oauth/index.js +0 -1
- package/dist/src/oauth/index.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +30 -13
- package/dist/src/oauth/userTokenClient.js +64 -26
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/oauth/userTokenClient.types.d.ts +19 -6
- package/dist/src/turnContext.d.ts +7 -1
- package/dist/src/turnContext.js +11 -4
- package/dist/src/turnContext.js.map +1 -1
- package/package.json +10 -6
- package/src/activityWireCompat.ts +8 -3
- package/src/agent-client/agentClient.ts +9 -3
- package/src/agent-client/agentResponseHandler.ts +5 -2
- package/src/app/agentApplication.ts +98 -79
- package/src/app/agentApplicationBuilder.ts +2 -2
- package/src/app/agentApplicationOptions.ts +10 -2
- package/src/app/appRoute.ts +8 -0
- package/src/app/attachmentDownloader.ts +18 -3
- package/src/app/auth/authorization.ts +252 -0
- package/src/app/auth/authorizationManager.ts +213 -0
- package/src/app/auth/handlerStorage.ts +61 -0
- package/src/app/auth/handlers/agenticAuthorization.ts +194 -0
- package/src/app/auth/handlers/azureBotAuthorization.ts +599 -0
- package/src/app/auth/handlers/index.ts +2 -0
- package/src/app/auth/index.ts +2 -0
- package/src/app/auth/types.ts +111 -0
- package/src/app/index.ts +2 -3
- package/src/app/inputFileDownloader.ts +11 -3
- package/src/app/routeList.ts +24 -5
- package/src/app/streaming/streamingResponse.ts +20 -3
- package/src/app/turnState.ts +2 -61
- package/src/auth/MemoryCache.ts +59 -0
- package/src/auth/authConfiguration.ts +258 -52
- package/src/auth/authConstants.ts +11 -0
- package/src/auth/authProvider.ts +31 -0
- package/src/auth/connections.ts +46 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/jwt-middleware.ts +38 -21
- package/src/auth/msalConnectionManager.ts +150 -0
- package/src/auth/msalTokenProvider.ts +209 -9
- package/src/baseAdapter.ts +10 -29
- package/src/cloudAdapter.ts +192 -67
- package/src/connector-client/connectorClient.ts +49 -10
- package/src/index.ts +0 -1
- package/src/oauth/index.ts +0 -1
- package/src/oauth/userTokenClient.ts +79 -23
- package/src/oauth/userTokenClient.types.ts +20 -8
- package/src/turnContext.ts +16 -5
- package/dist/src/app/authorization.js +0 -387
- package/dist/src/app/authorization.js.map +0 -1
- package/dist/src/claimsIdentity.d.ts +0 -35
- package/dist/src/claimsIdentity.js +0 -43
- package/dist/src/claimsIdentity.js.map +0 -1
- package/dist/src/oauth/oAuthFlow.d.ts +0 -119
- package/dist/src/oauth/oAuthFlow.js +0 -316
- package/dist/src/oauth/oAuthFlow.js.map +0 -1
- package/src/app/authorization.ts +0 -432
- package/src/claimsIdentity.ts +0 -47
- package/src/oauth/oAuthFlow.ts +0 -378
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { debug } from '@microsoft/agents-activity/logger'
|
|
7
|
+
import { ConnectionMapItem } from './msalConnectionManager'
|
|
8
|
+
import objectPath from 'object-path'
|
|
9
|
+
|
|
10
|
+
const logger = debug('agents:authConfiguration')
|
|
11
|
+
const DEFAULT_CONNECTION = 'serviceConnection'
|
|
12
|
+
|
|
6
13
|
/**
|
|
7
14
|
* Represents the authentication configuration.
|
|
8
15
|
*/
|
|
@@ -15,7 +22,7 @@ export interface AuthConfiguration {
|
|
|
15
22
|
/**
|
|
16
23
|
* The client ID for the authentication configuration. Required in production.
|
|
17
24
|
*/
|
|
18
|
-
clientId
|
|
25
|
+
clientId?: string
|
|
19
26
|
|
|
20
27
|
/**
|
|
21
28
|
* The client secret for the authentication configuration.
|
|
@@ -35,7 +42,7 @@ export interface AuthConfiguration {
|
|
|
35
42
|
/**
|
|
36
43
|
* A list of valid issuers for the authentication configuration.
|
|
37
44
|
*/
|
|
38
|
-
issuers
|
|
45
|
+
issuers?: string[]
|
|
39
46
|
|
|
40
47
|
/**
|
|
41
48
|
* The connection name for the authentication configuration.
|
|
@@ -56,6 +63,28 @@ export interface AuthConfiguration {
|
|
|
56
63
|
* see also https://learn.microsoft.com/entra/identity-platform/authentication-national-cloud
|
|
57
64
|
*/
|
|
58
65
|
authority?: string
|
|
66
|
+
|
|
67
|
+
scope?: string
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A map of connection names to their respective authentication configurations.
|
|
71
|
+
*/
|
|
72
|
+
connections?: Map<string, AuthConfiguration>
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A list of connection map items to map service URLs to connection names.
|
|
76
|
+
*/
|
|
77
|
+
connectionsMap?: ConnectionMapItem[],
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* An optional alternative blueprint Connection name used when constructing a connector client.
|
|
81
|
+
*/
|
|
82
|
+
altBlueprintConnectionName?: string
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The path to K8s provided token.
|
|
86
|
+
*/
|
|
87
|
+
WIDAssertionFile?: string
|
|
59
88
|
}
|
|
60
89
|
|
|
61
90
|
/**
|
|
@@ -83,44 +112,43 @@ export interface AuthConfiguration {
|
|
|
83
112
|
* ```
|
|
84
113
|
*
|
|
85
114
|
*/
|
|
86
|
-
export const loadAuthConfigFromEnv
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
connectionName: process.env.connectionName,
|
|
99
|
-
FICClientId: process.env.FICClientId,
|
|
100
|
-
authority,
|
|
101
|
-
issuers: [
|
|
102
|
-
'https://api.botframework.com',
|
|
103
|
-
`https://sts.windows.net/${process.env.tenantId}/`,
|
|
104
|
-
`${authority}/${process.env.tenantId}/v2.0`
|
|
105
|
-
],
|
|
106
|
-
}
|
|
115
|
+
export const loadAuthConfigFromEnv = (cnxName?: string): AuthConfiguration => {
|
|
116
|
+
const envConnections = loadConnectionsMapFromEnv()
|
|
117
|
+
let authConfig: AuthConfiguration
|
|
118
|
+
|
|
119
|
+
if (envConnections.connectionsMap.length === 0) {
|
|
120
|
+
// No connections provided, we need to populate the connections map with the old config settings
|
|
121
|
+
authConfig = buildLegacyAuthConfig(cnxName)
|
|
122
|
+
envConnections.connections.set(DEFAULT_CONNECTION, authConfig)
|
|
123
|
+
envConnections.connectionsMap.push({
|
|
124
|
+
serviceUrl: '*',
|
|
125
|
+
connection: DEFAULT_CONNECTION,
|
|
126
|
+
})
|
|
107
127
|
} else {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
// There are connections provided, use the default or specified connection
|
|
129
|
+
if (cnxName) {
|
|
130
|
+
const entry = envConnections.connections.get(cnxName)
|
|
131
|
+
if (entry) {
|
|
132
|
+
authConfig = entry
|
|
133
|
+
} else {
|
|
134
|
+
throw new Error(`Connection "${cnxName}" not found in environment.`)
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
const defaultItem = envConnections.connectionsMap.find((item) => item.serviceUrl === '*')
|
|
138
|
+
const defaultConn = defaultItem ? envConnections.connections.get(defaultItem.connection) : undefined
|
|
139
|
+
if (!defaultConn) {
|
|
140
|
+
throw new Error('No default connection found in environment connections.')
|
|
141
|
+
}
|
|
142
|
+
authConfig = defaultConn
|
|
123
143
|
}
|
|
144
|
+
|
|
145
|
+
authConfig.authority ??= 'https://login.microsoftonline.com'
|
|
146
|
+
authConfig.issuers ??= getDefaultIssuers(authConfig.tenantId ?? '', authConfig.authority)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
...authConfig,
|
|
151
|
+
...envConnections,
|
|
124
152
|
}
|
|
125
153
|
}
|
|
126
154
|
|
|
@@ -139,23 +167,201 @@ export const loadAuthConfigFromEnv: (cnxName?: string) => AuthConfiguration = (c
|
|
|
139
167
|
*
|
|
140
168
|
*/
|
|
141
169
|
export const loadPrevAuthConfigFromEnv: () => AuthConfiguration = () => {
|
|
142
|
-
|
|
170
|
+
const envConnections = loadConnectionsMapFromEnv()
|
|
171
|
+
let authConfig: AuthConfiguration = {}
|
|
172
|
+
|
|
173
|
+
if (envConnections.connectionsMap.length === 0) {
|
|
174
|
+
// No connections provided, we need to populate the connection map with the old config settings
|
|
175
|
+
if (process.env.MicrosoftAppId === undefined && process.env.NODE_ENV === 'production') {
|
|
176
|
+
throw new Error('ClientId required in production')
|
|
177
|
+
}
|
|
178
|
+
const authority = process.env.authorityEndpoint ?? 'https://login.microsoftonline.com'
|
|
179
|
+
authConfig = {
|
|
180
|
+
tenantId: process.env.MicrosoftAppTenantId,
|
|
181
|
+
clientId: process.env.MicrosoftAppId,
|
|
182
|
+
clientSecret: process.env.MicrosoftAppPassword,
|
|
183
|
+
certPemFile: process.env.certPemFile,
|
|
184
|
+
certKeyFile: process.env.certKeyFile,
|
|
185
|
+
connectionName: process.env.connectionName,
|
|
186
|
+
FICClientId: process.env.MicrosoftAppClientId,
|
|
187
|
+
authority,
|
|
188
|
+
scope: process.env.scope,
|
|
189
|
+
issuers: getDefaultIssuers(process.env.MicrosoftAppTenantId ?? '', authority),
|
|
190
|
+
altBlueprintConnectionName: process.env.altBlueprintConnectionName,
|
|
191
|
+
WIDAssertionFile: process.env.WIDAssertionFile,
|
|
192
|
+
}
|
|
193
|
+
envConnections.connections.set(DEFAULT_CONNECTION, authConfig)
|
|
194
|
+
envConnections.connectionsMap.push({
|
|
195
|
+
serviceUrl: '*',
|
|
196
|
+
connection: DEFAULT_CONNECTION,
|
|
197
|
+
})
|
|
198
|
+
} else {
|
|
199
|
+
// There are connections provided, use the default one.
|
|
200
|
+
const defaultItem = envConnections.connectionsMap.find((item) => item.serviceUrl === '*')
|
|
201
|
+
const defaultConn = defaultItem ? envConnections.connections.get(defaultItem.connection) : undefined
|
|
202
|
+
if (!defaultConn) {
|
|
203
|
+
throw new Error('No default connection found in environment connections.')
|
|
204
|
+
}
|
|
205
|
+
authConfig = defaultConn
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
authConfig.authority ??= 'https://login.microsoftonline.com'
|
|
209
|
+
authConfig.issuers ??= getDefaultIssuers(authConfig.tenantId ?? '', authConfig.authority)
|
|
210
|
+
|
|
211
|
+
return { ...authConfig, ...envConnections }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function loadConnectionsMapFromEnv () {
|
|
215
|
+
const envVars = process.env
|
|
216
|
+
const connections = new Map<string, AuthConfiguration>()
|
|
217
|
+
const connectionsMap: ConnectionMapItem[] = []
|
|
218
|
+
|
|
219
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
220
|
+
if (key.startsWith('connections__')) {
|
|
221
|
+
const parts = key.split('__')
|
|
222
|
+
if (parts.length >= 4 && parts[2] === 'settings') {
|
|
223
|
+
const connectionName = parts[1]
|
|
224
|
+
const propertyPath = parts.slice(3).join('.') // e.g., 'issuers.0' or 'clientId'
|
|
225
|
+
|
|
226
|
+
let config = connections.get(connectionName)
|
|
227
|
+
if (!config) {
|
|
228
|
+
config = {}
|
|
229
|
+
connections.set(connectionName, config)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
objectPath.set(config, propertyPath, value)
|
|
233
|
+
}
|
|
234
|
+
} else if (key.startsWith('connectionsMap__')) {
|
|
235
|
+
const parts = key.split('__')
|
|
236
|
+
if (parts.length === 3) {
|
|
237
|
+
const index = parseInt(parts[1], 10)
|
|
238
|
+
const property = parts[2]
|
|
239
|
+
|
|
240
|
+
if (!connectionsMap[index]) {
|
|
241
|
+
connectionsMap[index] = { serviceUrl: '', connection: '' }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
(connectionsMap[index] as any)[property] = value
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (connections.size === 0) {
|
|
250
|
+
logger.warn('No connections found in configuration.')
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (connectionsMap.length === 0) {
|
|
254
|
+
logger.warn('No connections map found in configuration.')
|
|
255
|
+
if (connections.size > 0) {
|
|
256
|
+
const firstEntry = connections.entries().next().value
|
|
257
|
+
|
|
258
|
+
if (firstEntry) {
|
|
259
|
+
const [firstKey] = firstEntry
|
|
260
|
+
// Provide a default connection map if none is specified
|
|
261
|
+
connectionsMap.push({
|
|
262
|
+
serviceUrl: '*',
|
|
263
|
+
connection: firstKey,
|
|
264
|
+
})
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
connections,
|
|
271
|
+
connectionsMap,
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Loads the authentication configuration from the provided config or from the environment variables
|
|
277
|
+
* providing default values for authority and issuers.
|
|
278
|
+
*
|
|
279
|
+
* @returns The authentication configuration.
|
|
280
|
+
* @throws Will throw an error if clientId is not provided in production.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```
|
|
284
|
+
* tenantId=your-tenant-id
|
|
285
|
+
* clientId=your-client-id
|
|
286
|
+
* clientSecret=your-client-secret
|
|
287
|
+
*
|
|
288
|
+
* certPemFile=your-cert-pem-file
|
|
289
|
+
* certKeyFile=your-cert-key-file
|
|
290
|
+
*
|
|
291
|
+
* FICClientId=your-FIC-client-id
|
|
292
|
+
*
|
|
293
|
+
* connectionName=your-connection-name
|
|
294
|
+
* authority=your-authority-endpoint
|
|
295
|
+
* ```
|
|
296
|
+
*
|
|
297
|
+
*/
|
|
298
|
+
export function getAuthConfigWithDefaults (config?: AuthConfiguration): AuthConfiguration {
|
|
299
|
+
if (!config) return loadAuthConfigFromEnv()
|
|
300
|
+
|
|
301
|
+
const providedConnections = config.connections && config.connectionsMap
|
|
302
|
+
? { connections: config.connections, connectionsMap: config.connectionsMap }
|
|
303
|
+
: undefined
|
|
304
|
+
|
|
305
|
+
const connections = providedConnections ?? loadConnectionsMapFromEnv()
|
|
306
|
+
|
|
307
|
+
let mergedConfig: AuthConfiguration
|
|
308
|
+
|
|
309
|
+
if (connections && connections.connectionsMap?.length === 0) {
|
|
310
|
+
// No connections provided, we need to populate the connections map with the old config settings
|
|
311
|
+
mergedConfig = buildLegacyAuthConfig(undefined, config)
|
|
312
|
+
connections.connections?.set(DEFAULT_CONNECTION, mergedConfig)
|
|
313
|
+
connections.connectionsMap.push({ serviceUrl: '*', connection: DEFAULT_CONNECTION })
|
|
314
|
+
} else {
|
|
315
|
+
// There are connections provided, use the default connection
|
|
316
|
+
const defaultItem = connections.connectionsMap?.find((item) => item.serviceUrl === '*')
|
|
317
|
+
const defaultConn = defaultItem ? connections.connections?.get(defaultItem.connection) : undefined
|
|
318
|
+
if (!defaultConn) {
|
|
319
|
+
throw new Error('No default connection found in environment connections.')
|
|
320
|
+
}
|
|
321
|
+
mergedConfig = buildLegacyAuthConfig(undefined, defaultConn)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
...mergedConfig,
|
|
326
|
+
...connections,
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function buildLegacyAuthConfig (envPrefix: string = '', customConfig?: AuthConfiguration): AuthConfiguration {
|
|
331
|
+
const prefix = envPrefix ? `${envPrefix}_` : ''
|
|
332
|
+
const authority = customConfig?.authority ?? process.env[`${prefix}authorityEndpoint`] ?? 'https://login.microsoftonline.com'
|
|
333
|
+
|
|
334
|
+
const clientId = customConfig?.clientId ?? process.env[`${prefix}clientId`]
|
|
335
|
+
|
|
336
|
+
if (!clientId && !envPrefix && process.env.NODE_ENV === 'production') {
|
|
143
337
|
throw new Error('ClientId required in production')
|
|
144
338
|
}
|
|
145
|
-
|
|
339
|
+
if (!clientId && envPrefix) {
|
|
340
|
+
throw new Error(`ClientId not found for connection: ${envPrefix}`)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const tenantId = customConfig?.tenantId ?? process.env[`${prefix}tenantId`]
|
|
344
|
+
|
|
146
345
|
return {
|
|
147
|
-
tenantId
|
|
148
|
-
clientId:
|
|
149
|
-
clientSecret: process.env
|
|
150
|
-
certPemFile: process.env
|
|
151
|
-
certKeyFile: process.env
|
|
152
|
-
connectionName: process.env
|
|
153
|
-
FICClientId: process.env
|
|
346
|
+
tenantId,
|
|
347
|
+
clientId: clientId!,
|
|
348
|
+
clientSecret: customConfig?.clientSecret ?? process.env[`${prefix}clientSecret`],
|
|
349
|
+
certPemFile: customConfig?.certPemFile ?? process.env[`${prefix}certPemFile`],
|
|
350
|
+
certKeyFile: customConfig?.certKeyFile ?? process.env[`${prefix}certKeyFile`],
|
|
351
|
+
connectionName: customConfig?.connectionName ?? process.env[`${prefix}connectionName`],
|
|
352
|
+
FICClientId: customConfig?.FICClientId ?? process.env[`${prefix}FICClientId`],
|
|
154
353
|
authority,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
]
|
|
354
|
+
scope: customConfig?.scope ?? process.env[`${prefix}scope`],
|
|
355
|
+
issuers: customConfig?.issuers ?? getDefaultIssuers(tenantId as string, authority),
|
|
356
|
+
altBlueprintConnectionName: customConfig?.altBlueprintConnectionName ?? process.env[`${prefix}altBlueprintConnectionName`],
|
|
357
|
+
WIDAssertionFile: customConfig?.WIDAssertionFile ?? process.env[`${prefix}WIDAssertionFile`]
|
|
160
358
|
}
|
|
161
359
|
}
|
|
360
|
+
|
|
361
|
+
function getDefaultIssuers (tenantId: string, authority: string) : string[] {
|
|
362
|
+
return [
|
|
363
|
+
'https://api.botframework.com',
|
|
364
|
+
`https://sts.windows.net/${tenantId}/`,
|
|
365
|
+
`${authority}/${tenantId}/v2.0`
|
|
366
|
+
]
|
|
367
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
export const ApxLocalScope = 'c16e153d-5d2b-4c21-b7f4-b05ee5d516f1/.default'
|
|
6
|
+
export const ApxDevScope = '0d94caae-b412-4943-8a68-83135ad6d35f/.default'
|
|
7
|
+
export const ApxProductionScope = '5a807f24-c9de-44ee-a3a7-329e88a00ffc/.default'
|
|
8
|
+
export const ApxGCCScope = 'c9475445-9789-4fef-9ec5-cde4a9bcd446/.default'
|
|
9
|
+
export const ApxGCCHScope = '6f669b9e-7701-4e2b-b624-82c9207fde26/.default'
|
|
10
|
+
export const ApxDoDScope = '0a069c81-8c7c-4712-886b-9c542d673ffb/.default'
|
|
11
|
+
export const ApxGallatinScope = 'bd004c8e-5acf-4c48-8570-4e7d46b2f63b/.default'
|
package/src/auth/authProvider.ts
CHANGED
|
@@ -16,4 +16,35 @@ export interface AuthProvider {
|
|
|
16
16
|
* @returns A promise that resolves to the access token.
|
|
17
17
|
*/
|
|
18
18
|
getAccessToken: (authConfig: AuthConfiguration, scope: string) => Promise<string>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get an access token for the agentic application
|
|
22
|
+
* @param agentAppInstanceId
|
|
23
|
+
* @returns a promise that resolves to the access token.
|
|
24
|
+
*/
|
|
25
|
+
getAgenticApplicationToken: (agentAppInstanceId: string) => Promise<string>
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get an access token for the agentic instance
|
|
29
|
+
* @param agentAppInstanceId
|
|
30
|
+
* @returns a promise that resolves to the access token.
|
|
31
|
+
*/
|
|
32
|
+
getAgenticInstanceToken: (agentAppInstanceId: string) => Promise<string>
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get an access token for the agentic user
|
|
36
|
+
* @param agentAppInstanceId
|
|
37
|
+
* @param upn
|
|
38
|
+
* @param scopes
|
|
39
|
+
* @returns a promise that resolves to the access token.
|
|
40
|
+
*/
|
|
41
|
+
getAgenticUserToken: (agentAppInstanceId: string, upn: string, scopes: string[]) => Promise<string>
|
|
42
|
+
|
|
43
|
+
acquireTokenOnBehalfOf (scopes: string[], oboAssertion: string): Promise<string>
|
|
44
|
+
acquireTokenOnBehalfOf (authConfig: AuthConfiguration, scopes: string[], oboAssertion: string): Promise<string>
|
|
45
|
+
acquireTokenOnBehalfOf (
|
|
46
|
+
authConfigOrScopes: AuthConfiguration | string[],
|
|
47
|
+
scopesOrOboAssertion?: string[] | string,
|
|
48
|
+
oboAssertion?: string
|
|
49
|
+
): Promise<string>
|
|
19
50
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Activity } from '@microsoft/agents-activity'
|
|
7
|
+
import { AuthConfiguration } from './authConfiguration'
|
|
8
|
+
import { AuthProvider } from './authProvider'
|
|
9
|
+
|
|
10
|
+
export interface Connections {
|
|
11
|
+
/**
|
|
12
|
+
* Get the OAuth connection for the agent.
|
|
13
|
+
* @param name - The connection name. Must match a configured OAuth connection.
|
|
14
|
+
* @returns An AuthProvider instance.
|
|
15
|
+
* @throws {Error} If the connection name is not found.
|
|
16
|
+
*/
|
|
17
|
+
getConnection: (name: string) => AuthProvider
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the default OAuth connection for the agent.
|
|
21
|
+
* @returns An AuthProvider instance.
|
|
22
|
+
*/
|
|
23
|
+
getDefaultConnection: () => AuthProvider
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the OAuth token provider for the agent.
|
|
27
|
+
* @param audience - The audience.
|
|
28
|
+
* @param serviceUrl - The service url.
|
|
29
|
+
* @returns An AuthProvider instance.
|
|
30
|
+
*/
|
|
31
|
+
getTokenProvider: (audience: string, serviceUrl: string) => AuthProvider
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get the OAuth token provider for the agent.
|
|
35
|
+
* @param audience - The audience.
|
|
36
|
+
* @param activity - The activity.
|
|
37
|
+
* @returns An AuthProvider instance.
|
|
38
|
+
*/
|
|
39
|
+
getTokenProviderFromActivity: (audience: string, activity: Activity) => AuthProvider
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get the default connection configuration for the agent.
|
|
43
|
+
* @returns An Auth Configuration.
|
|
44
|
+
*/
|
|
45
|
+
getDefaultConnectionConfiguration: () => AuthConfiguration
|
|
46
|
+
}
|
package/src/auth/index.ts
CHANGED
|
@@ -19,18 +19,37 @@ const logger = debug('agents:jwt-middleware')
|
|
|
19
19
|
* @returns A promise that resolves to the JWT payload.
|
|
20
20
|
*/
|
|
21
21
|
const verifyToken = async (raw: string, config: AuthConfiguration): Promise<JwtPayload> => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const payload = jwt.decode(raw) as JwtPayload
|
|
23
|
+
logger.debug('jwt.decode ', JSON.stringify(payload))
|
|
24
|
+
|
|
25
|
+
if (!payload) {
|
|
26
|
+
throw new Error('invalid token')
|
|
27
|
+
}
|
|
28
|
+
const audience = payload.aud
|
|
29
|
+
|
|
30
|
+
const matchingEntry = config.connections && config.connections.size > 0
|
|
31
|
+
? [...config.connections.entries()].find(([_, configuration]) => configuration.clientId === audience)
|
|
32
|
+
: undefined
|
|
33
|
+
|
|
34
|
+
if (!matchingEntry) {
|
|
35
|
+
const err = new Error('Audience mismatch')
|
|
36
|
+
logger.error(err.message, audience)
|
|
37
|
+
throw err
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const [key, authConfig] = matchingEntry
|
|
41
|
+
logger.debug(`Audience found at key: ${key}`)
|
|
28
42
|
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
const jwksUri = payload.iss === 'https://api.botframework.com'
|
|
44
|
+
? 'https://login.botframework.com/v1/.well-known/keys'
|
|
45
|
+
: `${authConfig.authority}/${authConfig.tenantId}/discovery/v2.0/keys`
|
|
31
46
|
|
|
47
|
+
logger.debug(`fetching keys from ${jwksUri}`)
|
|
48
|
+
const jwksClient: JwksClient = jwksRsa({ jwksUri })
|
|
49
|
+
|
|
50
|
+
const getKey: GetPublicKeyOrSecret = (header: JwtHeader, callback: SignCallback) => {
|
|
32
51
|
jwksClient.getSigningKey(header.kid, (err: Error | null, key: SigningKey | undefined): void => {
|
|
33
|
-
if (err
|
|
52
|
+
if (err) {
|
|
34
53
|
logger.error('jwksClient.getSigningKey ', JSON.stringify(err))
|
|
35
54
|
logger.error(JSON.stringify(err))
|
|
36
55
|
callback(err, undefined)
|
|
@@ -41,24 +60,22 @@ const verifyToken = async (raw: string, config: AuthConfiguration): Promise<JwtP
|
|
|
41
60
|
})
|
|
42
61
|
}
|
|
43
62
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
63
|
+
const verifyOptions: jwt.VerifyOptions = {
|
|
64
|
+
issuer: authConfig.issuers as [string, ...string[]],
|
|
65
|
+
audience: [authConfig.clientId!, 'https://api.botframework.com'],
|
|
66
|
+
ignoreExpiration: false,
|
|
67
|
+
algorithms: ['RS256'],
|
|
68
|
+
clockTolerance: 300
|
|
69
|
+
}
|
|
52
70
|
|
|
71
|
+
return await new Promise((resolve, reject) => {
|
|
53
72
|
jwt.verify(raw, getKey, verifyOptions, (err, user) => {
|
|
54
|
-
if (err
|
|
73
|
+
if (err) {
|
|
55
74
|
logger.error('jwt.verify ', JSON.stringify(err))
|
|
56
75
|
reject(err)
|
|
57
76
|
return
|
|
58
77
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
resolve(tokenClaims)
|
|
78
|
+
resolve(user as JwtPayload)
|
|
62
79
|
})
|
|
63
80
|
})
|
|
64
81
|
}
|