Skip to content

EAR Protocol Request #7633

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

Merged
merged 59 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
4e0640c
refactor RequestParameterBuilder
tnorling Mar 7, 2025
fadb3e1
restore broker param instrumentation
tnorling Mar 7, 2025
bbefb65
tests
tnorling Mar 7, 2025
729df91
Change files
tnorling Mar 7, 2025
e3bf806
refactor authorize url generation
tnorling Mar 7, 2025
6b405da
update browser tests
tnorling Mar 7, 2025
a90272d
common tests
tnorling Mar 8, 2025
c0f3d52
node tests
tnorling Mar 8, 2025
4f2b4f8
lint
tnorling Mar 8, 2025
e89b373
Merge branch 'refactor-request-generation' of https://github.com/Azur…
tnorling Mar 8, 2025
e38ab31
EAR request generation
tnorling Mar 11, 2025
bb33316
Add EAR protocol mode
tnorling Mar 11, 2025
a299d4e
temporarily omit EAR from accepted config type
tnorling Mar 11, 2025
11ef5c3
Merge branch 'dev' into refactor-request-generation
tnorling Mar 11, 2025
28c0910
add response_type
tnorling Mar 11, 2025
20172a6
update tests
tnorling Mar 11, 2025
c24b58b
merge dev
tnorling Mar 11, 2025
425f6bf
Merge branch 'protocol' of https://github.com/AzureAD/microsoft-authe…
tnorling Mar 11, 2025
9391ebb
add response properties
tnorling Mar 11, 2025
b4956c5
move response handling
tnorling Mar 11, 2025
5317fe2
formatting
tnorling Mar 11, 2025
adf96fd
Merge branch 'refactor-request-generation' of https://github.com/Azur…
tnorling Mar 11, 2025
a2ccb5a
merge from dev
tnorling Mar 11, 2025
2e496f2
Fix failing test
tnorling Mar 12, 2025
88ecb87
Merge branch 'refactor-request-generation' of https://github.com/Azur…
tnorling Mar 12, 2025
d5a5778
Merge branch 'protocol' of https://github.com/AzureAD/microsoft-authe…
tnorling Mar 12, 2025
1566554
format
tnorling Mar 12, 2025
188a472
Merge branch 'refactor-request-generation' of https://github.com/Azur…
tnorling Mar 12, 2025
1fb8f16
Merge branch 'protocol' of https://github.com/AzureAD/microsoft-authe…
tnorling Mar 12, 2025
8926fab
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Mar 12, 2025
6a0ddab
Change files
tnorling Mar 12, 2025
131d812
apiExtractor
tnorling Mar 12, 2025
5c39eec
Merge branch 'protocol' into ear-protocol
tnorling Mar 12, 2025
569cf57
rework code request generation
tnorling Mar 12, 2025
48b2829
telemetry
tnorling Mar 12, 2025
1c834b8
Merge branch 'protocol' of https://github.com/AzureAD/microsoft-authe…
tnorling Mar 12, 2025
62a9ab2
apiExtractor and lint
tnorling Mar 12, 2025
fb57c07
Merge branch 'protocol' of https://github.com/AzureAD/microsoft-authe…
tnorling Mar 12, 2025
872a060
Fix test
tnorling Mar 13, 2025
90f81c1
Fix test
tnorling Mar 13, 2025
08750fa
Merge branch 'protocol' of https://github.com/AzureAD/microsoft-authe…
tnorling Mar 13, 2025
3d7ff1e
update AuthorizationUrlRequest
tnorling Mar 13, 2025
5d69ae9
iframe request
tnorling Mar 13, 2025
bdd53f1
formatting
tnorling Mar 14, 2025
ec430a3
EAR request redirect
tnorling Mar 14, 2025
9f27cc2
add refresh token to response type
tnorling Mar 14, 2025
e858990
EAR popup request
tnorling Mar 14, 2025
75c223c
don't encode params during request generation
tnorling Mar 14, 2025
0e7ac52
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Mar 14, 2025
e2f4e10
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Mar 18, 2025
241bba8
tests and apiExtractor
tnorling Mar 18, 2025
62e0e4c
Change files
tnorling Mar 18, 2025
b01840c
fix linter errors
tnorling Mar 18, 2025
ed894dc
Fix node build/test
tnorling Mar 18, 2025
08c8330
Change files
tnorling Mar 18, 2025
a6de878
Merge branch 'dev' into ear-protocol
tnorling Mar 18, 2025
0421963
Merge branch 'dev' into ear-protocol
tnorling Mar 21, 2025
cbb5288
Merge branch 'dev' into ear-protocol
tnorling Mar 21, 2025
ae8d946
Merge branch 'dev' into ear-protocol
tnorling Mar 21, 2025
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": "patch",
"comment": "Fix request type for ssoSilent",
"packageName": "@azure/msal-angular",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "EAR protocol request support",
"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": "EAR protocol request support",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Minor updates to Authorize query string generation",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "patch"
}
4 changes: 2 additions & 2 deletions lib/msal-angular/src/IMsalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

