-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Verify SSO Capability #8252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Verify SSO Capability #8252
Changes from 13 commits
311fc3f
632c393
0a2f5e1
eb8df76
ef600d9
fa1c809
b0eac1a
4565ab7
f1fff9d
b14dbe8
7626e80
e9a32f7
7f283d7
64de352
4ee54c0
1e24dcb
827a6ff
e0f6b03
cd804d1
28cbf36
d29ef3d
6e7f446
03a70d4
4e6c400
6eac154
68d2fa1
0cb5c03
d0f410c
a5dce88
efa1b30
e3eb0ab
6b770c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "patch", | ||
| "comment": "Add a background ssoSilent call after interactive calls, with telemetry, [#8252](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/8252) ", | ||
| "packageName": "@azure/msal-browser", | ||
| "email": "sameera.gajjarapu@microsoft.com", | ||
| "dependentChangeType": "patch" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "patch", | ||
| "comment": "Add a background ssoSilent call after interactive calls, with telemetry, [#8252](https://github.com/AzureAD/microsoft-authentication-library-for-js/pull/8252)", | ||
sameerag marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "packageName": "@azure/msal-common", | ||
| "email": "sameera.gajjarapu@microsoft.com", | ||
| "dependentChangeType": "patch" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ import { | |
| ProtocolMode, | ||
| CommonAuthorizationUrlRequest, | ||
| HttpMethod, | ||
| AuthorizeProtocol, | ||
| } from "@azure/msal-common/browser"; | ||
| import { StandardInteractionClient } from "./StandardInteractionClient.js"; | ||
| import { BrowserConfiguration } from "../config/Configuration.js"; | ||
|
|
@@ -349,6 +350,141 @@ export class SilentIframeClient extends StandardInteractionClient { | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Refreshes the session by making an iframe request to /authorize without exchanging the code for tokens. | ||
| * This is useful for refreshing session cookies in the background without the overhead of a full token exchange. | ||
sameerag marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * @param request - The SSO silent request | ||
| * @returns true if the session was refreshed successfully with a valid authorization code, false otherwise | ||
| */ | ||
| async refreshSession(request: SsoSilentRequest): Promise<boolean> { | ||
sameerag marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| this.performanceClient.addQueueMeasurement( | ||
| PerformanceEvents.SilentIframeClientAcquireToken, | ||
sameerag marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| request.correlationId | ||
| ); | ||
|
|
||
| const inputRequest = { ...request }; | ||
| if (!inputRequest.prompt) { | ||
| inputRequest.prompt = PromptValue.NONE; | ||
| } | ||
|
|
||
| // Create silent request | ||
| const silentRequest: CommonAuthorizationUrlRequest = await invokeAsync( | ||
| this.initializeAuthorizationRequest.bind(this), | ||
| PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, | ||
| this.logger, | ||
| this.performanceClient, | ||
| request.correlationId | ||
| )(inputRequest, InteractionType.Silent); | ||
|
|
||
| const authClient = await invokeAsync( | ||
| this.createAuthCodeClient.bind(this), | ||
| PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, | ||
| this.logger, | ||
| this.performanceClient, | ||
| request.correlationId | ||
| )({ | ||
| serverTelemetryManager: this.initializeServerTelemetryManager( | ||
| this.apiId | ||
| ), | ||
| requestAuthority: silentRequest.authority, | ||
| requestAzureCloudOptions: silentRequest.azureCloudOptions, | ||
| requestExtraQueryParameters: silentRequest.extraQueryParameters, | ||
| account: silentRequest.account, | ||
| }); | ||
|
|
||
| const correlationId = silentRequest.correlationId; | ||
| const pkceCodes = await invokeAsync( | ||
| generatePkceCodes, | ||
| PerformanceEvents.GeneratePkceCodes, | ||
| this.logger, | ||
| this.performanceClient, | ||
| correlationId | ||
| )(this.performanceClient, this.logger, correlationId); | ||
|
|
||
| const requestWithPkce = { | ||
| ...silentRequest, | ||
| codeChallenge: pkceCodes.challenge, | ||
| }; | ||
|
|
||
| // Create authorize request url | ||
| const navigateUrl = await invokeAsync( | ||
| Authorize.getAuthCodeRequestUrl, | ||
| PerformanceEvents.GetAuthCodeUrl, | ||
| this.logger, | ||
| this.performanceClient, | ||
| correlationId | ||
| )( | ||
| this.config, | ||
| authClient.authority, | ||
| requestWithPkce, | ||
| this.logger, | ||
| this.performanceClient | ||
| ); | ||
|
|
||
| // Get the frame handle for the silent request - this triggers the session refresh | ||
| const msalFrame = await invokeAsync( | ||
| initiateCodeRequest, | ||
| PerformanceEvents.SilentHandlerInitiateAuthRequest, | ||
| this.logger, | ||
| this.performanceClient, | ||
| correlationId | ||
| )( | ||
| navigateUrl, | ||
| this.performanceClient, | ||
| this.logger, | ||
| correlationId, | ||
| this.config.system.navigateFrameWait | ||
| ); | ||
|
|
||
| const responseType = this.config.auth.OIDCOptions.serverResponseType; | ||
| // Monitor the iframe for the response | ||
| const responseString = await invokeAsync( | ||
| monitorIframeForHash, | ||
| PerformanceEvents.SilentHandlerMonitorIframeForHash, | ||
| this.logger, | ||
| this.performanceClient, | ||
| correlationId | ||
| )( | ||
| msalFrame, | ||
| this.config.system.iframeHashTimeout, | ||
| this.config.system.pollIntervalMilliseconds, | ||
| this.performanceClient, | ||
| this.logger, | ||
| correlationId, | ||
| responseType | ||
| ); | ||
|
|
||
| // Deserialize the response | ||
| const serverParams = invoke( | ||
| ResponseHandler.deserializeResponse, | ||
| PerformanceEvents.DeserializeResponse, | ||
| this.logger, | ||
| this.performanceClient, | ||
| correlationId | ||
| )(responseString, responseType, this.logger); | ||
|
|
||
| // Validate the response - this checks for errors and validates state | ||
| AuthorizeProtocol.validateAuthorizationResponse( | ||
| serverParams, | ||
| silentRequest.state | ||
| ); | ||
|
|
||
| // Verify a valid authorization code is present | ||
| if (!serverParams.code) { | ||
| this.logger.warning( | ||
| "Session refresh response did not contain an authorization code", | ||
| correlationId | ||
| ); | ||
| return false; | ||
sameerag marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| this.logger.verbose( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we factor out the shared code with ssoSilent? Any distinct PerformanceEvent names/log messages can be parameterized. I'd rather we not have 2 sources of truth for the iframe flow.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No shared code w.r.t events. Can you clarify what exactly you mean? |
||
| "Session refresh completed successfully with valid authorization code - skipped token exchange", | ||
| correlationId | ||
| ); | ||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Currently Unsupported | ||
| */ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.