Skip to content

Commit

Permalink
Add first order broker parameters (#7348)
Browse files Browse the repository at this point in the history
- Add first order embedded client id parameter.
- Instrument embedded client id and embedded redirect uri.
- Default redirect uri to the current page in auth config.
  • Loading branch information
konstantin-msft authored Oct 16, 2024
1 parent 278647a commit 09066cc
Show file tree
Hide file tree
Showing 30 changed files with 544 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Add first order broker parameters #7348",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Add first order broker parameters #7348",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Add first order broker parameters #7348",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "patch"
}
2 changes: 1 addition & 1 deletion lib/msal-browser/apiReview/msal-browser.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1714,7 +1714,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU];
// src/app/PublicClientNext.ts:85:79 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// src/app/PublicClientNext.ts:88:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/app/PublicClientNext.ts:89:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/config/Configuration.ts:245:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts
// src/config/Configuration.ts:246:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts
// src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@"
// src/index.ts:8:4 - (tsdoc-undefined-tag) The TSDoc tag "@module" is not defined in this configuration
// src/navigation/NavigationClient.ts:36:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
Expand Down
1 change: 1 addition & 0 deletions lib/msal-browser/src/broker/nativeBroker/NativeRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type NativeTokenRequest = {
extraParameters?: StringDict;
storeInCache?: StoreInCache; // Object of booleans indicating whether to store tokens in the cache or not (default is true)
signPopToken?: boolean; // Set to true only if token request deos not contain a PoP keyId
embeddedClientId?: string;
};

