Skip to content
Closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Adjust InjectionToken<T> usage so that properly-typed tokens can be used with new `inject(TOKEN)` syntax.",
"packageName": "@azure/msal-angular",
"email": "[email protected]",
"dependentChangeType": "major"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Fix expires_in format & double brokering errors #7646",
"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": "Refactor /authorize request generation",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "encodeURIComponent during QS generation",
"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": "Refactor /authorize request generation",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "Test changes",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "none"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Refactor /authorize request generation",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "patch"
}
20 changes: 12 additions & 8 deletions lib/msal-angular/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
*/

import { InjectionToken } from "@angular/core";
import { type IPublicClientApplication } from "@azure/msal-browser";
import { type MsalBroadcastConfiguration } from "./msal.broadcast.config";
import { type MsalGuardConfiguration } from "./msal.guard.config";
import { type MsalInterceptorConfiguration } from "./msal.interceptor.config";

export const MSAL_INSTANCE = new InjectionToken<string>("MSAL_INSTANCE");
export const MSAL_INSTANCE = new InjectionToken<IPublicClientApplication>(
"MSAL_INSTANCE"
);

export const MSAL_GUARD_CONFIG = new InjectionToken<string>(
export const MSAL_GUARD_CONFIG = new InjectionToken<MsalGuardConfiguration>(
"MSAL_GUARD_CONFIG"
);

export const MSAL_INTERCEPTOR_CONFIG = new InjectionToken<string>(
"MSAL_INTERCEPTOR_CONFIG"
);
export const MSAL_INTERCEPTOR_CONFIG =
new InjectionToken<MsalInterceptorConfiguration>("MSAL_INTERCEPTOR_CONFIG");

export const MSAL_BROADCAST_CONFIG = new InjectionToken<string>(
"MSAL_BROADCAST_CONFIG"
);
export const MSAL_BROADCAST_CONFIG =
new InjectionToken<MsalBroadcastConfiguration>("MSAL_BROADCAST_CONFIG");
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,15 @@ export class NativeInteractionClient extends BaseInteractionClient {
nativeAccountId: request.accountId,
})?.homeAccountId;

