Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Add support for authorize call using method POST #7920",
"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 support for authorize call using method POST #7920",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
247 changes: 180 additions & 67 deletions lib/msal-browser/src/interaction_client/PopupClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
initializeServerTelemetryManager,
} from "./BaseInteractionClient.js";
import { monitorPopupForHash } from "../utils/PopupUtils.js";
import { validateRequestMethod } from "../request/RequestHelpers.js";

export type PopupParams = {
popup?: Window | null;
Expand Down Expand Up @@ -107,12 +108,13 @@ export class PopupClient extends StandardInteractionClient {
request: PopupRequest,
pkceCodes?: PkceCodes
): Promise<AuthenticationResult> {
let popupParams: PopupParams | undefined = undefined;
try {
const popupName = this.generatePopupName(
request.scopes || Constants.OIDC_DEFAULT_SCOPES,
request.authority || this.config.auth.authority
);
const popupParams: PopupParams = {
popupParams = {
popupName,
popupWindowAttributes: request.popupWindowAttributes || {},
popupWindowParent: request.popupWindowParent ?? window,
Expand All @@ -136,6 +138,16 @@ export class PopupClient extends StandardInteractionClient {
);
} else {
// navigatePopups flag is set to true. Opens popup before acquiring token.

// Pre-validate request method to avoid opening popup if the request is invalid
const validatedRequest: PopupRequest = {
...request,
httpMethod: validateRequestMethod(
request,
this.config.system.protocolMode
),
};

this.logger.verbose(
"navigatePopups set to true, opening popup before acquiring token"
);
Expand All @@ -144,7 +156,7 @@ export class PopupClient extends StandardInteractionClient {
popupParams
);
return this.acquireTokenPopupAsync(
request,
validatedRequest,
popupParams,
pkceCodes
);
Expand Down Expand Up @@ -312,75 +324,84 @@ export class PopupClient extends StandardInteractionClient {
account: popupRequest.account,
});

// Create acquire token url.
const navigateUrl = await invokeAsync(
Authorize.getAuthCodeRequestUrl,
PerformanceEvents.GetAuthCodeUrl,
this.logger,
this.performanceClient,
correlationId
)(
this.config,
authClient.authority,
popupRequest,
this.logger,
this.performanceClient
);
if (popupRequest.httpMethod === Constants.HttpMethod.POST) {
return await this.executeCodeFlowWithPost(
popupRequest,
popupParams,
authClient,
pkce.verifier
);
} else {
// Create acquire token url.
const navigateUrl = await invokeAsync(
Authorize.getAuthCodeRequestUrl,
PerformanceEvents.GetAuthCodeUrl,
this.logger,
this.performanceClient,
correlationId
)(
this.config,
authClient.authority,
popupRequest,
this.logger,
this.performanceClient
);

// Show the UI once the url has been created. Get the window handle for the popup.
const popupWindow: Window = this.initiateAuthRequest(
navigateUrl,
popupParams
);
this.eventHandler.emitEvent(
EventType.POPUP_OPENED,
InteractionType.Popup,
{ popupWindow },
null
);
// Show the UI once the url has been created. Get the window handle for the popup.
const popupWindow: Window = this.initiateAuthRequest(
navigateUrl,
popupParams
);
this.eventHandler.emitEvent(
EventType.POPUP_OPENED,
InteractionType.Popup,
{ popupWindow },
null
);

// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
const responseString = await monitorPopupForHash(
popupWindow,
popupParams.popupWindowParent,
this.config.auth.OIDCOptions.responseMode,
this.config.system.pollIntervalMilliseconds,
this.logger,
this.unloadWindow
);
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
const responseString = await monitorPopupForHash(
popupWindow,
popupParams.popupWindowParent,
this.config.auth.OIDCOptions.responseMode,
this.config.system.pollIntervalMilliseconds,
this.logger,
this.unloadWindow
);

const serverParams = invoke(
ResponseHandler.deserializeResponse,
BrowserPerformanceEvents.DeserializeResponse,
this.logger,
this.performanceClient,
this.correlationId
)(
responseString,
this.config.auth.OIDCOptions.responseMode,
this.logger
);
const serverParams = invoke(
ResponseHandler.deserializeResponse,
BrowserPerformanceEvents.DeserializeResponse,
this.logger,
this.performanceClient,
this.correlationId
)(
responseString,
this.config.auth.OIDCOptions.responseMode,
this.logger
);

return await invokeAsync(
Authorize.handleResponseCode,
BrowserPerformanceEvents.HandleResponseCode,
this.logger,
this.performanceClient,
correlationId
)(
request,
serverParams,
pkce.verifier,
ApiId.acquireTokenPopup,
this.config,
authClient,
this.browserStorage,
this.nativeStorage,
this.eventHandler,
this.logger,
this.performanceClient,
this.platformAuthProvider
);
return await invokeAsync(
Authorize.handleResponseCode,
BrowserPerformanceEvents.HandleResponseCode,
this.logger,
this.performanceClient,
correlationId
)(
request,
serverParams,
pkce.verifier,
ApiId.acquireTokenPopup,
this.config,
authClient,
this.browserStorage,
this.nativeStorage,
this.eventHandler,
this.logger,
this.performanceClient,
this.platformAuthProvider
);
}
} catch (e) {
// Close the synchronous popup if an error is thrown before the window unload event is registered
popupParams.popup?.close();
Expand Down Expand Up @@ -496,6 +517,98 @@ export class PopupClient extends StandardInteractionClient {
);
}

async executeCodeFlowWithPost(
request: CommonAuthorizationUrlRequest,
popupParams: PopupParams,
authClient: AuthorizationCodeClient,
pkceVerifier: string
): Promise<AuthenticationResult> {
const correlationId = request.correlationId;
// Get the frame handle for the silent request
const discoveredAuthority = await invokeAsync(
getDiscoveredAuthority,
BrowserPerformanceEvents.StandardInteractionClientGetDiscoveredAuthority,
this.logger,
this.performanceClient,
correlationId
)(
{
requestAuthority: request.authority,
requestAzureCloudOptions: request.azureCloudOptions,
requestExtraQueryParameters: request.extraQueryParameters,
account: request.account,
},
this.config,
this.correlationId,
this.performanceClient,
this.browserStorage,
this.logger
);

const popupWindow =
popupParams.popup || this.openPopup("about:blank", popupParams);

const form = await Authorize.getCodeForm(
popupWindow.document,
this.config,
discoveredAuthority,
request,
this.logger,
this.performanceClient
);

form.submit();

// Monitor the popup for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
const responseString = await invokeAsync(
monitorPopupForHash,
BrowserPerformanceEvents.SilentHandlerMonitorIframeForHash,
this.logger,
this.performanceClient,
correlationId
)(
popupWindow,
popupParams.popupWindowParent,
this.config.auth.OIDCOptions.responseMode,
this.config.system.pollIntervalMilliseconds,
this.logger,
this.unloadWindow
);

const serverParams = invoke(
ResponseHandler.deserializeResponse,
BrowserPerformanceEvents.DeserializeResponse,
this.logger,
this.performanceClient,
this.correlationId
)(
responseString,
this.config.auth.OIDCOptions.responseMode,
this.logger
);

return invokeAsync(
Authorize.handleResponseCode,
BrowserPerformanceEvents.HandleResponseCode,
this.logger,
this.performanceClient,
correlationId
)(
request,
serverParams,
pkceVerifier,
ApiId.acquireTokenPopup,
this.config,
authClient,
this.browserStorage,
this.nativeStorage,
this.eventHandler,
this.logger,
this.performanceClient,
this.platformAuthProvider
);
}

/**
*
* @param validRequest
Expand Down
Loading
Loading