Skip to content

Commit

Permalink
[identity] Add consumer_passthrough support to MSALClient and improve…
Browse files Browse the repository at this point in the history
… logging (#29390)

### Packages impacted by this PR

@azure/identity

### Issues associated with this PR

Resolves #28872

### Describe the problem that is addressed by this PR

Two things are addressed in this PR:

1. Complete porting over the logic for MSAL broker plugin to MSALClient
by adding support for legacyMSAPassthrough
2. Improve logging for MSALClient and establish some patterns
  • Loading branch information
maorleger committed Apr 22, 2024
1 parent de9dc04 commit e0dc8c2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
27 changes: 22 additions & 5 deletions sdk/identity/identity/src/msal/nodeFlows/msalClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,17 @@ export function createMsalClient(

let confidentialClientApp = confidentialApps.get(appKey);
if (confidentialClientApp) {
msalLogger.getToken.info(
"Existing ConfidentialClientApplication found in cache, returning it.",
);
return confidentialClientApp;
}

// Initialize a new app and cache it
msalLogger.getToken.info(
`Creating new ConfidentialClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`,
);

const cachePlugin = options.enableCae
? state.pluginConfiguration.cache.cachePluginCae
: state.pluginConfiguration.cache.cachePlugin;
Expand All @@ -207,6 +214,9 @@ export function createMsalClient(
options: GetTokenOptions = {},
): Promise<msal.AuthenticationResult> {
if (state.cachedAccount === null) {
msalLogger.getToken.info(
"No cached account found in local state, attempting to load it from MSAL cache.",
);
const cache = app.getTokenCache();
const accounts = await cache.getAllAccounts();

Expand All @@ -231,14 +241,21 @@ To work with multiple accounts for the same Client ID and Tenant ID, please prov
state.cachedClaims = options.claims;
}

// TODO: port over changes for broker
// https://github.com/Azure/azure-sdk-for-js/blob/727a7208251961b5036d8e1d86edaa944c42e3d6/sdk/identity/identity/src/msal/nodeFlows/msalNodeCommon.ts#L383-L395
msalLogger.getToken.info("Attempting to acquire token silently");
return app.acquireTokenSilent({
const silentRequest: msal.SilentFlowRequest = {
account: state.cachedAccount,
scopes,
claims: state.cachedClaims,
});
};

if (state.pluginConfiguration.broker.isEnabled) {
silentRequest.tokenQueryParameters ||= {};
if (state.pluginConfiguration.broker.enableMsaPassthrough) {
silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
}
}

msalLogger.getToken.info("Attempting to acquire token silently");
return app.acquireTokenSilent(silentRequest);
}

/**
Expand Down
23 changes: 22 additions & 1 deletion sdk/identity/identity/src/msal/nodeFlows/msalPlugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,36 @@ export interface PluginConfiguration {
* Configuration for the cache plugin.
*/
cache: {
/**
* The non-CAE cache plugin handler.
*/
cachePlugin?: Promise<msalNode.ICachePlugin>;
/**
* The CAE cache plugin handler - persisted to a different file.
*/
cachePluginCae?: Promise<msalNode.ICachePlugin>;
};
/**
* Configuration for the broker plugin.
*/
broker: {
/**
* True if the broker plugin is enabled and available. False otherwise.
*
* It is a bug if this is true and the broker plugin is not available.
*/
isEnabled: boolean;
/**
* If true, MSA account will be passed through, required for WAM authentication.
*/
enableMsaPassthrough: boolean;
/**
* The parent window handle for the broker.
*/
parentWindowHandle?: Uint8Array;
/**
* The native broker plugin handler.
*/
nativeBrokerPlugin?: msalNode.INativeBrokerPlugin;
};
}
Expand Down Expand Up @@ -86,6 +107,7 @@ function generatePluginConfiguration(options: MsalClientOptions): PluginConfigur
const config: PluginConfiguration = {
cache: {},
broker: {
isEnabled: options.brokerOptions?.enabled ?? false,
enableMsaPassthrough: options.brokerOptions?.legacyEnableMsaPassthrough ?? false,
parentWindowHandle: options.brokerOptions?.parentWindowHandle,
},
Expand Down Expand Up @@ -125,7 +147,6 @@ function generatePluginConfiguration(options: MsalClientOptions): PluginConfigur
].join(" "),
);
}

config.broker.nativeBrokerPlugin = nativeBrokerInfo!.broker;
}

Expand Down
2 changes: 2 additions & 0 deletions sdk/identity/identity/test/internal/node/msalClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ describe("MsalClient", function () {

sandbox.stub(msalPlugins, "generatePluginConfiguration").returns({
broker: {
isEnabled: false,
enableMsaPassthrough: false,
},
cache: {
Expand Down Expand Up @@ -187,6 +188,7 @@ describe("MsalClient", function () {

sandbox.stub(msalPlugins, "generatePluginConfiguration").returns({
broker: {
isEnabled: false,
enableMsaPassthrough: false,
},
cache: {
Expand Down
2 changes: 2 additions & 0 deletions sdk/identity/identity/test/internal/node/msalPlugins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe("#generatePluginConfiguration", function () {
const expected: PluginConfiguration = {
cache: {},
broker: {
isEnabled: false,
enableMsaPassthrough: false,
parentWindowHandle: undefined,
},
Expand Down Expand Up @@ -104,6 +105,7 @@ describe("#generatePluginConfiguration", function () {
assert.strictEqual(result.broker.nativeBrokerPlugin, nativeBrokerPlugin);
assert.strictEqual(result.broker.enableMsaPassthrough, true);
assert.strictEqual(result.broker.parentWindowHandle, parentWindowHandle);
assert.strictEqual(result.broker.isEnabled, true);
});
});
});

0 comments on commit e0dc8c2

Please sign in to comment.