import {
EndSessionRequest,
AuthorizationUrlRequest,
AuthenticationResult,
PopupRequest,
RedirectRequest,
SilentRequest,
Logger,
SsoSilentRequest,
} from "@azure/msal-browser";
import { Observable } from "rxjs";

Expand All @@ -25,7 +25,7 @@ export interface IMsalService {
loginPopup(request?: PopupRequest): Observable<AuthenticationResult>;
loginRedirect(request?: RedirectRequest): Observable<void>;
logout(logoutRequest?: EndSessionRequest): Observable<void>;
ssoSilent(request: AuthorizationUrlRequest): Observable<AuthenticationResult>;
ssoSilent(request: SsoSilentRequest): Observable<AuthenticationResult>;
getLogger(): Logger;
setLogger(logger: Logger): void;
}
19 changes: 11 additions & 8 deletions lib/msal-browser/apiReview/msal-browser.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,8 @@ export type AuthorizationCodeRequest = Partial<Omit<CommonAuthorizationCodeReque

// Warning: (ae-missing-release-tag) "AuthorizationUrlRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type AuthorizationUrlRequest = Omit<CommonAuthorizationUrlRequest, "state" | "nonce" | "requestedClaimsHash" | "platformBroker"> & {
state: string;
nonce: string;
};
// @public @deprecated
export type AuthorizationUrlRequest = Omit<CommonAuthorizationUrlRequest, "requestedClaimsHash" | "platformBroker">;