// add exception for double brokering, please note this is temporary and will be fortified in future
if (
request.extraParameters?.child_client_id &&
response.account.id !== request.accountId
) {
this.logger.info(
"handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch"
);
} else if (
homeAccountIdentifier !== cachedhomeAccountId &&
response.account.id !== request.accountId
) {
Expand All @@ -525,6 +533,9 @@ export class NativeInteractionClient extends BaseInteractionClient {
this.logger
);

// Ensure expires_in is in number format
response.expires_in = Number(response.expires_in);

// generate authenticationResult
const result = await this.generateAuthenticationResult(
response,
Expand Down
61 changes: 40 additions & 21 deletions lib/msal-browser/src/interaction_client/PopupClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import { PopupWindowAttributes } from "../request/PopupWindowAttributes.js";
import { EventError } from "../event/EventMessage.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
import * as ResponseHandler from "../response/ResponseHandler.js";
import { getAuthCodeRequestUrl } from "../protocol/Authorize.js";
import { generatePkceCodes } from "../crypto/PkceGenerator.js";

export type PopupParams = {
popup?: Window | null;
Expand Down Expand Up @@ -217,6 +219,17 @@ export class PopupClient extends StandardInteractionClient {
this.correlationId
)(request, InteractionType.Popup);

const pkce =
pkceCodes ||
(await invokeAsync(
generatePkceCodes,
PerformanceEvents.GeneratePkceCodes,
this.logger,
this.performanceClient,
this.correlationId
)(this.performanceClient, this.logger, this.correlationId));
validRequest.codeChallenge = pkce.challenge;

/*
* Skip pre-connect for async popups to reduce time between user interaction and popup window creation to avoid
* popup from being blocked by browsers with shorter popup timers
Expand All @@ -226,16 +239,6 @@ export class PopupClient extends StandardInteractionClient {
}

try {
// Create auth code request and generate PKCE params
const authCodeRequest: CommonAuthorizationCodeRequest =
await invokeAsync(
this.initializeAuthorizationCodeRequest.bind(this),
PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
this.logger,
this.performanceClient,
this.correlationId
)(validRequest, pkceCodes);

// Initialize the client
const authClient: AuthorizationCodeClient = await invokeAsync(
this.createAuthCodeClient.bind(this),
Expand Down Expand Up @@ -269,16 +272,19 @@ export class PopupClient extends StandardInteractionClient {
}

// Create acquire token url.
const navigateUrl = await authClient.getAuthCodeUrl({
...validRequest,
platformBroker: isPlatformBroker,
});

// Create popup interaction handler.
const interactionHandler = new InteractionHandler(
authClient,
this.browserStorage,
authCodeRequest,
const navigateUrl = await invokeAsync(
getAuthCodeRequestUrl,
PerformanceEvents.GetAuthCodeUrl,
this.logger,
this.performanceClient,
validRequest.correlationId
)(
this.config,
authClient.authority,
{
...validRequest,
platformBroker: isPlatformBroker,
},
this.logger,
this.performanceClient
);
Expand Down Expand Up @@ -316,7 +322,7 @@ export class PopupClient extends StandardInteractionClient {
ThrottlingUtils.removeThrottle(
this.browserStorage,
this.config.auth.clientId,
authCodeRequest
validRequest
);

if (serverParams.accountId) {
Expand Down Expand Up @@ -361,6 +367,19 @@ export class PopupClient extends StandardInteractionClient {
});
}

const authCodeRequest: CommonAuthorizationCodeRequest = {
...validRequest,
code: serverParams.code || "",
codeVerifier: pkce.verifier,
};
// Create popup interaction handler.
const interactionHandler = new InteractionHandler(
authClient,
this.browserStorage,
authCodeRequest,
this.logger,
this.performanceClient
);
// Handle response from hash string.
const result = await interactionHandler.handleCodeResponse(
serverParams,
Expand Down
63 changes: 41 additions & 22 deletions lib/msal-browser/src/interaction_client/RedirectClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
ServerTelemetryManager,
Constants,
ProtocolUtils,
ServerAuthorizationCodeResponse,
AuthorizeResponse,
ThrottlingUtils,
ICrypto,
Logger,
Expand Down Expand Up @@ -48,6 +48,8 @@ import { INavigationClient } from "../navigation/INavigationClient.js";
import { EventError } from "../event/EventMessage.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
import * as ResponseHandler from "../response/ResponseHandler.js";
import { getAuthCodeRequestUrl } from "../protocol/Authorize.js";
import { generatePkceCodes } from "../crypto/PkceGenerator.js";

function getNavigationType(): NavigationTimingType | undefined {
if (
Expand Down Expand Up @@ -107,6 +109,15 @@ export class RedirectClient extends StandardInteractionClient {
this.correlationId
)(request, InteractionType.Redirect);

const pkceCodes = await invokeAsync(
generatePkceCodes,
PerformanceEvents.GeneratePkceCodes,
this.logger,
this.performanceClient,
this.correlationId
)(this.performanceClient, this.logger, this.correlationId);
validRequest.codeChallenge = pkceCodes.challenge;

this.browserStorage.updateCacheEntries(
validRequest.state,
validRequest.nonce,
Expand All @@ -133,16 +144,6 @@ export class RedirectClient extends StandardInteractionClient {
};

try {
// Create auth code request and generate PKCE params
const authCodeRequest: CommonAuthorizationCodeRequest =
await invokeAsync(
this.initializeAuthorizationCodeRequest.bind(this),
PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
this.logger,
this.performanceClient,
this.correlationId
)(validRequest);

// Initialize the client
const authClient: AuthorizationCodeClient = await invokeAsync(
this.createAuthCodeClient.bind(this),
Expand All @@ -158,6 +159,11 @@ export class RedirectClient extends StandardInteractionClient {
account: validRequest.account,
});

const authCodeRequest: CommonAuthorizationCodeRequest = {
...validRequest,
code: "", // Will get filled in after the redirect
codeVerifier: pkceCodes.verifier,
};
// Create redirect interaction handler.
const interactionHandler = new RedirectHandler(
authClient,
Expand All @@ -168,15 +174,28 @@ export class RedirectClient extends StandardInteractionClient {
);

// Create acquire token url.
const navigateUrl = await authClient.getAuthCodeUrl({
...validRequest,
platformBroker: NativeMessageHandler.isPlatformBrokerAvailable(
this.config,
this.logger,
this.nativeMessageHandler,
request.authenticationScheme
),
});
const navigateUrl = await invokeAsync(
getAuthCodeRequestUrl,
PerformanceEvents.GetAuthCodeUrl,
this.logger,
this.performanceClient,
validRequest.correlationId
)(
this.config,
authClient.authority,
{
...validRequest,
platformBroker:
NativeMessageHandler.isPlatformBrokerAvailable(
this.config,
this.logger,
this.nativeMessageHandler,
request.authenticationScheme
),
},
this.logger,
this.performanceClient
);

const redirectStartPage = this.getRedirectStartPage(
request.redirectStartPage
Expand Down Expand Up @@ -373,7 +392,7 @@ export class RedirectClient extends StandardInteractionClient {
*/
protected getRedirectResponse(
userProvidedResponse: string
): [ServerAuthorizationCodeResponse | null, string] {
): [AuthorizeResponse | null, string] {
this.logger.verbose("getRedirectResponseHash called");
// Get current location hash from window or cache.
let responseString = userProvidedResponse;
Expand Down Expand Up @@ -439,7 +458,7 @@ export class RedirectClient extends StandardInteractionClient {
* @param state
*/
protected async handleResponse(
serverParams: ServerAuthorizationCodeResponse,
serverParams: AuthorizeResponse,
serverTelemetryManager: ServerTelemetryManager
): Promise<AuthenticationResult> {
const state = serverParams.state;
Expand Down
Loading