src/vs/workbench/services/authentication/common/authentication.ts

541 LOC · 507 covered · 34 uncovered · 4 ranges · 2291 concepts · 1 introducers · 1303 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- chatEntitlementService.ts ×52
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 > import { Event } from '../../../../base/common/event.js';
6 > import { IDisposable } from '../../../../base/common/lifecycle.js';
7 > import { IAuthenticationChallenge, IAuthorizationProtectedResourceMetadata, IAuthorizationServerMetadata } from '../../../../base/common/oauth.js';
8 > import { URI } from '../../../../base/common/uri.js';
9 > import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
10 >
11 > /**
12 > * Use this if you don't want the onDidChangeSessions event to fire in the extension host
13 > */
14 > export const INTERNAL_AUTH_PROVIDER_PREFIX = '__';
15 >
16 > export interface AuthenticationSessionAccount {
17 > label: string;
18 > id: string;
19 > }
20 >
21 > export interface AuthenticationSession {
22 > id: string;
23 > accessToken: string;
24 > account: AuthenticationSessionAccount;
25 > scopes: ReadonlyArray<string>;
26 > idToken?: string;
27 > }
28 >
29 > export interface AuthenticationSessionsChangeEvent {
30 > added: ReadonlyArray<AuthenticationSession> | undefined;
31 > removed: ReadonlyArray<AuthenticationSession> | undefined;
32 > changed: ReadonlyArray<AuthenticationSession> | undefined;
33 > }
34 >
35 > export interface AuthenticationProviderInformation {
36 > id: string;
37 > label: string;
38 > authorizationServerGlobs?: ReadonlyArray<string>;
39 > }
40 >
41 > /**
42 > * Options for creating an authentication session via the service.
43 > */
44 > export interface IAuthenticationCreateSessionOptions {
45 > activateImmediate?: boolean;
46 > /**
47 > * The account that is being asked about. If this is passed in, the provider should
48 > * attempt to return the sessions that are only related to this account.
49 > */
50 > account?: AuthenticationSessionAccount;
51 > /**
52 > * The authorization server URI to use for this creation request. If passed in, first we validate that
53 > * the provider can use this authorization server, then it is passed down to the auth provider.
54 > */
55 > authorizationServer?: URI;
56 > /**
57 > * When specified, the authentication provider will request a token bound to this resource URI
58 > * (RFC 8707 resource indicator).
59 > */
60 > resource?: string;
61 > /**
62 > * The audience for the requested access token. Primarily used for OAuth Identity Assertion
63 > * Authorization Grant (ID-JAG, defined in `draft-ietf-oauth-identity-assertion-authz-grant` using RFC 8693 token-exchange semantics) flows where the audience identifies the authorization server of the resource that
64 > * will redeem the assertion (typically the resource's authorization server URL). Providers that do not understand audience-bound tokens should
65 > * ignore this option.
66 > */
67 > audience?: string;
68 > /**
69 > * Allows the authentication provider to take in additional parameters.
70 > * It is up to the provider to define what these parameters are and handle them.
71 > * This is useful for passing in additional information that is specific to the provider
72 > * and not part of the standard authentication flow.
73 > */
74 > [key: string]: any;
75 > }
76 >
77 > export interface IAuthenticationWwwAuthenticateRequest {
78 > /**
79 > * The raw WWW-Authenticate header value that triggered this challenge.
80 > * This will be parsed by the authentication provider to extract the necessary
81 > * challenge information.
82 > */
83 > readonly wwwAuthenticate: string;
84 >
85 > /**
86 > * Optional scopes for the session. If not provided, the authentication provider
87 > * may use default scopes or extract them from the challenge.
88 > */
89 > readonly fallbackScopes?: readonly string[];
90 > }
91 >
92 > export function isAuthenticationWwwAuthenticateRequest(obj: unknown): obj is IAuthenticationWwwAuthenticateRequest {
93 return typeof obj === 'object'
94 && obj !== null
95 && 'wwwAuthenticate' in obj
96 && (typeof obj.wwwAuthenticate === 'string');
97 }
99 > /**
100 > * Represents constraints for authentication, including challenges and optional scopes.
101 > * This is used when creating or retrieving sessions that must satisfy specific authentication
102 > * requirements from WWW-Authenticate headers.
103 > */
104 > export interface IAuthenticationConstraint {
105 > /**
106 > * Array of authentication challenges parsed from WWW-Authenticate headers.
107 > */
108 > readonly challenges: readonly IAuthenticationChallenge[];
109 >
110 > /**
111 > * Optional scopes for the session. If not provided, the authentication provider
112 > * may extract scopes from the challenges or use default scopes.
113 > */
114 > readonly fallbackScopes?: readonly string[];
115 > }
116 >
117 > /**
118 > * Options for getting authentication sessions via the service.
119 > */
120 > export interface IAuthenticationGetSessionsOptions {
121 > /**
122 > * Whether the provider must avoid user interaction while resolving existing sessions.
123 > */
124 > silent?: boolean;
125 > /**
126 > * The account that is being asked about. If this is passed in, the provider should
127 > * attempt to return the sessions that are only related to this account.
128 > */
129 > account?: AuthenticationSessionAccount;
130 > /**
131 > * The authorization server URI to use for this request. If passed in, first we validate that
132 > * the provider can use this authorization server, then it is passed down to the auth provider.
133 > */
134 > authorizationServer?: URI;
135 > /**
136 > * When specified, the authentication provider will request a token bound to this resource URI
137 > * (RFC 8707 resource indicator).
138 > */
139 > resource?: string;
140 > /**
141 > * The audience for the requested access token. Primarily used for OAuth Identity Assertion
142 > * Authorization Grant (ID-JAG, defined in `draft-ietf-oauth-identity-assertion-authz-grant` using RFC 8693 token-exchange semantics) flows where the audience identifies the authorization server of the resource that
143 > * will redeem the assertion (typically the resource's authorization server URL). Providers that do not understand audience-bound tokens should
144 > * ignore this option.
145 > */
146 > audience?: string;
147 > /**
148 > * Allows the authentication provider to take in additional parameters.
149 > * It is up to the provider to define what these parameters are and handle them.
150 > * This is useful for passing in additional information that is specific to the provider
151 > * and not part of the standard authentication flow.
152 > */
153 > [key: string]: any;
154 > }
155 >
156 > export interface AllowedExtension {
157 > id: string;
158 > name: string;
159 > /**
160 > * If true or undefined, the extension is allowed to use the account
161 > * If false, the extension is not allowed to use the account
162 > * TODO: undefined shouldn't be a valid value, but it is for now
163 > */
164 > allowed?: boolean;
165 > lastUsed?: number;
166 > // If true, this comes from the product.json
167 > trusted?: boolean;
168 > }
169 >
170 > export interface IAuthenticationProviderHostDelegate {
171 > /** Priority for this delegate, delegates are tested in descending priority order */
172 > readonly priority: number;
173 > create(authorizationServer: URI, serverMetadata: IAuthorizationServerMetadata, resource: IAuthorizationProtectedResourceMetadata | undefined, clientId?: string, clientSecret?: string): Promise<string>;
174 > /**
175 > * Creates an XAA (enterprise-managed, ID-JAG) authentication provider for the given SSO issuer.
176 > * The returned string is the provider id.
177 > */
178 > createXaa?(issuer: URI): Promise<string>;
179 > }
180 >
181 > export function getDynamicAuthenticationProviderId(authorizationServer: URI, resource: IAuthorizationProtectedResourceMetadata | undefined): string {
182 return resource ? `${authorizationServer.toString(true)} ${resource.resource}` : authorizationServer.toString(true);
183 }
185 > export const IAuthenticationService = createDecorator<IAuthenticationService>('IAuthenticationService');
186 >
187 > export interface IAuthenticationService {
188 > readonly _serviceBrand: undefined;
189 >
190 > /**
191 > * Fires when an authentication provider has been registered
192 > */
193 > readonly onDidRegisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
194 > /**
195 > * Fires when an authentication provider has been unregistered
196 > */
197 > readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
198 >
199 > /**
200 > * Fires when the list of sessions for a provider has been added, removed or changed
201 > */
202 > readonly onDidChangeSessions: Event<{ providerId: string; label: string; event: AuthenticationSessionsChangeEvent }>;
203 >
204 > /**
205 > * Fires when the list of declaredProviders has changed
206 > */
207 > readonly onDidChangeDeclaredProviders: Event<void>;
208 >
209 > /**
210 > * All providers that have been statically declared by extensions. These may not actually be registered or active yet.
211 > */
212 > readonly declaredProviders: AuthenticationProviderInformation[];
213 >
214 > /**
215 > * Registers that an extension has declared an authentication provider in their package.json
216 > * @param provider The provider information to register
217 > */
218 > registerDeclaredAuthenticationProvider(provider: AuthenticationProviderInformation): void;
219 >
220 > /**
221 > * Unregisters a declared authentication provider
222 > * @param id The id of the provider to unregister
223 > */
224 > unregisterDeclaredAuthenticationProvider(id: string): void;
225 >
226 > /**
227 > * Checks if an authentication provider has been registered
228 > * @param id The id of the provider to check
229 > */
230 > isAuthenticationProviderRegistered(id: string): boolean;
231 >
232 > /**
233 > * Checks if an authentication provider is dynamic
234 > * @param id The id of the provider to check
235 > */
236 > isDynamicAuthenticationProvider(id: string): boolean;
237 >
238 > /**
239 > * Registers an authentication provider
240 > * @param id The id of the provider
241 > * @param provider The implementation of the provider
242 > */
243 > registerAuthenticationProvider(id: string, provider: IAuthenticationProvider): void;
244 >
245 > /**
246 > * Unregisters an authentication provider
247 > * @param id The id of the provider to unregister
248 > */
249 > unregisterAuthenticationProvider(id: string): void;
250 >
251 > /**
252 > * Gets the provider ids of all registered authentication providers
253 > */
254 > getProviderIds(): string[];
255 >
256 > /**
257 > * Gets the provider with the given id.
258 > * @param id The id of the provider to get
259 > * @throws if the provider is not registered
260 > */
261 > getProvider(id: string): IAuthenticationProvider;
262 >
263 > /**
264 > * Gets all accounts that are currently logged in across all sessions
265 > * @param id The id of the provider to ask for accounts
266 > * @returns A promise that resolves to an array of accounts
267 > */
268 > getAccounts(id: string): Promise<ReadonlyArray<AuthenticationSessionAccount>>;
269 >
270 > /**
271 > * Gets all sessions that satisfy the given scopes from the provider with the given id
272 > * @param id The id of the provider to ask for a session
273 > * @param scopes The scopes for the session
274 > * @param options Additional options for getting sessions
275 > * @param activateImmediate If true, the provider should activate immediately if it is not already
276 > */
277 > getSessions(id: string, scopeListOrRequest?: ReadonlyArray<string> | IAuthenticationWwwAuthenticateRequest, options?: IAuthenticationGetSessionsOptions, activateImmediate?: boolean): Promise<ReadonlyArray<AuthenticationSession>>;
278 >
279 > /**
280 > * Creates an AuthenticationSession with the given provider and scopes
281 > * @param providerId The id of the provider
282 > * @param scopes The scopes to request
283 > * @param options Additional options for creating the session
284 > */
285 > createSession(providerId: string, scopeListOrRequest: ReadonlyArray<string> | IAuthenticationWwwAuthenticateRequest, options?: IAuthenticationCreateSessionOptions): Promise<AuthenticationSession>;
286 >
287 > /**
288 > * Removes the session with the given id from the provider with the given id
289 > * @param providerId The id of the provider
290 > * @param sessionId The id of the session to remove
291 > */
292 > removeSession(providerId: string, sessionId: string): Promise<void>;
293 >
294 > /**
295 > * Gets a provider id for a specified authorization server
296 > * @param authorizationServer The authorization server url that this provider is responsible for
297 > * @param resourceServer The resource server URI that should match the provider's resourceServer (if defined)
298 > */
299 > getOrActivateProviderIdForServer(authorizationServer: URI, resourceServer?: URI): Promise<string | undefined>;
300 >
301 > /**
302 > * Allows the ability register a delegate that will be used to start authentication providers
303 > * @param delegate The delegate to register
304 > */
305 > registerAuthenticationProviderHostDelegate(delegate: IAuthenticationProviderHostDelegate): IDisposable;
306 >
307 > /**
308 > * Creates a dynamic authentication provider for the given server metadata
309 > * @param serverMetadata The metadata for the server that is being authenticated against
310 > */
311 > createDynamicAuthenticationProvider(authorizationServer: URI, serverMetadata: IAuthorizationServerMetadata, resourceMetadata: IAuthorizationProtectedResourceMetadata | undefined, clientId?: string, clientSecret?: string): Promise<IAuthenticationProvider | undefined>;
312 >
313 > /**
314 > * Gets or creates a built-in XAA (enterprise-managed, ID-JAG) authentication provider for the given
315 > * SSO issuer. Subsequent calls with the same issuer return the existing provider. The returned id
316 > * can be used with {@link getSessions}/{@link createSession} just like any other provider.
317 > *
318 > * @param issuer The OAuth/OIDC issuer URL (typically read from `mcp.enterpriseManagedAuth.idp`).
319 > */
320 > createOrGetXaaProvider(issuer: URI): Promise<string | undefined>;
321 > }
322 >
323 > export function isAuthenticationSession(thing: unknown): thing is AuthenticationSession {
324 if (typeof thing !== 'object' || !thing) {
325 return false;
326 }
327 const maybe = thing as AuthenticationSession;
328 if (typeof maybe.id !== 'string') {
329 return false;
330 }
331 if (typeof maybe.accessToken !== 'string') {
332 return false;
333 }
334 if (typeof maybe.account !== 'object' || !maybe.account) {
335 return false;
336 }
337 if (typeof maybe.account.label !== 'string') {
338 return false;
339 }
340 if (typeof maybe.account.id !== 'string') {
341 return false;
342 }
343 if (!Array.isArray(maybe.scopes)) {
344 return false;
345 }
346 if (maybe.idToken && typeof maybe.idToken !== 'string') {
347 return false;
348 }
349 return true;
350 }
352 > // TODO: Move this into MainThreadAuthentication
353 > export const IAuthenticationExtensionsService = createDecorator<IAuthenticationExtensionsService>('IAuthenticationExtensionsService');
354 > export interface IAuthenticationExtensionsService {
355 > readonly _serviceBrand: undefined;
356 >
357 > /**
358 > * Fires when an account preference for a specific provider has changed for the specified extensions. Does not fire when:
359 > * * An account preference is removed
360 > * * A session preference is changed (because it's deprecated)
361 > * * A session preference is removed (because it's deprecated)
362 > */
363 > readonly onDidChangeAccountPreference: Event<{ extensionIds: string[]; providerId: string }>;
364 > /**
365 > * Returns the accountName (also known as account.label) to pair with `IAuthenticationAccessService` to get the account preference
366 > * @param providerId The authentication provider id
367 > * @param extensionId The extension id to get the preference for
368 > * @returns The accountName of the preference, or undefined if there is no preference set
369 > */
370 > getAccountPreference(extensionId: string, providerId: string): string | undefined;
371 > /**
372 > * Sets the account preference for the given provider and extension
373 > * @param providerId The authentication provider id
374 > * @param extensionId The extension id to set the preference for
375 > * @param account The account to set the preference to
376 > */
377 > updateAccountPreference(extensionId: string, providerId: string, account: AuthenticationSessionAccount): void;
378 > /**
379 > * Removes the account preference for the given provider and extension
380 > * @param providerId The authentication provider id
381 > * @param extensionId The extension id to remove the preference for
382 > */
383 > removeAccountPreference(extensionId: string, providerId: string): void;
384 > /**
385 > * @deprecated Sets the session preference for the given provider and extension
386 > * @param providerId
387 > * @param extensionId
388 > * @param session
389 > */
390 > updateSessionPreference(providerId: string, extensionId: string, session: AuthenticationSession): void;
391 > /**
392 > * @deprecated Gets the session preference for the given provider and extension
393 > * @param providerId
394 > * @param extensionId
395 > * @param scopes
396 > */
397 > getSessionPreference(providerId: string, extensionId: string, scopes: string[]): string | undefined;
398 > /**
399 > * @deprecated Removes the session preference for the given provider and extension
400 > * @param providerId
401 > * @param extensionId
402 > * @param scopes
403 > */
404 > removeSessionPreference(providerId: string, extensionId: string, scopes: string[]): void;
405 > selectSession(providerId: string, extensionId: string, extensionName: string, scopeListOrRequest: ReadonlyArray<string> | IAuthenticationWwwAuthenticateRequest, possibleSessions: readonly AuthenticationSession[]): Promise<AuthenticationSession>;
406 > requestSessionAccess(providerId: string, extensionId: string, extensionName: string, scopeListOrRequest: ReadonlyArray<string> | IAuthenticationWwwAuthenticateRequest, possibleSessions: readonly AuthenticationSession[]): void;
407 > requestNewSession(providerId: string, scopeListOrRequest: ReadonlyArray<string> | IAuthenticationWwwAuthenticateRequest, extensionId: string, extensionName: string): Promise<void>;
408 > updateNewSessionRequests(providerId: string, addedSessions: readonly AuthenticationSession[]): void;
409 > }
410 >
411 > /**
412 > * Options passed to the authentication provider when asking for sessions.
413 > */
414 > export interface IAuthenticationProviderSessionOptions {
415 > /**
416 > * Whether the provider must avoid user interaction while resolving existing sessions.
417 > */
418 > silent?: boolean;
419 > /**
420 > * The account that is being asked about. If this is passed in, the provider should
421 > * attempt to return the sessions that are only related to this account.
422 > */
423 > account?: AuthenticationSessionAccount;
424 > /**
425 > * The authorization server that is being asked about. If this is passed in, the provider should
426 > * attempt to return sessions that are only related to this authorization server.
427 > */
428 > authorizationServer?: URI;
429 > /**
430 > * When specified, the authentication provider will request a token bound to this resource URI
431 > * (RFC 8707 resource indicator).
432 > */
433 > resource?: string;
434 > /**
435 > * The audience for the requested access token. Primarily used for OAuth Identity Assertion
436 > * Authorization Grant (ID-JAG, defined in `draft-ietf-oauth-identity-assertion-authz-grant` using RFC 8693 token-exchange semantics) flows where the audience identifies the authorization server of the resource that
437 > * will redeem the assertion (typically the resource's authorization server URL). Providers that do not understand audience-bound tokens should
438 > * ignore this option.
439 > */
440 > audience?: string;
441 > /**
442 > * Allows the authentication provider to take in additional parameters.
443 > * It is up to the provider to define what these parameters are and handle them.
444 > * This is useful for passing in additional information that is specific to the provider
445 > * and not part of the standard authentication flow.
446 > */
447 > [key: string]: any;
448 > }
449 >
450 > /**
451 > * Represents an authentication provider.
452 > */
453 > export interface IAuthenticationProvider {
454 > /**
455 > * The unique identifier of the authentication provider.
456 > */
457 > readonly id: string;
458 >
459 > /**
460 > * The display label of the authentication provider.
461 > */
462 > readonly label: string;
463 >
464 > /**
465 > * The resource server URI that this provider is responsible for, if any.
466 > * TODO@TylerLeonhardt: Rather than this being added to the provider, it should be passed in to
467 > * getSessions/createSession/etc... this way we can have providers that handle multiple resource servers.
468 > */
469 > readonly resourceServer?: URI;
470 >
471 > /**
472 > * The resolved authorization servers. These can still contain globs, but should be concrete URIs
473 > */
474 > readonly authorizationServers?: ReadonlyArray<URI>;
475 >
476 > /**
477 > * Indicates whether the authentication provider supports multiple accounts.
478 > */
479 > readonly supportsMultipleAccounts: boolean;
480 >
481 > /**
482 > * Optional function to provide a custom confirmation message for authentication prompts.
483 > * If not implemented, the default confirmation messages will be used.
484 > * @param extensionName - The name of the extension requesting authentication.
485 > * @param recreatingSession - Whether this is recreating an existing session.
486 > * @returns A custom confirmation message or undefined to use the default message.
487 > */
488 > readonly confirmation?: (extensionName: string, recreatingSession: boolean) => string | undefined;
489 >
490 > /**
491 > * An {@link Event} which fires when the array of sessions has changed, or data
492 > * within a session has changed.
493 > */
494 > readonly onDidChangeSessions: Event<AuthenticationSessionsChangeEvent>;
495 >
496 > /**
497 > * Retrieves a list of authentication sessions.
498 > * @param scopes - An optional list of scopes. If provided, the sessions returned should match these permissions, otherwise all sessions should be returned.
499 > * @param options - Additional options for getting sessions.
500 > * @returns A promise that resolves to an array of authentication sessions.
501 > */
502 > getSessions(scopes: string[] | undefined, options: IAuthenticationProviderSessionOptions): Promise<readonly AuthenticationSession[]>;
503 >
504 > /**
505 > * Prompts the user to log in.
506 > * If login is successful, the `onDidChangeSessions` event should be fired.
507 > * If login fails, a rejected promise should be returned.
508 > * If the provider does not support multiple accounts, this method should not be called if there is already an existing session matching the provided scopes.
509 > * @param scopes - A list of scopes that the new session should be created with.
510 > * @param options - Additional options for creating the session.
511 > * @returns A promise that resolves to an authentication session.
512 > */
513 > createSession(scopes: string[], options: IAuthenticationProviderSessionOptions): Promise<AuthenticationSession>;
514 >
515 > /**
516 > * Get existing sessions that match the given authentication constraints.
517 > *
518 > * @param constraint The authentication constraint containing challenges and optional scopes
519 > * @param options Options for the session request
520 > * @returns A thenable that resolves to an array of existing authentication sessions
521 > */
522 > getSessionsFromChallenges?(constraint: IAuthenticationConstraint, options: IAuthenticationProviderSessionOptions): Promise<readonly AuthenticationSession[]>;
523 >
524 > /**
525 > * Create a new session based on authentication constraints.
526 > * This is called when no existing session matches the constraint requirements.
527 > *
528 > * @param constraint The authentication constraint containing challenges and optional scopes
529 > * @param options Options for the session creation
530 > * @returns A thenable that resolves to a new authentication session
531 > */
532 > createSessionFromChallenges?(constraint: IAuthenticationConstraint, options: IAuthenticationProviderSessionOptions): Promise<AuthenticationSession>;
533 >
534 > /**
535 > * Removes the session corresponding to the specified session ID.
536 > * If the removal is successful, the `onDidChangeSessions` event should be fired.
537 > * If a session cannot be removed, the provider should reject with an error message.
538 > * @param sessionId - The ID of the session to remove.
539 > */
540 > removeSession(sessionId: string): Promise<void>;
541 > }