Skip to content

Commit

Permalink
- Add first order broker parameters.
Browse files Browse the repository at this point in the history
- Instrument embedded client id.
  • Loading branch information
konstantin-msft committed Sep 27, 2024
1 parent 471ea55 commit ff65f71
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 19 deletions.
13 changes: 3 additions & 10 deletions lib/msal-browser/src/interaction_client/NativeInteractionClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ import { AuthenticationResult } from "../response/AuthenticationResult.js";
import { base64Decode } from "../encode/Base64Decode.js";
import { version } from "../packageMetadata.js";

const BrokerServerParamKeys = {
BROKER_CLIENT_ID: "brk_client_id",
BROKER_REDIRECT_URI: "brk_redirect_uri",
};

export class NativeInteractionClient extends BaseInteractionClient {
protected apiId: ApiId;
protected accountId: string;
Expand Down Expand Up @@ -1050,20 +1045,18 @@ export class NativeInteractionClient extends BaseInteractionClient {

if (
request.extraParameters.hasOwnProperty(
BrokerServerParamKeys.BROKER_CLIENT_ID
AADServerParamKeys.BROKER_CLIENT_ID
) &&
request.extraParameters.hasOwnProperty(
BrokerServerParamKeys.BROKER_REDIRECT_URI
AADServerParamKeys.BROKER_REDIRECT_URI
) &&
request.extraParameters.hasOwnProperty(AADServerParamKeys.CLIENT_ID)
) {
const child_client_id =
request.extraParameters[AADServerParamKeys.CLIENT_ID];
const child_redirect_uri = request.redirectUri;
const brk_redirect_uri =
request.extraParameters[
BrokerServerParamKeys.BROKER_REDIRECT_URI
];
request.extraParameters[AADServerParamKeys.BROKER_REDIRECT_URI];
request.extraParameters = {
child_client_id,
child_redirect_uri,
Expand Down
30 changes: 25 additions & 5 deletions lib/msal-common/src/client/AuthorizationCodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,13 @@ export class AuthorizationCodeClient extends BaseClient {
request.correlationId
);

const parameterBuilder = new RequestParameterBuilder();
const parameterBuilder = new RequestParameterBuilder(
this.performanceClient
);

parameterBuilder.addClientId(
request.tokenBodyParameters?.[AADServerParamKeys.CLIENT_ID] ||
request.brokerParameters?.embeddedClientId ||
request.tokenBodyParameters?.[AADServerParamKeys.CLIENT_ID] ||
this.config.authOptions.clientId
);

Expand Down Expand Up @@ -493,6 +496,10 @@ export class AuthorizationCodeClient extends BaseClient {
});
}

if (request.brokerParameters) {
parameterBuilder.addBrokerParameters(request.brokerParameters);
}

return parameterBuilder.createQueryString();
}

Expand All @@ -508,10 +515,13 @@ export class AuthorizationCodeClient extends BaseClient {
request.correlationId
);

const parameterBuilder = new RequestParameterBuilder();
const parameterBuilder = new RequestParameterBuilder(
this.performanceClient
);

parameterBuilder.addClientId(
request.extraQueryParameters?.[AADServerParamKeys.CLIENT_ID] ||
request.brokerParameters?.embeddedClientId ||
request.extraQueryParameters?.[AADServerParamKeys.CLIENT_ID] ||
this.config.authOptions.clientId
);

Expand Down Expand Up @@ -674,6 +684,10 @@ export class AuthorizationCodeClient extends BaseClient {
);
}

if (request.brokerParameters) {
parameterBuilder.addBrokerParameters(request.brokerParameters);
}

this.addExtraQueryParams(request, parameterBuilder);