// Warning: (ae-missing-release-tag) "authRequestNotSetError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down Expand Up @@ -190,6 +187,7 @@ export class BrowserAuthError extends AuthError {
declare namespace BrowserAuthErrorCodes {
export {
pkceNotCreated,
earJwkEmpty,
cryptoNonExistent,
emptyNavigateUri,
hashEmptyError,
Expand Down Expand Up @@ -718,6 +716,11 @@ const databaseUnavailable = "database_unavailable";
// @public (undocumented)
export const DEFAULT_IFRAME_TIMEOUT_MS = 10000;

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

// Warning: (ae-missing-release-tag) "emptyNavigateUri" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -1338,7 +1341,7 @@ export type PopupPosition = {
// Warning: (ae-missing-release-tag) "PopupRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type PopupRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "scopes" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">> & {
export type PopupRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "scopes" | "earJwk" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">> & {
scopes: Array<string>;
popupWindowAttributes?: PopupWindowAttributes;
popupWindowParent?: Window;
Expand Down Expand Up @@ -1595,7 +1598,7 @@ function redirectPreflightCheck(initialized: boolean, config: BrowserConfigurati
// Warning: (ae-missing-release-tag) "RedirectRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type RedirectRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "scopes" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">> & {
export type RedirectRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "scopes" | "earJwk" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">> & {
scopes: Array<string>;
redirectStartPage?: string;
onRedirectNavigate?: (url: string) => boolean | void;
Expand Down Expand Up @@ -1687,7 +1690,7 @@ const spaCodeAndNativeAccountIdPresent = "spa_code_and_nativeAccountId_present";
// Warning: (ae-missing-release-tag) "SsoSilentRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type SsoSilentRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">>;
export type SsoSilentRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "earJwk" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">>;

// Warning: (ae-missing-release-tag) "stateInteractionTypeMismatch" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down
16 changes: 14 additions & 2 deletions lib/msal-browser/src/config/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,10 @@ export function buildConfiguration(
);
}

// Throw an error if user has set allowPlatformBroker to true without being in AAD protocol mode
// Throw an error if user has set allowPlatformBroker to true with OIDC protocol mode
if (
userInputAuth?.protocolMode &&
userInputAuth.protocolMode !== ProtocolMode.AAD &&
userInputAuth.protocolMode === ProtocolMode.OIDC &&
providedSystemOptions?.allowPlatformBroker
) {
throw createClientConfigurationError(
Expand All @@ -402,5 +402,17 @@ export function buildConfiguration(
telemetry: { ...DEFAULT_TELEMETRY_OPTIONS, ...userInputTelemetry },
};

/**
* Temporarily disable EAR until implementation is complete
* TODO: Remove this
*/
if (overlayedConfig.auth.protocolMode === ProtocolMode.EAR) {
const logger = new Logger(providedSystemOptions.loggerOptions);
logger.warning(
"EAR Protocol Mode is not yet supported. Overriding to use PKCE auth"
);
overlayedConfig.auth.protocolMode = ProtocolMode.AAD;
}

return overlayedConfig;
}
2 changes: 2 additions & 0 deletions lib/msal-browser/src/controllers/NestedAppAuthController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ export class NestedAppAuthController implements IController {
CommonAuthorizationUrlRequest,
| "requestedClaimsHash"
| "responseMode"
| "earJwk"
| "codeChallenge"
| "codeChallengeMethod"
| "platformBroker"
Expand Down Expand Up @@ -792,6 +793,7 @@ export class NestedAppAuthController implements IController {
CommonAuthorizationUrlRequest,
| "requestedClaimsHash"
| "responseMode"
| "earJwk"
| "codeChallenge"
| "codeChallengeMethod"
| "platformBroker"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export class UnknownOperatingContextController implements IController {
Omit<
CommonAuthorizationUrlRequest,
| "responseMode"
| "earJwk"
| "codeChallenge"
| "codeChallengeMethod"
| "requestedClaimsHash"
Expand Down Expand Up @@ -293,6 +294,7 @@ export class UnknownOperatingContextController implements IController {
Omit<
CommonAuthorizationUrlRequest,
| "responseMode"
| "earJwk"
| "codeChallenge"
| "codeChallengeMethod"
| "requestedClaimsHash"
Expand Down
18 changes: 17 additions & 1 deletion lib/msal-browser/src/crypto/BrowserCrypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
PerformanceEvents,
} from "@azure/msal-common/browser";
import { KEY_FORMAT_JWK } from "../utils/BrowserConstants.js";
import { urlEncodeArr } from "../encode/Base64Encode.js";
import { base64Encode, urlEncodeArr } from "../encode/Base64Encode.js";
import { base64DecToArr } from "../encode/Base64Decode.js";

/**
Expand Down Expand Up @@ -226,6 +226,22 @@ export async function sign(
) as Promise<ArrayBuffer>;
}

/**
* Generates Base64 encoded jwk used in the Encrypted Authorize Response (EAR) flow
*/
export async function generateEarKey(): Promise<string> {
const key = await generateBaseKey();
const keyStr = urlEncodeArr(new Uint8Array(key));

const jwk = {
alg: "dir",
kty: "oct",
k: keyStr,
};

return base64Encode(JSON.stringify(jwk));
}

/**
* Generates symmetric base encryption key. This may be stored as all encryption/decryption keys will be derived from this one.
*/
Expand Down
2 changes: 2 additions & 0 deletions lib/msal-browser/src/error/BrowserAuthError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const ErrorLink = "For more visit: aka.ms/msaljs/browser-errors";
export const BrowserAuthErrorMessages = {
[BrowserAuthErrorCodes.pkceNotCreated]:
"The PKCE code challenge and verifier could not be generated.",
[BrowserAuthErrorCodes.earJwkEmpty]:
"No EAR encryption key provided. This is unexpected.",
[BrowserAuthErrorCodes.cryptoNonExistent]:
"The crypto object or function is not available.",
[BrowserAuthErrorCodes.emptyNavigateUri]:
Expand Down
1 change: 1 addition & 0 deletions lib/msal-browser/src/error/BrowserAuthErrorCodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

export const pkceNotCreated = "pkce_not_created";
export const earJwkEmpty = "ear_jwk_empty";
export const cryptoNonExistent = "crypto_nonexistent";
export const emptyNavigateUri = "empty_navigate_uri";
export const hashEmptyError = "hash_empty_error";
Expand Down
Loading