/**
Expand Down
4 changes: 3 additions & 1 deletion lib/msal-browser/src/config/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import { INavigationClient } from "../navigation/INavigationClient.js";
import { NavigationClient } from "../navigation/NavigationClient.js";
import { FetchClient } from "../network/FetchClient.js";
import * as BrowserUtils from "../utils/BrowserUtils.js";

// Default timeout for popup windows and iframes in milliseconds
export const DEFAULT_POPUP_TIMEOUT_MS = 60000;
Expand Down Expand Up @@ -273,7 +274,8 @@ export function buildConfiguration(
knownAuthorities: [],
cloudDiscoveryMetadata: Constants.EMPTY_STRING,
authorityMetadata: Constants.EMPTY_STRING,
redirectUri: Constants.EMPTY_STRING,
redirectUri:
typeof window !== "undefined" ? BrowserUtils.getCurrentUri() : "",
postLogoutRedirectUri: Constants.EMPTY_STRING,
navigateToLoginRequestUrl: true,
clientCapabilities: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,7 @@ export abstract class BaseInteractionClient {
*/
getRedirectUri(requestRedirectUri?: string): string {
this.logger.verbose("getRedirectUri called");
const redirectUri =
requestRedirectUri ||
this.config.auth.redirectUri ||
BrowserUtils.getCurrentUri();
const redirectUri = requestRedirectUri || this.config.auth.redirectUri;
return UrlString.getAbsoluteUrl(
redirectUri,
BrowserUtils.getCurrentUri()
Expand Down
60 changes: 35 additions & 25 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 @@ -1044,31 +1039,46 @@ export class NativeInteractionClient extends BaseInteractionClient {
* @private
*/
private handleExtraBrokerParams(request: NativeTokenRequest): void {
if (!request.extraParameters) {
return;
}

if (
const hasExtraBrokerParams =
request.extraParameters &&
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.hasOwnProperty(
AADServerParamKeys.CLIENT_ID
);

if (!request.embeddedClientId && !hasExtraBrokerParams) {
return;
}

let child_client_id: string = "";
const child_redirect_uri = request.redirectUri;

if (request.embeddedClientId) {
request.redirectUri = this.config.auth.redirectUri;
child_client_id = request.embeddedClientId;
} else if (request.extraParameters) {
request.redirectUri =
request.extraParameters[AADServerParamKeys.BROKER_REDIRECT_URI];
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 = {
child_client_id,
child_redirect_uri,
};
request.redirectUri = brk_redirect_uri;
}

request.extraParameters = {
child_client_id,
child_redirect_uri,
};

this.performanceClient?.addFields(
{
embeddedClientId: child_client_id,
embeddedRedirectUri: child_redirect_uri,
},
request.correlationId
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ export abstract class StandardInteractionClient extends BaseInteractionClient {
clientId: this.config.auth.clientId,
authority: discoveredAuthority,
clientCapabilities: this.config.auth.clientCapabilities,
redirectUri: this.config.auth.redirectUri,
},
systemOptions: {
tokenRenewalOffsetSeconds:
Expand Down
9 changes: 4 additions & 5 deletions lib/msal-browser/src/naa/mapping/NestedAppAuthAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export class NestedAppAuthAdapter {
);
}

const requestBuilder = new RequestParameterBuilder();
const correlationId =
request.correlationId || this.crypto.createNewGuid();
const requestBuilder = new RequestParameterBuilder(correlationId);
const claims = requestBuilder.addClientCapabilitiesToClaims(
request.claims,
this.clientCapabilities
Expand All @@ -83,10 +85,7 @@ export class NestedAppAuthAdapter {
clientId: this.clientId,
authority: request.authority,
scope: scopes.join(" "),
correlationId:
request.correlationId !== undefined
? request.correlationId
: this.crypto.createNewGuid(),
correlationId,
claims: !StringUtils.isEmptyObj(claims) ? claims : undefined,
state: request.state,
authenticationScheme:
Expand Down
2 changes: 1 addition & 1 deletion lib/msal-browser/test/config/Configuration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("Configuration.ts Class Unit Tests", () => {
expect(emptyConfig.auth.authority).toBe(
`${Constants.DEFAULT_AUTHORITY}`
);
expect(emptyConfig.auth.redirectUri).toBe("");
expect(emptyConfig.auth.redirectUri).toBeDefined();
expect(emptyConfig.auth.postLogoutRedirectUri).toBe("");
expect(emptyConfig.auth.navigateToLoginRequestUrl).toBe(true);
expect(emptyConfig.auth?.azureCloudOptions?.azureCloudInstance).toBe(
Expand Down
31 changes: 26 additions & 5 deletions lib/msal-common/apiReview/msal-common.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ declare namespace AADServerParamKeys {
SID,
LOGIN_HINT,
DOMAIN_HINT,
X_CLIENT_EXTRA_SKU
X_CLIENT_EXTRA_SKU,
BROKER_CLIENT_ID,
BROKER_REDIRECT_URI
}
}
export { AADServerParamKeys }
Expand Down Expand Up @@ -355,6 +357,7 @@ export const AuthErrorMessage: {
export type AuthOptions = {
clientId: string;
authority: Authority;
redirectUri: string;
clientCapabilities?: Array<string>;
azureCloudOptions?: AzureCloudOptions;
skipAuthorityMetadataCache?: boolean;
Expand Down Expand Up @@ -603,6 +606,7 @@ export type BaseAuthRequest = {
storeInCache?: StoreInCache;
scenarioId?: string;
popKid?: string;
embeddedClientId?: string;
};

// Warning: (ae-internal-missing-underscore) The name "BaseClient" should be prefixed with an underscore because the declaration is marked as @internal
Expand Down Expand Up @@ -647,6 +651,16 @@ export abstract class BaseClient {
// @public (undocumented)
const bindingKeyNotRemoved = "binding_key_not_removed";

// Warning: (ae-missing-release-tag) "BROKER_CLIENT_ID" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
const BROKER_CLIENT_ID = "brk_client_id";

// Warning: (ae-missing-release-tag) "BROKER_REDIRECT_URI" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
const BROKER_REDIRECT_URI = "brk_redirect_uri";

// Warning: (ae-incompatible-release-tags) The symbol "buildAccountToCache" is marked as @public, but its signature references "CacheManager" which is marked as @internal
// Warning: (ae-incompatible-release-tags) The symbol "buildAccountToCache" is marked as @public, but its signature references "Authority" which is marked as @internal
// Warning: (ae-incompatible-release-tags) The symbol "buildAccountToCache" is marked as @public, but its signature references "AccountEntity" which is marked as @internal
Expand Down Expand Up @@ -3045,6 +3059,8 @@ export type PerformanceEvent = {
scenarioId?: string;
accountType?: "AAD" | "MSA" | "B2C";
retryError?: string;
embeddedClientId?: string;
embeddedRedirectUri?: string;
};

// Warning: (tsdoc-undefined-tag) The TSDoc tag "@export" is not defined in this configuration
Expand Down Expand Up @@ -3353,11 +3369,16 @@ const REQUESTED_TOKEN_USE = "requested_token_use";
//
// @internal (undocumented)
export class RequestParameterBuilder {
constructor();
constructor(correlationId?: string, performanceClient?: IPerformanceClient);
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
addApplicationTelemetry(appTelemetry: ApplicationTelemetry): void;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
addAuthorizationCode(code: string): void;
// (undocumented)
addBrokerParameters(params: {
brokerClientId: string;
brokerRedirectUri: string;
}): void;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
addCcsOid(clientInfo: ClientInfo): void;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
Expand Down Expand Up @@ -4263,9 +4284,9 @@ const X_MS_LIB_CAPABILITY = "x-ms-lib-capability";
// src/client/AuthorizationCodeClient.ts:228:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:229:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:307:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:501:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:712:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:769:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:512:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:735:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/AuthorizationCodeClient.ts:795:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/RefreshTokenClient.ts:193:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/RefreshTokenClient.ts:277:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/client/RefreshTokenClient.ts:278:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
Expand Down
46 changes: 36 additions & 10 deletions lib/msal-common/src/client/AuthorizationCodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,14 @@ export class AuthorizationCodeClient extends BaseClient {
request.correlationId
);

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

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

Expand Down Expand Up @@ -474,6 +478,13 @@ export class AuthorizationCodeClient extends BaseClient {
}
}

if (request.embeddedClientId) {
parameterBuilder.addBrokerParameters({
brokerClientId: this.config.authOptions.clientId,
brokerRedirectUri: this.config.authOptions.redirectUri,
});
}

if (request.tokenBodyParameters) {
parameterBuilder.addExtraQueryParameters(
request.tokenBodyParameters
Expand Down Expand Up @@ -503,15 +514,24 @@ export class AuthorizationCodeClient extends BaseClient {
private async createAuthCodeUrlQueryString(
request: CommonAuthorizationUrlRequest
): Promise<string> {
// generate the correlationId if not set by the user and add
const correlationId =
request.correlationId ||
this.config.cryptoInterface.createNewGuid();

this.performanceClient?.addQueueMeasurement(
PerformanceEvents.AuthClientCreateQueryString,
request.correlationId
correlationId
);

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

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

Expand All @@ -524,10 +544,6 @@ export class AuthorizationCodeClient extends BaseClient {
// validate the redirectUri (to be a non null value)
parameterBuilder.addRedirectUri(request.redirectUri);

// generate the correlationId if not set by the user and add
const correlationId =
request.correlationId ||
this.config.cryptoInterface.createNewGuid();
parameterBuilder.addCorrelationId(correlationId);

// add response_mode. If not passed in it defaults to query.
Expand Down Expand Up @@ -674,6 +690,13 @@ export class AuthorizationCodeClient extends BaseClient {
);
}

if (request.embeddedClientId) {
parameterBuilder.addBrokerParameters({
brokerClientId: this.config.authOptions.clientId,
brokerRedirectUri: this.config.authOptions.redirectUri,
});
}

this.addExtraQueryParams(request, parameterBuilder);

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

if (request.postLogoutRedirectUri) {
parameterBuilder.addPostLogoutRedirectUri(
Expand Down
12 changes: 11 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,17 @@ export abstract class BaseClient {
* @param request
*/
createTokenQueryParameters(request: BaseAuthRequest): string {
const parameterBuilder = new RequestParameterBuilder();
const parameterBuilder = new RequestParameterBuilder(
request.correlationId,
this.performanceClient
);

if (request.embeddedClientId) {
parameterBuilder.addBrokerParameters({
brokerClientId: this.config.authOptions.clientId,
brokerRedirectUri: this.config.authOptions.redirectUri,
});
}

if (request.tokenQueryParameters) {
parameterBuilder.addExtraQueryParameters(
Expand Down
Loading

0 comments on commit 09066cc

Please sign in to comment.