if (request.nativeBroker) {
Expand Down Expand Up @@ -714,7 +728,9 @@ export class AuthorizationCodeClient extends BaseClient {
private createLogoutUrlQueryString(
request: CommonEndSessionRequest
): string {
const parameterBuilder = new RequestParameterBuilder();
const parameterBuilder = new RequestParameterBuilder(
this.performanceClient
);

if (request.postLogoutRedirectUri) {
parameterBuilder.addPostLogoutRedirectUri(
Expand All @@ -738,6 +754,10 @@ export class AuthorizationCodeClient extends BaseClient {
parameterBuilder.addLogoutHint(request.logoutHint);
}

if (request.brokerParameters) {
parameterBuilder.addBrokerParameters(request.brokerParameters);
}

this.addExtraQueryParams(request, parameterBuilder);

return parameterBuilder.createQueryString();
Expand Down
8 changes: 7 additions & 1 deletion lib/msal-common/src/client/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,13 @@ export abstract class BaseClient {
* @param request
*/
createTokenQueryParameters(request: BaseAuthRequest): string {
const parameterBuilder = new RequestParameterBuilder();
const parameterBuilder = new RequestParameterBuilder(
this.performanceClient
);

if (request.brokerParameters) {
parameterBuilder.addBrokerParameters(request.brokerParameters);
}

if (request.tokenQueryParameters) {
parameterBuilder.addExtraQueryParameters(
Expand Down
11 changes: 9 additions & 2 deletions lib/msal-common/src/client/RefreshTokenClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,13 @@ export class RefreshTokenClient extends BaseClient {
);

const correlationId = request.correlationId;
const parameterBuilder = new RequestParameterBuilder();
const parameterBuilder = new RequestParameterBuilder(
this.performanceClient
);

parameterBuilder.addClientId(
request.tokenBodyParameters?.[AADServerParamKeys.CLIENT_ID] ||
request.brokerParameters?.embeddedClientId ||
request.tokenBodyParameters?.[AADServerParamKeys.CLIENT_ID] ||
this.config.authOptions.clientId
);

Expand Down Expand Up @@ -478,6 +481,10 @@ export class RefreshTokenClient extends BaseClient {
);
}

if (request.brokerParameters) {
parameterBuilder.addBrokerParameters(request.brokerParameters);
}

return parameterBuilder.createQueryString();
}
}
2 changes: 2 additions & 0 deletions lib/msal-common/src/constants/AADServerParamKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ export const SID = "sid";
export const LOGIN_HINT = "login_hint";
export const DOMAIN_HINT = "domain_hint";
export const X_CLIENT_EXTRA_SKU = "x-client-xtra-sku";
export const BROKER_CLIENT_ID = "brk_client_id";
export const BROKER_REDIRECT_URI = "brk_redirect_uri";
3 changes: 3 additions & 0 deletions lib/msal-common/src/request/BaseAuthRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AzureCloudOptions } from "../config/ClientConfiguration.js";
import { StringDict } from "../utils/MsalTypes.js";
import { StoreInCache } from "./StoreInCache.js";
import { ShrOptions } from "../crypto/SignedHttpRequest.js";
import { BrokerParameters } from "./BrokerParameters.js";

/**
* BaseAuthRequest
Expand All @@ -29,6 +30,7 @@ import { ShrOptions } from "../crypto/SignedHttpRequest.js";
* - storeInCache - Object containing boolean values indicating whether to store tokens in the cache or not (default is true)
* - scenarioId - Scenario id to track custom user prompts
* - popKid - Key ID to identify the public key for PoP token request
* - brokerParameters - Broker parameters
*/
export type BaseAuthRequest = {
authority: string;
Expand All @@ -50,4 +52,5 @@ export type BaseAuthRequest = {
storeInCache?: StoreInCache;
scenarioId?: string;
popKid?: string;
brokerParameters?: BrokerParameters;
};
16 changes: 16 additions & 0 deletions lib/msal-common/src/request/BrokerParameters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

/**
* Broker parameters
*/
export type BrokerParameters = {
// Embedded client id
embeddedClientId: string;
// Broker client id
brokerClientId: string;
// Broker redirect URI
brokerRedirectUri: string;
};
3 changes: 3 additions & 0 deletions lib/msal-common/src/request/CommonEndSessionRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { AccountInfo } from "../account/AccountInfo.js";
import { StringDict } from "../utils/MsalTypes.js";
import { BrokerParameters } from "./BrokerParameters.js";

/**
* CommonEndSessionRequest
Expand All @@ -15,6 +16,7 @@ import { StringDict } from "../utils/MsalTypes.js";
* - state - A value included in the request to the logout endpoint which will be returned in the query string upon post logout redirection
* - logoutHint - A string that specifies the account that is being logged out in order to skip the server account picker on logout
* - extraQueryParameters - String to string map of custom query parameters added to the /authorize call
* - brokerParameters - Broker parameters
*/
export type CommonEndSessionRequest = {
correlationId: string;
Expand All @@ -24,4 +26,5 @@ export type CommonEndSessionRequest = {
state?: string;
logoutHint?: string;
extraQueryParameters?: StringDict;
brokerParameters?: BrokerParameters;
};
35 changes: 34 additions & 1 deletion lib/msal-common/src/request/RequestParameterBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ import {
} from "../config/ClientConfiguration.js";
import { ServerTelemetryManager } from "../telemetry/server/ServerTelemetryManager.js";
import { ClientInfo } from "../account/ClientInfo.js";
import { IPerformanceClient } from "../telemetry/performance/IPerformanceClient.js";
import { BrokerParameters } from "./BrokerParameters.js";

/** @internal */
export class RequestParameterBuilder {
private parameters: Map<string, string>;
private readonly performanceClient?: IPerformanceClient;

constructor() {
constructor(performanceClient?: IPerformanceClient) {
this.parameters = new Map<string, string>();
this.performanceClient = performanceClient;
}

/**
Expand Down Expand Up @@ -608,6 +612,35 @@ export class RequestParameterBuilder {
queryParameterArray.push(`${key}=${value}`);
});

const correlationId = this.parameters.get(
AADServerParamKeys.CLIENT_REQUEST_ID
);
const clientId = this.parameters.get(AADServerParamKeys.CLIENT_ID);

if (
this.parameters.has(AADServerParamKeys.BROKER_CLIENT_ID) &&
clientId &&
correlationId
) {
this.performanceClient?.addFields(
{
embeddedClientId: clientId,
},
correlationId
);
}

return queryParameterArray.join("&");
}

addBrokerParameters(params: BrokerParameters): void {
const brokerParams: StringDict = {};
brokerParams[AADServerParamKeys.BROKER_CLIENT_ID] =
params.brokerClientId;
brokerParams[AADServerParamKeys.BROKER_REDIRECT_URI] =
params.brokerRedirectUri;

this.addClientId(params.embeddedClientId);
this.addExtraQueryParameters(brokerParams);
}
}
2 changes: 2 additions & 0 deletions lib/msal-common/src/telemetry/performance/PerformanceEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,8 @@ export type PerformanceEvent = {
* @type {string}
*/
retryError?: string;

embeddedClientId?: string;
};

export type PerformanceEventContext = {
Expand Down
54 changes: 54 additions & 0 deletions lib/msal-common/test/client/AuthorizationCodeClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4028,6 +4028,33 @@ describe("AuthorizationCodeClient unit tests", () => {

expect(queryString).toContain(`instance_aware=false`);
});

it("pick up broker params", async () => {
const config: ClientConfiguration =
await ClientTestUtils.createTestClientConfiguration();
const client = new AuthorizationCodeClient(config);

const queryString =
// @ts-ignore
await client.createAuthCodeUrlQueryString({
scopes: ["User.Read"],
redirectUri: "localhost",
brokerParameters: {
embeddedClientId: "child_client_id_1",
brokerClientId: "broker_client_id",
brokerRedirectUri: "broker_redirect_uri",
},
extraQueryParameters: {
client_id: "child_client_id_2",
},
});

expect(queryString).toContain(`client_id=child_client_id_1`);
expect(queryString).toContain(`brk_client_id=broker_client_id`);
expect(queryString).toContain(
`brk_redirect_uri=broker_redirect_uri`
);
});
});

describe("createTokenRequestBody tests", () => {
Expand Down Expand Up @@ -4065,5 +4092,32 @@ describe("AuthorizationCodeClient unit tests", () => {

expect(queryString).toContain(`client_id=child_client_id`);
});

it("pick up broker params", async () => {
const config: ClientConfiguration =
await ClientTestUtils.createTestClientConfiguration();
const client = new AuthorizationCodeClient(config);

const queryString =
// @ts-ignore
await client.createTokenRequestBody({
scopes: ["User.Read"],
redirectUri: "localhost",
brokerParameters: {
embeddedClientId: "child_client_id_1",
brokerClientId: "broker_client_id",
brokerRedirectUri: "broker_redirect_uri",
},
tokenBodyParameters: {
client_id: "child_client_id_2",
},
});

expect(queryString).toContain(`client_id=child_client_id_1`);
expect(queryString).toContain(`brk_client_id=broker_client_id`);
expect(queryString).toContain(
`brk_redirect_uri=broker_redirect_uri`
);
});
});
});
29 changes: 29 additions & 0 deletions lib/msal-common/test/client/RefreshTokenClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1509,4 +1509,33 @@ describe("RefreshTokenClient unit tests", () => {
).toBe(false);
});
});

describe("createTokenRequestBody tests", () => {
it("pick up broker params", async () => {
const config: ClientConfiguration =
await ClientTestUtils.createTestClientConfiguration();
const client = new RefreshTokenClient(config);

const queryString =
// @ts-ignore
await client.createTokenRequestBody({
scopes: ["User.Read"],
redirectUri: "localhost",
brokerParameters: {
embeddedClientId: "child_client_id_1",
brokerClientId: "broker_client_id",
brokerRedirectUri: "broker_redirect_uri",
},
tokenBodyParameters: {
client_id: "child_client_id_2",
},
});

expect(queryString).toContain(`client_id=child_client_id_1`);
expect(queryString).toContain(`brk_client_id=broker_client_id`);
expect(queryString).toContain(
`brk_redirect_uri=broker_redirect_uri`
);
});
});
});
Loading

0 comments on commit ff65f71

Please sign in to comment.