mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-31 00:10:04 +08:00
Add new msal-no-broker implementation option to allow for getting rid of classic soon (#263966)
Also, removes the redirectUri from acquireTokenSilent because MSAL was throwing because of it.
This commit is contained in:
committed by
GitHub
parent
c281e3ea7e
commit
7e8f8e9230
@@ -110,10 +110,12 @@
|
||||
"default": "msal",
|
||||
"enum": [
|
||||
"msal",
|
||||
"msal-no-broker",
|
||||
"classic"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"%microsoft-authentication.implementation.enumDescriptions.msal%",
|
||||
"%microsoft-authentication.implementation.enumDescriptions.msal-no-broker%",
|
||||
"%microsoft-authentication.implementation.enumDescriptions.classic%"
|
||||
],
|
||||
"markdownDescription": "%microsoft-authentication.implementation.description%",
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
"signIn": "Sign In",
|
||||
"signOut": "Sign Out",
|
||||
"microsoft-authentication.implementation.description": {
|
||||
"message": "The authentication implementation to use for signing in with a Microsoft account.\n\n*NOTE: The `classic` implementation is deprecated and will be removed, along with this setting, in a future release. If only the `classic` implementation works for you, please [open an issue](command:workbench.action.openIssueReporter) and explain what you are trying to log in to.*",
|
||||
"message": "The authentication implementation to use for signing in with a Microsoft account.\n\n*NOTE: The `classic` implementation is deprecated and will be removed in a future release. If the `msal` implementation does not work for you, please [open an issue](command:workbench.action.openIssueReporter) and explain what you are trying to log in to.*",
|
||||
"comment": [
|
||||
"{Locked='[(command:workbench.action.openIssueReporter)]'}",
|
||||
"The `command:` syntax will turn into a link. Do not translate it."
|
||||
]
|
||||
},
|
||||
"microsoft-authentication.implementation.enumDescriptions.msal": "Use the Microsoft Authentication Library (MSAL) to sign in with a Microsoft account.",
|
||||
"microsoft-authentication.implementation.enumDescriptions.msal-no-broker": "Use the Microsoft Authentication Library (MSAL) to sign in with a Microsoft account using a browser. This is useful if you are having issues with the native broker.",
|
||||
"microsoft-authentication.implementation.enumDescriptions.classic": "(deprecated) Use the classic authentication flow to sign in with a Microsoft account.",
|
||||
"microsoft-sovereign-cloud.environment.description": {
|
||||
"message": "The Sovereign Cloud to use for authentication. If you select `custom`, you must also set the `#microsoft-sovereign-cloud.customEnvironment#` setting.",
|
||||
|
||||
@@ -36,11 +36,22 @@ export class MicrosoftAuthenticationTelemetryReporter implements IExperimentatio
|
||||
);
|
||||
}
|
||||
|
||||
sendActivatedWithClassicImplementationEvent(): void {
|
||||
sendActivatedWithMsalNoBrokerEvent(): void {
|
||||
/* __GDPR__
|
||||
"activatingClassic" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users use the classic login flow." }
|
||||
"activatingMsalNoBroker" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users use the msal-no-broker login flow. This only fires if the user explictly opts in to this." }
|
||||
*/
|
||||
this._telemetryReporter.sendTelemetryEvent('activatingClassic');
|
||||
this._telemetryReporter.sendTelemetryEvent('activatingmsalnobroker');
|
||||
}
|
||||
|
||||
sendActivatedWithClassicImplementationEvent(reason: 'setting' | 'web'): void {
|
||||
/* __GDPR__
|
||||
"activatingClassic" : {
|
||||
"owner": "TylerLeonhardt",
|
||||
"comment": "Used to determine how often users use the classic login flow.",
|
||||
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Why classic was used" },
|
||||
}
|
||||
*/
|
||||
this._telemetryReporter.sendTelemetryEvent('activatingClassic', { reason });
|
||||
}
|
||||
|
||||
sendLoginEvent(scopes: readonly string[]): void {
|
||||
|
||||
@@ -3,60 +3,28 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { commands, env, ExtensionContext, l10n, window, workspace } from 'vscode';
|
||||
import { commands, ExtensionContext, l10n, window, workspace } from 'vscode';
|
||||
import * as extensionV1 from './extensionV1';
|
||||
import * as extensionV2 from './extensionV2';
|
||||
import { createExperimentationService } from './common/experimentation';
|
||||
import { MicrosoftAuthenticationTelemetryReporter } from './common/telemetryReporter';
|
||||
import { IExperimentationService } from 'vscode-tas-client';
|
||||
import Logger from './logger';
|
||||
|
||||
function shouldUseMsal(expService: IExperimentationService): boolean {
|
||||
// First check if there is a setting value to allow user to override the default
|
||||
const inspect = workspace.getConfiguration('microsoft-authentication').inspect<'msal' | 'classic'>('implementation');
|
||||
if (inspect?.workspaceFolderValue !== undefined) {
|
||||
Logger.info(`Acquired MSAL enablement value from 'workspaceFolderValue'. Value: ${inspect.workspaceFolderValue}`);
|
||||
return inspect.workspaceFolderValue === 'msal';
|
||||
}
|
||||
if (inspect?.workspaceValue !== undefined) {
|
||||
Logger.info(`Acquired MSAL enablement value from 'workspaceValue'. Value: ${inspect.workspaceValue}`);
|
||||
return inspect.workspaceValue === 'msal';
|
||||
}
|
||||
if (inspect?.globalValue !== undefined) {
|
||||
Logger.info(`Acquired MSAL enablement value from 'globalValue'. Value: ${inspect.globalValue}`);
|
||||
return inspect.globalValue === 'msal';
|
||||
}
|
||||
let implementation: 'msal' | 'msal-no-broker' | 'classic' = 'msal';
|
||||
const getImplementation = () => workspace.getConfiguration('microsoft-authentication').get<'msal' | 'msal-no-broker' | 'classic'>('implementation') ?? 'msal';
|
||||
|
||||
// Then check if the experiment value
|
||||
const expValue = expService.getTreatmentVariable<boolean>('vscode', 'microsoft.useMsal');
|
||||
if (expValue !== undefined) {
|
||||
Logger.info(`Acquired MSAL enablement value from 'exp'. Value: ${expValue}`);
|
||||
return expValue;
|
||||
}
|
||||
|
||||
Logger.info('Acquired MSAL enablement value from default. Value: true');
|
||||
// If no setting or experiment value is found, default to true
|
||||
return true;
|
||||
}
|
||||
|
||||
let useMsal: boolean | undefined;
|
||||
export async function activate(context: ExtensionContext) {
|
||||
const mainTelemetryReporter = new MicrosoftAuthenticationTelemetryReporter(context.extension.packageJSON.aiKey);
|
||||
const expService = await createExperimentationService(
|
||||
context,
|
||||
mainTelemetryReporter,
|
||||
env.uriScheme !== 'vscode', // isPreRelease
|
||||
);
|
||||
useMsal = shouldUseMsal(expService);
|
||||
implementation = getImplementation();
|
||||
context.subscriptions.push(workspace.onDidChangeConfiguration(async e => {
|
||||
if (!e.affectsConfiguration('microsoft-authentication')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (useMsal === shouldUseMsal(expService)) {
|
||||
if (implementation === getImplementation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow for the migration to be re-attempted if the user switches back to the MSAL implementation
|
||||
context.globalState.update('msalMigration', undefined);
|
||||
|
||||
const reload = l10n.t('Reload');
|
||||
const result = await window.showInformationMessage(
|
||||
'Reload required',
|
||||
@@ -72,17 +40,31 @@ export async function activate(context: ExtensionContext) {
|
||||
}
|
||||
}));
|
||||
const isNodeEnvironment = typeof process !== 'undefined' && typeof process?.versions?.node === 'string';
|
||||
|
||||
// Only activate the new extension if we are not running in a browser environment
|
||||
if (useMsal && isNodeEnvironment) {
|
||||
await extensionV2.activate(context, mainTelemetryReporter);
|
||||
} else {
|
||||
mainTelemetryReporter.sendActivatedWithClassicImplementationEvent();
|
||||
await extensionV1.activate(context, mainTelemetryReporter.telemetryReporter);
|
||||
if (!isNodeEnvironment) {
|
||||
mainTelemetryReporter.sendActivatedWithClassicImplementationEvent('web');
|
||||
return await extensionV1.activate(context, mainTelemetryReporter.telemetryReporter);
|
||||
}
|
||||
|
||||
switch (implementation) {
|
||||
case 'msal-no-broker':
|
||||
mainTelemetryReporter.sendActivatedWithMsalNoBrokerEvent();
|
||||
await extensionV2.activate(context, mainTelemetryReporter);
|
||||
break;
|
||||
case 'classic':
|
||||
mainTelemetryReporter.sendActivatedWithClassicImplementationEvent('setting');
|
||||
await extensionV1.activate(context, mainTelemetryReporter.telemetryReporter);
|
||||
break;
|
||||
case 'msal':
|
||||
default:
|
||||
await extensionV2.activate(context, mainTelemetryReporter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
if (useMsal) {
|
||||
if (implementation !== 'classic') {
|
||||
extensionV2.deactivate();
|
||||
} else {
|
||||
extensionV1.deactivate();
|
||||
|
||||
@@ -484,15 +484,10 @@ export class MsalAuthProvider implements AuthenticationProvider {
|
||||
forceRefresh = true;
|
||||
claims = scopeData.claims;
|
||||
}
|
||||
let redirectUri = DEFAULT_REDIRECT_URI;
|
||||
if (cachedPca.isBrokerAvailable && process.platform === 'darwin') {
|
||||
redirectUri = Config.macOSBrokerRedirectUri;
|
||||
}
|
||||
const result = await cachedPca.acquireTokenSilent({
|
||||
account,
|
||||
authority,
|
||||
scopes: scopeData.scopesToSend,
|
||||
redirectUri,
|
||||
claims,
|
||||
forceRefresh
|
||||
});
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { PublicClientApplication, AccountInfo, SilentFlowRequest, AuthenticationResult, InteractiveRequest, LogLevel, RefreshTokenRequest } from '@azure/msal-node';
|
||||
import { PublicClientApplication, AccountInfo, SilentFlowRequest, AuthenticationResult, InteractiveRequest, LogLevel, RefreshTokenRequest, BrokerOptions } from '@azure/msal-node';
|
||||
import { NativeBrokerPlugin } from '@azure/msal-node-extensions';
|
||||
import { Disposable, SecretStorage, LogOutputChannel, window, ProgressLocation, l10n, EventEmitter } from 'vscode';
|
||||
import { Disposable, SecretStorage, LogOutputChannel, window, ProgressLocation, l10n, EventEmitter, workspace } from 'vscode';
|
||||
import { raceCancellationAndTimeoutError } from '../common/async';
|
||||
import { SecretStorageCachePlugin } from '../common/cachePlugin';
|
||||
import { MsalLoggerOptions } from '../common/loggerOptions';
|
||||
@@ -24,7 +24,7 @@ export class CachedPublicClientApplication implements ICachedPublicClientApplica
|
||||
private readonly _secretStorageCachePlugin: SecretStorageCachePlugin;
|
||||
|
||||
// Broker properties
|
||||
readonly isBrokerAvailable: boolean;
|
||||
readonly isBrokerAvailable: boolean = false;
|
||||
|
||||
//#region Events
|
||||
|
||||
@@ -50,8 +50,15 @@ export class CachedPublicClientApplication implements ICachedPublicClientApplica
|
||||
);
|
||||
|
||||
const loggerOptions = new MsalLoggerOptions(_logger, telemetryReporter);
|
||||
const nativeBrokerPlugin = new NativeBrokerPlugin();
|
||||
this.isBrokerAvailable = nativeBrokerPlugin.isBrokerAvailable;
|
||||
let broker: BrokerOptions | undefined;
|
||||
if (workspace.getConfiguration('microsoft-authentication').get<'msal' | 'msal-no-broker'>('implementation') !== 'msal-no-broker') {
|
||||
const nativeBrokerPlugin = new NativeBrokerPlugin();
|
||||
this.isBrokerAvailable = nativeBrokerPlugin.isBrokerAvailable;
|
||||
this._logger.info(`[${this._clientId}] Native Broker enabled: ${this.isBrokerAvailable}`);
|
||||
broker = { nativeBrokerPlugin };
|
||||
} else {
|
||||
this._logger.info(`[${this._clientId}] Native Broker disabled via settings`);
|
||||
}
|
||||
this._pca = new PublicClientApplication({
|
||||
auth: { clientId: _clientId },
|
||||
system: {
|
||||
@@ -63,7 +70,7 @@ export class CachedPublicClientApplication implements ICachedPublicClientApplica
|
||||
piiLoggingEnabled: true
|
||||
}
|
||||
},
|
||||
broker: { nativeBrokerPlugin },
|
||||
broker,
|
||||
cache: { cachePlugin: this._secretStorageCachePlugin }
|
||||
});
|
||||
this._disposable = Disposable.from(
|
||||
|
||||
Reference in New Issue
Block a user