@azure/identity 4.7.1-alpha.20250218.5 → 4.7.1-alpha.20250220.3
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +3 -1
- package/dist/browser/credentials/interactiveBrowserCredential-browser.d.mts.map +1 -1
- package/dist/browser/credentials/interactiveBrowserCredential-browser.mjs.map +1 -1
- package/dist/browser/credentials/interactiveBrowserCredential.d.ts +1 -1
- package/dist/browser/credentials/interactiveBrowserCredential.js +5 -5
- package/dist/browser/credentials/usernamePasswordCredential-browser.d.mts.map +1 -1
- package/dist/browser/credentials/usernamePasswordCredential-browser.mjs.map +1 -1
- package/dist/browser/credentials/usernamePasswordCredential.d.ts +2 -0
- package/dist/browser/credentials/usernamePasswordCredential.js +2 -0
- package/dist/browser/msal/browserFlows/msalBrowserCommon.d.ts +10 -97
- package/dist/browser/msal/browserFlows/msalBrowserCommon.d.ts.map +1 -1
- package/dist/browser/msal/browserFlows/msalBrowserCommon.js +235 -60
- package/dist/browser/msal/browserFlows/msalBrowserCommon.js.map +1 -1
- package/dist/browser/msal/browserFlows/msalBrowserOptions.d.ts +87 -0
- package/dist/browser/msal/browserFlows/msalBrowserOptions.d.ts.map +1 -0
- package/dist/{esm/msal/browserFlows/flows.js → browser/msal/browserFlows/msalBrowserOptions.js} +1 -1
- package/dist/browser/msal/browserFlows/msalBrowserOptions.js.map +1 -0
- package/dist/commonjs/credentials/usernamePasswordCredential.d.ts +2 -0
- package/dist/commonjs/credentials/usernamePasswordCredential.d.ts.map +1 -1
- package/dist/commonjs/credentials/usernamePasswordCredential.js +2 -0
- package/dist/commonjs/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist/commonjs/msal/browserFlows/msalBrowserCommon.d.ts +10 -97
- package/dist/commonjs/msal/browserFlows/msalBrowserCommon.d.ts.map +1 -1
- package/dist/commonjs/msal/browserFlows/msalBrowserCommon.js +237 -63
- package/dist/commonjs/msal/browserFlows/msalBrowserCommon.js.map +1 -1
- package/dist/commonjs/msal/browserFlows/msalBrowserOptions.d.ts +87 -0
- package/dist/commonjs/msal/browserFlows/msalBrowserOptions.d.ts.map +1 -0
- package/dist/commonjs/msal/browserFlows/{flows.js → msalBrowserOptions.js} +1 -1
- package/dist/commonjs/msal/browserFlows/msalBrowserOptions.js.map +1 -0
- package/dist/commonjs/tsdoc-metadata.json +1 -1
- package/dist/esm/credentials/usernamePasswordCredential.d.ts +2 -0
- package/dist/esm/credentials/usernamePasswordCredential.d.ts.map +1 -1
- package/dist/esm/credentials/usernamePasswordCredential.js +2 -0
- package/dist/esm/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist/esm/msal/browserFlows/msalBrowserCommon.d.ts +10 -97
- package/dist/esm/msal/browserFlows/msalBrowserCommon.d.ts.map +1 -1
- package/dist/esm/msal/browserFlows/msalBrowserCommon.js +235 -60
- package/dist/esm/msal/browserFlows/msalBrowserCommon.js.map +1 -1
- package/dist/esm/msal/browserFlows/msalBrowserOptions.d.ts +87 -0
- package/dist/esm/msal/browserFlows/msalBrowserOptions.d.ts.map +1 -0
- package/dist/{browser/msal/browserFlows/flows.js → esm/msal/browserFlows/msalBrowserOptions.js} +1 -1
- package/dist/esm/msal/browserFlows/msalBrowserOptions.js.map +1 -0
- package/package.json +2 -2
- package/dist/browser/msal/browserFlows/flows.d.ts +0 -42
- package/dist/browser/msal/browserFlows/flows.d.ts.map +0 -1
- package/dist/browser/msal/browserFlows/flows.js.map +0 -1
- package/dist/browser/msal/browserFlows/msalAuthCode.d.ts +0 -48
- package/dist/browser/msal/browserFlows/msalAuthCode.d.ts.map +0 -1
- package/dist/browser/msal/browserFlows/msalAuthCode.js +0 -203
- package/dist/browser/msal/browserFlows/msalAuthCode.js.map +0 -1
- package/dist/commonjs/msal/browserFlows/flows.d.ts +0 -42
- package/dist/commonjs/msal/browserFlows/flows.d.ts.map +0 -1
- package/dist/commonjs/msal/browserFlows/flows.js.map +0 -1
- package/dist/commonjs/msal/browserFlows/msalAuthCode.d.ts +0 -48
- package/dist/commonjs/msal/browserFlows/msalAuthCode.d.ts.map +0 -1
- package/dist/commonjs/msal/browserFlows/msalAuthCode.js +0 -208
- package/dist/commonjs/msal/browserFlows/msalAuthCode.js.map +0 -1
- package/dist/esm/msal/browserFlows/flows.d.ts +0 -42
- package/dist/esm/msal/browserFlows/flows.d.ts.map +0 -1
- package/dist/esm/msal/browserFlows/flows.js.map +0 -1
- package/dist/esm/msal/browserFlows/msalAuthCode.d.ts +0 -48
- package/dist/esm/msal/browserFlows/msalAuthCode.d.ts.map +0 -1
- package/dist/esm/msal/browserFlows/msalAuthCode.js +0 -203
- package/dist/esm/msal/browserFlows/msalAuthCode.js.map +0 -1
@@ -1,106 +1,19 @@
|
|
1
|
-
import type
|
2
|
-
import type { AccessToken
|
3
|
-
import type { AuthenticationRecord
|
4
|
-
import type { CredentialLogger } from "../../util/logging.js";
|
5
|
-
import type { MsalFlow, MsalFlowOptions } from "./flows.js";
|
6
|
-
import type { BrowserLoginStyle } from "../../credentials/interactiveBrowserCredentialOptions.js";
|
1
|
+
import type { MsalBrowserFlowOptions } from "./msalBrowserOptions.js";
|
2
|
+
import type { AccessToken } from "@azure/core-auth";
|
3
|
+
import type { AuthenticationRecord } from "../types.js";
|
7
4
|
import type { CredentialFlowGetTokenOptions } from "../credentials.js";
|
8
|
-
import type { LogPolicyOptions } from "@azure/core-rest-pipeline";
|
9
|
-
import type { MultiTenantTokenCredentialOptions } from "../../credentials/multiTenantTokenCredentialOptions.js";
|
10
5
|
/**
|
11
|
-
*
|
12
|
-
* Some properties might not be used by some flow types.
|
13
|
-
*/
|
14
|
-
export interface MsalBrowserFlowOptions extends MsalFlowOptions {
|
15
|
-
tokenCredentialOptions: MultiTenantTokenCredentialOptions;
|
16
|
-
redirectUri?: string;
|
17
|
-
loginStyle: BrowserLoginStyle;
|
18
|
-
loginHint?: string;
|
19
|
-
/**
|
20
|
-
* Allows users to configure settings for logging policy options, allow logging account information and personally identifiable information for customer support.
|
21
|
-
*/
|
22
|
-
loggingOptions?: LogPolicyOptions & {
|
23
|
-
/**
|
24
|
-
* Allows logging account information once the authentication flow succeeds.
|
25
|
-
*/
|
26
|
-
allowLoggingAccountIdentifiers?: boolean;
|
27
|
-
/**
|
28
|
-
* Allows logging personally identifiable information for customer support.
|
29
|
-
*/
|
30
|
-
enableUnsafeSupportLogging?: boolean;
|
31
|
-
};
|
32
|
-
}
|
33
|
-
/**
|
34
|
-
* The common methods we use to work with the MSAL browser flows.
|
6
|
+
* Methods that are used by InteractiveBrowserCredential
|
35
7
|
* @internal
|
36
8
|
*/
|
37
|
-
export interface
|
38
|
-
|
39
|
-
|
9
|
+
export interface MsalBrowserClient {
|
10
|
+
getActiveAccount(): Promise<AuthenticationRecord | undefined>;
|
11
|
+
getToken(scopes: string[], options: CredentialFlowGetTokenOptions): Promise<AccessToken>;
|
40
12
|
}
|
41
13
|
/**
|
42
|
-
*
|
14
|
+
* Uses MSAL Browser 2.X for browser authentication,
|
15
|
+
* which uses the [Auth Code Flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).
|
43
16
|
* @internal
|
44
17
|
*/
|
45
|
-
export declare function
|
46
|
-
/**
|
47
|
-
* MSAL partial base client for the browsers.
|
48
|
-
*
|
49
|
-
* It completes the input configuration with some default values.
|
50
|
-
* It also provides with utility protected methods that can be used from any of the clients,
|
51
|
-
* which includes handlers for successful responses and errors.
|
52
|
-
*
|
53
|
-
* @internal
|
54
|
-
*/
|
55
|
-
export declare abstract class MsalBrowser implements MsalBrowserFlow {
|
56
|
-
protected loginStyle: BrowserLoginStyle;
|
57
|
-
protected clientId: string;
|
58
|
-
protected tenantId: string;
|
59
|
-
protected additionallyAllowedTenantIds: string[];
|
60
|
-
protected authorityHost?: string;
|
61
|
-
protected account: AuthenticationRecord | undefined;
|
62
|
-
protected msalConfig: msalBrowser.Configuration;
|
63
|
-
protected disableAutomaticAuthentication?: boolean;
|
64
|
-
protected app?: msalBrowser.IPublicClientApplication;
|
65
|
-
protected logger: CredentialLogger;
|
66
|
-
constructor(options: MsalBrowserFlowOptions);
|
67
|
-
/**
|
68
|
-
* In the browsers we don't need to init()
|
69
|
-
*/
|
70
|
-
init(): Promise<void>;
|
71
|
-
/**
|
72
|
-
* Attempts to handle a redirection request the least amount of times possible.
|
73
|
-
*/
|
74
|
-
abstract handleRedirect(): Promise<AuthenticationRecord | undefined>;
|
75
|
-
/**
|
76
|
-
* Clears MSAL's cache.
|
77
|
-
*/
|
78
|
-
logout(): Promise<void>;
|
79
|
-
/**
|
80
|
-
* Uses MSAL to retrieve the active account.
|
81
|
-
*/
|
82
|
-
abstract getActiveAccount(): Promise<AuthenticationRecord | undefined>;
|
83
|
-
/**
|
84
|
-
* Uses MSAL to trigger a redirect or a popup login.
|
85
|
-
*/
|
86
|
-
abstract login(scopes?: string | string[]): Promise<AuthenticationRecord | undefined>;
|
87
|
-
/**
|
88
|
-
* Attempts to retrieve a token from cache.
|
89
|
-
*/
|
90
|
-
abstract getTokenSilent(scopes: string[]): Promise<AccessToken>;
|
91
|
-
/**
|
92
|
-
* Attempts to retrieve the token in the browser.
|
93
|
-
*/
|
94
|
-
protected abstract doGetToken(scopes: string[]): Promise<AccessToken>;
|
95
|
-
/**
|
96
|
-
* Attempts to retrieve an authenticated token from MSAL.
|
97
|
-
*/
|
98
|
-
getToken(scopes: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;
|
99
|
-
/**
|
100
|
-
* Handles the MSAL authentication result.
|
101
|
-
* If the result has an account, we update the local account reference.
|
102
|
-
* If the token received is invalid, an error will be thrown depending on what's missing.
|
103
|
-
*/
|
104
|
-
protected handleResult(scopes: string | string[], result?: MsalResult, getTokenOptions?: GetTokenOptions): AccessToken;
|
105
|
-
}
|
18
|
+
export declare function createMsalBrowserClient(options: MsalBrowserFlowOptions): MsalBrowserClient;
|
106
19
|
//# sourceMappingURL=msalBrowserCommon.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"msalBrowserCommon.d.ts","sourceRoot":"","sources":["../../../../src/msal/browserFlows/msalBrowserCommon.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"msalBrowserCommon.d.ts","sourceRoot":"","sources":["../../../../src/msal/browserFlows/msalBrowserCommon.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAYtE,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAc,MAAM,aAAa,CAAC;AAEpE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AA2CvE;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1F;AAKD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,iBAAiB,CA+R1F"}
|
@@ -2,18 +2,21 @@
|
|
2
2
|
// Copyright (c) Microsoft Corporation.
|
3
3
|
// Licensed under the MIT License.
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
5
|
-
exports.
|
6
|
-
|
5
|
+
exports.createMsalBrowserClient = createMsalBrowserClient;
|
6
|
+
const tslib_1 = require("tslib");
|
7
|
+
const msalBrowser = tslib_1.__importStar(require("@azure/msal-browser"));
|
8
|
+
const utils_js_1 = require("../utils.js");
|
7
9
|
const errors_js_1 = require("../../errors.js");
|
10
|
+
const logger_1 = require("@azure/logger");
|
8
11
|
const logging_js_1 = require("../../util/logging.js");
|
9
|
-
const utils_js_1 = require("../utils.js");
|
10
12
|
const tenantIdUtils_js_1 = require("../../util/tenantIdUtils.js");
|
11
13
|
const constants_js_1 = require("../../constants.js");
|
12
14
|
/**
|
13
15
|
* Generates a MSAL configuration that generally works for browsers
|
14
16
|
* @internal
|
15
17
|
*/
|
16
|
-
function
|
18
|
+
function generateMsalBrowserConfiguration(options) {
|
19
|
+
var _a;
|
17
20
|
const tenantId = options.tenantId || constants_js_1.DefaultTenantId;
|
18
21
|
const authority = (0, utils_js_1.getAuthority)(tenantId, options.authorityHost);
|
19
22
|
return {
|
@@ -26,89 +29,124 @@ function defaultBrowserMsalConfig(options) {
|
|
26
29
|
// we can try to use the current page we're in as a default value.
|
27
30
|
redirectUri: options.redirectUri || self.location.origin,
|
28
31
|
},
|
32
|
+
cache: {
|
33
|
+
cacheLocation: "sessionStorage",
|
34
|
+
storeAuthStateInCookie: true, // Set to true to improve the experience on IE11 and Edge.
|
35
|
+
},
|
36
|
+
system: {
|
37
|
+
loggerOptions: {
|
38
|
+
loggerCallback: (0, utils_js_1.defaultLoggerCallback)(options.logger, "Browser"),
|
39
|
+
logLevel: (0, utils_js_1.getMSALLogLevel)((0, logger_1.getLogLevel)()),
|
40
|
+
piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
|
41
|
+
},
|
42
|
+
},
|
29
43
|
};
|
30
44
|
}
|
45
|
+
// We keep a copy of the redirect hash.
|
46
|
+
const redirectHash = self.location.hash;
|
31
47
|
/**
|
32
|
-
* MSAL
|
33
|
-
*
|
34
|
-
* It completes the input configuration with some default values.
|
35
|
-
* It also provides with utility protected methods that can be used from any of the clients,
|
36
|
-
* which includes handlers for successful responses and errors.
|
37
|
-
*
|
48
|
+
* Uses MSAL Browser 2.X for browser authentication,
|
49
|
+
* which uses the [Auth Code Flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).
|
38
50
|
* @internal
|
39
51
|
*/
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
if (!options.clientId) {
|
46
|
-
throw new errors_js_1.CredentialUnavailableError("A client ID is required in browsers");
|
47
|
-
}
|
48
|
-
this.clientId = options.clientId;
|
49
|
-
this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
|
50
|
-
this.tenantId = (0, tenantIdUtils_js_1.resolveTenantId)(this.logger, options.tenantId, options.clientId);
|
51
|
-
this.authorityHost = options.authorityHost;
|
52
|
-
this.msalConfig = defaultBrowserMsalConfig(options);
|
53
|
-
this.disableAutomaticAuthentication = options.disableAutomaticAuthentication;
|
54
|
-
if (options.authenticationRecord) {
|
55
|
-
this.account = Object.assign(Object.assign({}, options.authenticationRecord), { tenantId: this.tenantId });
|
56
|
-
}
|
52
|
+
function createMsalBrowserClient(options) {
|
53
|
+
var _a;
|
54
|
+
const loginStyle = options.loginStyle;
|
55
|
+
if (!options.clientId) {
|
56
|
+
throw new errors_js_1.CredentialUnavailableError("A client ID is required in browsers");
|
57
57
|
}
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
const clientId = options.clientId;
|
59
|
+
const logger = options.logger;
|
60
|
+
const tenantId = (0, tenantIdUtils_js_1.resolveTenantId)(logger, options.tenantId, options.clientId);
|
61
|
+
const additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
|
62
|
+
const authorityHost = options.authorityHost;
|
63
|
+
const msalConfig = generateMsalBrowserConfiguration(options);
|
64
|
+
const disableAutomaticAuthentication = options.disableAutomaticAuthentication;
|
65
|
+
const loginHint = options.loginHint;
|
66
|
+
let account;
|
67
|
+
if (options.authenticationRecord) {
|
68
|
+
account = Object.assign(Object.assign({}, options.authenticationRecord), { tenantId });
|
63
69
|
}
|
70
|
+
// This variable should only be used through calling `getApp` function
|
71
|
+
let app;
|
64
72
|
/**
|
65
|
-
*
|
73
|
+
* Return the MSAL account if not set yet
|
74
|
+
* @returns MSAL application
|
66
75
|
*/
|
67
|
-
async
|
68
|
-
|
69
|
-
|
76
|
+
async function getApp() {
|
77
|
+
if (!app) {
|
78
|
+
// Prepare the MSAL application
|
79
|
+
app = await msalBrowser.PublicClientApplication.createPublicClientApplication(msalConfig);
|
80
|
+
// setting the account right after the app is created.
|
81
|
+
if (account) {
|
82
|
+
app.setActiveAccount((0, utils_js_1.publicToMsal)(account));
|
83
|
+
}
|
84
|
+
}
|
85
|
+
return app;
|
70
86
|
}
|
71
87
|
/**
|
72
|
-
*
|
88
|
+
* Loads the account based on the result of the authentication.
|
89
|
+
* If no result was received, tries to load the account from the cache.
|
90
|
+
* @param result - Result object received from MSAL.
|
73
91
|
*/
|
74
|
-
async
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
await this.handleRedirect();
|
82
|
-
if (!(await this.getActiveAccount()) && !this.disableAutomaticAuthentication) {
|
83
|
-
await this.login(scopes);
|
84
|
-
}
|
85
|
-
return this.getTokenSilent(scopes).catch((err) => {
|
86
|
-
if (err.name !== "AuthenticationRequiredError") {
|
87
|
-
throw err;
|
92
|
+
async function handleBrowserResult(result) {
|
93
|
+
try {
|
94
|
+
const msalApp = await getApp();
|
95
|
+
if (result && result.account) {
|
96
|
+
logger.info(`MSAL Browser V2 authentication successful.`);
|
97
|
+
msalApp.setActiveAccount(result.account);
|
98
|
+
return (0, utils_js_1.msalToPublic)(clientId, result.account);
|
88
99
|
}
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
100
|
+
// If by this point we happen to have an active account, we should stop trying to parse this.
|
101
|
+
const activeAccount = msalApp.getActiveAccount();
|
102
|
+
if (activeAccount) {
|
103
|
+
return (0, utils_js_1.msalToPublic)(clientId, activeAccount);
|
104
|
+
}
|
105
|
+
// If we don't have an active account, we try to activate it from all the already loaded accounts.
|
106
|
+
const allAccounts = app.getAllAccounts();
|
107
|
+
if (allAccounts.length > 1) {
|
108
|
+
// If there's more than one account in memory, we force the user to authenticate again.
|
109
|
+
// At this point we can't identify which account should this credential work with,
|
110
|
+
// since at this point the user won't have provided enough information.
|
111
|
+
// We log a message in case that helps.
|
112
|
+
logger.info(`More than one account was found authenticated for this Client ID and Tenant ID.
|
113
|
+
However, no "authenticationRecord" has been provided for this credential,
|
114
|
+
therefore we're unable to pick between these accounts.
|
115
|
+
A new login attempt will be requested, to ensure the correct account is picked.
|
116
|
+
To work with multiple accounts for the same Client ID and Tenant ID, please provide an "authenticationRecord" when initializing "InteractiveBrowserCredential".`);
|
117
|
+
// To safely trigger a new login, we're also ensuring the local cache is cleared up for this MSAL object.
|
118
|
+
// However, we want to avoid kicking the user out of their authentication on the Azure side.
|
119
|
+
// We do this by calling to logout while specifying a `onRedirectNavigate` that returns false.
|
120
|
+
await msalApp.logout({
|
121
|
+
onRedirectNavigate: () => false,
|
94
122
|
});
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
// If there's only one account for this MSAL object, we can safely activate it.
|
126
|
+
if (allAccounts.length === 1) {
|
127
|
+
const msalAccount = allAccounts[0];
|
128
|
+
msalApp.setActiveAccount(msalAccount);
|
129
|
+
return (0, utils_js_1.msalToPublic)(clientId, msalAccount);
|
95
130
|
}
|
96
|
-
|
97
|
-
|
98
|
-
|
131
|
+
logger.info(`No accounts were found through MSAL.`);
|
132
|
+
}
|
133
|
+
catch (e) {
|
134
|
+
logger.info(`Failed to acquire token through MSAL. ${e.message}`);
|
135
|
+
}
|
136
|
+
return;
|
99
137
|
}
|
100
138
|
/**
|
101
139
|
* Handles the MSAL authentication result.
|
102
140
|
* If the result has an account, we update the local account reference.
|
103
141
|
* If the token received is invalid, an error will be thrown depending on what's missing.
|
104
142
|
*/
|
105
|
-
handleResult(scopes, result, getTokenOptions) {
|
143
|
+
function handleResult(scopes, result, getTokenOptions) {
|
106
144
|
var _a;
|
107
145
|
if (result === null || result === void 0 ? void 0 : result.account) {
|
108
|
-
|
146
|
+
account = (0, utils_js_1.msalToPublic)(clientId, result.account);
|
109
147
|
}
|
110
148
|
(0, utils_js_1.ensureValidMsalToken)(scopes, result, getTokenOptions);
|
111
|
-
|
149
|
+
logger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
|
112
150
|
return {
|
113
151
|
token: result.accessToken,
|
114
152
|
expiresOnTimestamp: result.expiresOn.getTime(),
|
@@ -116,6 +154,142 @@ class MsalBrowser {
|
|
116
154
|
tokenType: "Bearer",
|
117
155
|
};
|
118
156
|
}
|
157
|
+
/**
|
158
|
+
* Uses MSAL to handle the redirect.
|
159
|
+
*/
|
160
|
+
async function handleRedirect() {
|
161
|
+
const msalApp = await getApp();
|
162
|
+
return handleBrowserResult((await msalApp.handleRedirectPromise(redirectHash)) || undefined);
|
163
|
+
}
|
164
|
+
/**
|
165
|
+
* Uses MSAL to retrieve the active account.
|
166
|
+
*/
|
167
|
+
async function getActiveAccount() {
|
168
|
+
const msalApp = await getApp();
|
169
|
+
const activeAccount = msalApp.getActiveAccount();
|
170
|
+
if (!activeAccount) {
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
return (0, utils_js_1.msalToPublic)(clientId, activeAccount);
|
174
|
+
}
|
175
|
+
/**
|
176
|
+
* Uses MSAL to trigger a redirect or a popup login.
|
177
|
+
*/
|
178
|
+
async function login(scopes = []) {
|
179
|
+
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
|
180
|
+
const loginRequest = {
|
181
|
+
scopes: arrayScopes,
|
182
|
+
loginHint: loginHint,
|
183
|
+
};
|
184
|
+
const msalApp = await getApp();
|
185
|
+
switch (loginStyle) {
|
186
|
+
case "redirect": {
|
187
|
+
await app.loginRedirect(loginRequest);
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
case "popup":
|
191
|
+
return handleBrowserResult(await msalApp.loginPopup(loginRequest));
|
192
|
+
}
|
193
|
+
}
|
194
|
+
/**
|
195
|
+
* Tries to retrieve the token silently using MSAL.
|
196
|
+
*/
|
197
|
+
async function getTokenSilent(scopes, getTokenOptions) {
|
198
|
+
const activeAccount = await getActiveAccount();
|
199
|
+
if (!activeAccount) {
|
200
|
+
throw new errors_js_1.AuthenticationRequiredError({
|
201
|
+
scopes,
|
202
|
+
getTokenOptions,
|
203
|
+
message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
|
204
|
+
});
|
205
|
+
}
|
206
|
+
const parameters = {
|
207
|
+
authority: (getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.authority) || msalConfig.auth.authority,
|
208
|
+
correlationId: getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.correlationId,
|
209
|
+
claims: getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.claims,
|
210
|
+
account: (0, utils_js_1.publicToMsal)(activeAccount),
|
211
|
+
forceRefresh: false,
|
212
|
+
scopes,
|
213
|
+
};
|
214
|
+
try {
|
215
|
+
logger.info("Attempting to acquire token silently");
|
216
|
+
const msalApp = await getApp();
|
217
|
+
const response = await msalApp.acquireTokenSilent(parameters);
|
218
|
+
return handleResult(scopes, response);
|
219
|
+
}
|
220
|
+
catch (err) {
|
221
|
+
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
/**
|
225
|
+
* Attempts to retrieve the token in the browser through interactive methods.
|
226
|
+
*/
|
227
|
+
async function getTokenInteractive(scopes, getTokenOptions) {
|
228
|
+
const activeAccount = await getActiveAccount();
|
229
|
+
if (!activeAccount) {
|
230
|
+
throw new errors_js_1.AuthenticationRequiredError({
|
231
|
+
scopes,
|
232
|
+
getTokenOptions,
|
233
|
+
message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
|
234
|
+
});
|
235
|
+
}
|
236
|
+
const parameters = {
|
237
|
+
authority: (getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.authority) || msalConfig.auth.authority,
|
238
|
+
correlationId: getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.correlationId,
|
239
|
+
claims: getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.claims,
|
240
|
+
account: (0, utils_js_1.publicToMsal)(activeAccount),
|
241
|
+
loginHint: loginHint,
|
242
|
+
scopes,
|
243
|
+
};
|
244
|
+
const msalApp = await getApp();
|
245
|
+
switch (loginStyle) {
|
246
|
+
case "redirect":
|
247
|
+
// This will go out of the page.
|
248
|
+
// Once the InteractiveBrowserCredential is initialized again,
|
249
|
+
// we'll load the MSAL account in the constructor.
|
250
|
+
await msalApp.acquireTokenRedirect(parameters);
|
251
|
+
return { token: "", expiresOnTimestamp: 0, tokenType: "Bearer" };
|
252
|
+
case "popup":
|
253
|
+
return handleResult(scopes, await app.acquireTokenPopup(parameters));
|
254
|
+
}
|
255
|
+
}
|
256
|
+
/**
|
257
|
+
* Attempts to get token through the silent flow.
|
258
|
+
* If failed, get token through interactive method with `doGetToken` method.
|
259
|
+
*/
|
260
|
+
async function getToken(scopes, getTokenOptions = {}) {
|
261
|
+
const getTokenTenantId = (0, tenantIdUtils_js_1.processMultiTenantRequest)(tenantId, getTokenOptions, additionallyAllowedTenantIds) ||
|
262
|
+
tenantId;
|
263
|
+
if (!getTokenOptions.authority) {
|
264
|
+
getTokenOptions.authority = (0, utils_js_1.getAuthority)(getTokenTenantId, authorityHost);
|
265
|
+
}
|
266
|
+
// We ensure that redirection is handled at this point.
|
267
|
+
await handleRedirect();
|
268
|
+
if (!(await getActiveAccount()) && !disableAutomaticAuthentication) {
|
269
|
+
await login(scopes);
|
270
|
+
}
|
271
|
+
// Attempts to get the token silently; else, falls back to interactive method.
|
272
|
+
try {
|
273
|
+
return await getTokenSilent(scopes, getTokenOptions);
|
274
|
+
}
|
275
|
+
catch (err) {
|
276
|
+
if (err.name !== "AuthenticationRequiredError") {
|
277
|
+
throw err;
|
278
|
+
}
|
279
|
+
if (getTokenOptions === null || getTokenOptions === void 0 ? void 0 : getTokenOptions.disableAutomaticAuthentication) {
|
280
|
+
throw new errors_js_1.AuthenticationRequiredError({
|
281
|
+
scopes,
|
282
|
+
getTokenOptions,
|
283
|
+
message: "Automatic authentication has been disabled. You may call the authenticate() method.",
|
284
|
+
});
|
285
|
+
}
|
286
|
+
logger.info(`Silent authentication failed, falling back to interactive method ${loginStyle}`);
|
287
|
+
return getTokenInteractive(scopes, getTokenOptions);
|
288
|
+
}
|
289
|
+
}
|
290
|
+
return {
|
291
|
+
getActiveAccount,
|
292
|
+
getToken,
|
293
|
+
};
|
119
294
|
}
|
120
|
-
exports.MsalBrowser = MsalBrowser;
|
121
295
|
//# sourceMappingURL=msalBrowserCommon.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"msalBrowserCommon.js","sourceRoot":"","sources":["../../../../src/msal/browserFlows/msalBrowserCommon.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type * as msalBrowser from \"@azure/msal-browser\";\n\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport type { AuthenticationRecord, MsalResult } from \"../types.js\";\nimport { AuthenticationRequiredError, CredentialUnavailableError } from \"../../errors.js\";\nimport type { CredentialLogger } from \"../../util/logging.js\";\nimport { formatSuccess } from \"../../util/logging.js\";\nimport type { MsalFlow, MsalFlowOptions } from \"./flows.js\";\nimport { ensureValidMsalToken, getAuthority, getKnownAuthorities, msalToPublic } from \"../utils.js\";\nimport {\n processMultiTenantRequest,\n resolveAdditionallyAllowedTenantIds,\n resolveTenantId,\n} from \"../../util/tenantIdUtils.js\";\n\nimport type { BrowserLoginStyle } from \"../../credentials/interactiveBrowserCredentialOptions.js\";\nimport type { CredentialFlowGetTokenOptions } from \"../credentials.js\";\nimport { DefaultTenantId } from \"../../constants.js\";\nimport type { LogPolicyOptions } from \"@azure/core-rest-pipeline\";\nimport type { MultiTenantTokenCredentialOptions } from \"../../credentials/multiTenantTokenCredentialOptions.js\";\n\n/**\n * Union of the constructor parameters that all MSAL flow types take.\n * Some properties might not be used by some flow types.\n */\nexport interface MsalBrowserFlowOptions extends MsalFlowOptions {\n tokenCredentialOptions: MultiTenantTokenCredentialOptions;\n redirectUri?: string;\n loginStyle: BrowserLoginStyle;\n loginHint?: string;\n /**\n * Allows users to configure settings for logging policy options, allow logging account information and personally identifiable information for customer support.\n */\n loggingOptions?: LogPolicyOptions & {\n /**\n * Allows logging account information once the authentication flow succeeds.\n */\n allowLoggingAccountIdentifiers?: boolean;\n /**\n * Allows logging personally identifiable information for customer support.\n */\n enableUnsafeSupportLogging?: boolean;\n };\n}\n\n/**\n * The common methods we use to work with the MSAL browser flows.\n * @internal\n */\nexport interface MsalBrowserFlow extends MsalFlow {\n login(scopes?: string[]): Promise<AuthenticationRecord | undefined>;\n handleRedirect(): Promise<AuthenticationRecord | undefined>;\n}\n\n/**\n * Generates a MSAL configuration that generally works for browsers\n * @internal\n */\nexport function defaultBrowserMsalConfig(\n options: MsalBrowserFlowOptions,\n): msalBrowser.Configuration {\n const tenantId = options.tenantId || DefaultTenantId;\n const authority = getAuthority(tenantId, options.authorityHost);\n return {\n auth: {\n clientId: options.clientId!,\n authority,\n knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),\n // If the users picked redirect as their login style,\n // but they didn't provide a redirectUri,\n // we can try to use the current page we're in as a default value.\n redirectUri: options.redirectUri || self.location.origin,\n },\n };\n}\n\n/**\n * MSAL partial base client for the browsers.\n *\n * It completes the input configuration with some default values.\n * It also provides with utility protected methods that can be used from any of the clients,\n * which includes handlers for successful responses and errors.\n *\n * @internal\n */\nexport abstract class MsalBrowser implements MsalBrowserFlow {\n protected loginStyle: BrowserLoginStyle;\n protected clientId: string;\n protected tenantId: string;\n protected additionallyAllowedTenantIds: string[];\n protected authorityHost?: string;\n protected account: AuthenticationRecord | undefined;\n protected msalConfig: msalBrowser.Configuration;\n protected disableAutomaticAuthentication?: boolean;\n protected app?: msalBrowser.IPublicClientApplication;\n protected logger: CredentialLogger;\n\n constructor(options: MsalBrowserFlowOptions) {\n this.logger = options.logger;\n this.loginStyle = options.loginStyle;\n if (!options.clientId) {\n throw new CredentialUnavailableError(\"A client ID is required in browsers\");\n }\n this.clientId = options.clientId;\n this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n options?.tokenCredentialOptions?.additionallyAllowedTenants,\n );\n this.tenantId = resolveTenantId(this.logger, options.tenantId, options.clientId);\n this.authorityHost = options.authorityHost;\n this.msalConfig = defaultBrowserMsalConfig(options);\n this.disableAutomaticAuthentication = options.disableAutomaticAuthentication;\n\n if (options.authenticationRecord) {\n this.account = {\n ...options.authenticationRecord,\n tenantId: this.tenantId,\n };\n }\n }\n\n /**\n * In the browsers we don't need to init()\n */\n async init(): Promise<void> {\n // Nothing to do here.\n }\n\n /**\n * Attempts to handle a redirection request the least amount of times possible.\n */\n public abstract handleRedirect(): Promise<AuthenticationRecord | undefined>;\n\n /**\n * Clears MSAL's cache.\n */\n async logout(): Promise<void> {\n this.app?.logout();\n }\n\n /**\n * Uses MSAL to retrieve the active account.\n */\n public abstract getActiveAccount(): Promise<AuthenticationRecord | undefined>;\n\n /**\n * Uses MSAL to trigger a redirect or a popup login.\n */\n public abstract login(scopes?: string | string[]): Promise<AuthenticationRecord | undefined>;\n\n /**\n * Attempts to retrieve a token from cache.\n */\n public abstract getTokenSilent(scopes: string[]): Promise<AccessToken>;\n\n /**\n * Attempts to retrieve the token in the browser.\n */\n protected abstract doGetToken(scopes: string[]): Promise<AccessToken>;\n\n /**\n * Attempts to retrieve an authenticated token from MSAL.\n */\n public async getToken(\n scopes: string[],\n options: CredentialFlowGetTokenOptions = {},\n ): Promise<AccessToken> {\n const tenantId =\n processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||\n this.tenantId;\n\n if (!options.authority) {\n options.authority = getAuthority(tenantId, this.authorityHost);\n }\n\n // We ensure that redirection is handled at this point.\n await this.handleRedirect();\n\n if (!(await this.getActiveAccount()) && !this.disableAutomaticAuthentication) {\n await this.login(scopes);\n }\n return this.getTokenSilent(scopes).catch((err) => {\n if (err.name !== \"AuthenticationRequiredError\") {\n throw err;\n }\n if (options?.disableAutomaticAuthentication) {\n throw new AuthenticationRequiredError({\n scopes,\n getTokenOptions: options,\n message:\n \"Automatic authentication has been disabled. You may call the authentication() method.\",\n });\n }\n this.logger.info(\n `Silent authentication failed, falling back to interactive method ${this.loginStyle}`,\n );\n return this.doGetToken(scopes);\n });\n }\n\n /**\n * Handles the MSAL authentication result.\n * If the result has an account, we update the local account reference.\n * If the token received is invalid, an error will be thrown depending on what's missing.\n */\n protected handleResult(\n scopes: string | string[],\n result?: MsalResult,\n getTokenOptions?: GetTokenOptions,\n ): AccessToken {\n if (result?.account) {\n this.account = msalToPublic(this.clientId, result.account);\n }\n ensureValidMsalToken(scopes, result, getTokenOptions);\n this.logger.getToken.info(formatSuccess(scopes));\n return {\n token: result.accessToken,\n expiresOnTimestamp: result.expiresOn.getTime(),\n refreshAfterTimestamp: result.refreshOn?.getTime(),\n tokenType: \"Bearer\",\n } as AccessToken;\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"msalBrowserCommon.js","sourceRoot":"","sources":["../../../../src/msal/browserFlows/msalBrowserCommon.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport * as msalBrowser from \"@azure/msal-browser\";\n\nimport type { MsalBrowserFlowOptions } from \"./msalBrowserOptions.js\";\nimport {\n defaultLoggerCallback,\n ensureValidMsalToken,\n getAuthority,\n getKnownAuthorities,\n getMSALLogLevel,\n handleMsalError,\n msalToPublic,\n publicToMsal,\n} from \"../utils.js\";\n\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport type { AuthenticationRecord, MsalResult } from \"../types.js\";\nimport { AuthenticationRequiredError, CredentialUnavailableError } from \"../../errors.js\";\nimport type { CredentialFlowGetTokenOptions } from \"../credentials.js\";\nimport { getLogLevel } from \"@azure/logger\";\nimport { formatSuccess } from \"../../util/logging.js\";\nimport {\n processMultiTenantRequest,\n resolveAdditionallyAllowedTenantIds,\n resolveTenantId,\n} from \"../../util/tenantIdUtils.js\";\nimport { DefaultTenantId } from \"../../constants.js\";\n\n/**\n * Generates a MSAL configuration that generally works for browsers\n * @internal\n */\nfunction generateMsalBrowserConfiguration(\n options: MsalBrowserFlowOptions,\n): msalBrowser.Configuration {\n const tenantId = options.tenantId || DefaultTenantId;\n const authority = getAuthority(tenantId, options.authorityHost);\n return {\n auth: {\n clientId: options.clientId!,\n authority,\n knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),\n // If the users picked redirect as their login style,\n // but they didn't provide a redirectUri,\n // we can try to use the current page we're in as a default value.\n redirectUri: options.redirectUri || self.location.origin,\n },\n cache: {\n cacheLocation: \"sessionStorage\",\n storeAuthStateInCookie: true, // Set to true to improve the experience on IE11 and Edge.\n },\n system: {\n loggerOptions: {\n loggerCallback: defaultLoggerCallback(options.logger, \"Browser\"),\n logLevel: getMSALLogLevel(getLogLevel()),\n piiLoggingEnabled: options.loggingOptions?.enableUnsafeSupportLogging,\n },\n },\n };\n}\n\n/**\n * Methods that are used by InteractiveBrowserCredential\n * @internal\n */\nexport interface MsalBrowserClient {\n getActiveAccount(): Promise<AuthenticationRecord | undefined>;\n getToken(scopes: string[], options: CredentialFlowGetTokenOptions): Promise<AccessToken>;\n}\n\n// We keep a copy of the redirect hash.\nconst redirectHash = self.location.hash;\n\n/**\n * Uses MSAL Browser 2.X for browser authentication,\n * which uses the [Auth Code Flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).\n * @internal\n */\nexport function createMsalBrowserClient(options: MsalBrowserFlowOptions): MsalBrowserClient {\n const loginStyle = options.loginStyle;\n if (!options.clientId) {\n throw new CredentialUnavailableError(\"A client ID is required in browsers\");\n }\n const clientId = options.clientId;\n const logger = options.logger;\n const tenantId = resolveTenantId(logger, options.tenantId, options.clientId);\n const additionallyAllowedTenantIds: string[] = resolveAdditionallyAllowedTenantIds(\n options?.tokenCredentialOptions?.additionallyAllowedTenants,\n );\n const authorityHost = options.authorityHost;\n const msalConfig = generateMsalBrowserConfiguration(options);\n const disableAutomaticAuthentication = options.disableAutomaticAuthentication;\n const loginHint = options.loginHint;\n\n let account: AuthenticationRecord | undefined;\n if (options.authenticationRecord) {\n account = {\n ...options.authenticationRecord,\n tenantId,\n };\n }\n\n // This variable should only be used through calling `getApp` function\n let app: msalBrowser.IPublicClientApplication;\n /**\n * Return the MSAL account if not set yet\n * @returns MSAL application\n */\n async function getApp(): Promise<msalBrowser.IPublicClientApplication> {\n if (!app) {\n // Prepare the MSAL application\n app = await msalBrowser.PublicClientApplication.createPublicClientApplication(msalConfig);\n\n // setting the account right after the app is created.\n if (account) {\n app.setActiveAccount(publicToMsal(account));\n }\n }\n\n return app;\n }\n\n /**\n * Loads the account based on the result of the authentication.\n * If no result was received, tries to load the account from the cache.\n * @param result - Result object received from MSAL.\n */\n async function handleBrowserResult(\n result?: msalBrowser.AuthenticationResult,\n ): Promise<AuthenticationRecord | undefined> {\n try {\n const msalApp = await getApp();\n if (result && result.account) {\n logger.info(`MSAL Browser V2 authentication successful.`);\n msalApp.setActiveAccount(result.account);\n return msalToPublic(clientId, result.account);\n }\n\n // If by this point we happen to have an active account, we should stop trying to parse this.\n const activeAccount = msalApp.getActiveAccount();\n if (activeAccount) {\n return msalToPublic(clientId, activeAccount);\n }\n\n // If we don't have an active account, we try to activate it from all the already loaded accounts.\n const allAccounts = app.getAllAccounts();\n if (allAccounts.length > 1) {\n // If there's more than one account in memory, we force the user to authenticate again.\n // At this point we can't identify which account should this credential work with,\n // since at this point the user won't have provided enough information.\n // We log a message in case that helps.\n logger.info(\n `More than one account was found authenticated for this Client ID and Tenant ID.\n However, no \"authenticationRecord\" has been provided for this credential,\n therefore we're unable to pick between these accounts.\n A new login attempt will be requested, to ensure the correct account is picked.\n To work with multiple accounts for the same Client ID and Tenant ID, please provide an \"authenticationRecord\" when initializing \"InteractiveBrowserCredential\".`,\n );\n // To safely trigger a new login, we're also ensuring the local cache is cleared up for this MSAL object.\n // However, we want to avoid kicking the user out of their authentication on the Azure side.\n // We do this by calling to logout while specifying a `onRedirectNavigate` that returns false.\n await msalApp.logout({\n onRedirectNavigate: () => false,\n });\n return;\n }\n\n // If there's only one account for this MSAL object, we can safely activate it.\n if (allAccounts.length === 1) {\n const msalAccount = allAccounts[0];\n msalApp.setActiveAccount(msalAccount);\n return msalToPublic(clientId, msalAccount);\n }\n\n logger.info(`No accounts were found through MSAL.`);\n } catch (e: any) {\n logger.info(`Failed to acquire token through MSAL. ${e.message}`);\n }\n return;\n }\n\n /**\n * Handles the MSAL authentication result.\n * If the result has an account, we update the local account reference.\n * If the token received is invalid, an error will be thrown depending on what's missing.\n */\n function handleResult(\n scopes: string | string[],\n result?: MsalResult,\n getTokenOptions?: GetTokenOptions,\n ): AccessToken {\n if (result?.account) {\n account = msalToPublic(clientId, result.account);\n }\n ensureValidMsalToken(scopes, result, getTokenOptions);\n logger.getToken.info(formatSuccess(scopes));\n return {\n token: result.accessToken,\n expiresOnTimestamp: result.expiresOn.getTime(),\n refreshAfterTimestamp: result.refreshOn?.getTime(),\n tokenType: \"Bearer\",\n };\n }\n\n /**\n * Uses MSAL to handle the redirect.\n */\n async function handleRedirect(): Promise<AuthenticationRecord | undefined> {\n const msalApp = await getApp();\n return handleBrowserResult((await msalApp.handleRedirectPromise(redirectHash)) || undefined);\n }\n\n /**\n * Uses MSAL to retrieve the active account.\n */\n async function getActiveAccount(): Promise<AuthenticationRecord | undefined> {\n const msalApp = await getApp();\n const activeAccount = msalApp.getActiveAccount();\n if (!activeAccount) {\n return;\n }\n return msalToPublic(clientId, activeAccount);\n }\n\n /**\n * Uses MSAL to trigger a redirect or a popup login.\n */\n async function login(scopes: string | string[] = []): Promise<AuthenticationRecord | undefined> {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n const loginRequest: msalBrowser.RedirectRequest = {\n scopes: arrayScopes,\n loginHint: loginHint,\n };\n const msalApp = await getApp();\n switch (loginStyle) {\n case \"redirect\": {\n await app.loginRedirect(loginRequest);\n return;\n }\n case \"popup\":\n return handleBrowserResult(await msalApp.loginPopup(loginRequest));\n }\n }\n\n /**\n * Tries to retrieve the token silently using MSAL.\n */\n async function getTokenSilent(\n scopes: string[],\n getTokenOptions?: CredentialFlowGetTokenOptions,\n ): Promise<AccessToken> {\n const activeAccount = await getActiveAccount();\n if (!activeAccount) {\n throw new AuthenticationRequiredError({\n scopes,\n getTokenOptions,\n message:\n \"Silent authentication failed. We couldn't retrieve an active account from the cache.\",\n });\n }\n\n const parameters: msalBrowser.SilentRequest = {\n authority: getTokenOptions?.authority || msalConfig.auth.authority!,\n correlationId: getTokenOptions?.correlationId,\n claims: getTokenOptions?.claims,\n account: publicToMsal(activeAccount),\n forceRefresh: false,\n scopes,\n };\n\n try {\n logger.info(\"Attempting to acquire token silently\");\n const msalApp = await getApp();\n const response = await msalApp.acquireTokenSilent(parameters);\n return handleResult(scopes, response);\n } catch (err: any) {\n throw handleMsalError(scopes, err, options);\n }\n }\n\n /**\n * Attempts to retrieve the token in the browser through interactive methods.\n */\n async function getTokenInteractive(\n scopes: string[],\n getTokenOptions?: CredentialFlowGetTokenOptions,\n ): Promise<AccessToken> {\n const activeAccount = await getActiveAccount();\n if (!activeAccount) {\n throw new AuthenticationRequiredError({\n scopes,\n getTokenOptions,\n message:\n \"Silent authentication failed. We couldn't retrieve an active account from the cache.\",\n });\n }\n\n const parameters: msalBrowser.RedirectRequest = {\n authority: getTokenOptions?.authority || msalConfig.auth.authority!,\n correlationId: getTokenOptions?.correlationId,\n claims: getTokenOptions?.claims,\n account: publicToMsal(activeAccount),\n loginHint: loginHint,\n scopes,\n };\n const msalApp = await getApp();\n switch (loginStyle) {\n case \"redirect\":\n // This will go out of the page.\n // Once the InteractiveBrowserCredential is initialized again,\n // we'll load the MSAL account in the constructor.\n\n await msalApp.acquireTokenRedirect(parameters);\n return { token: \"\", expiresOnTimestamp: 0, tokenType: \"Bearer\" };\n case \"popup\":\n return handleResult(scopes, await app.acquireTokenPopup(parameters));\n }\n }\n\n /**\n * Attempts to get token through the silent flow.\n * If failed, get token through interactive method with `doGetToken` method.\n */\n async function getToken(\n scopes: string[],\n getTokenOptions: CredentialFlowGetTokenOptions = {},\n ): Promise<AccessToken> {\n const getTokenTenantId =\n processMultiTenantRequest(tenantId, getTokenOptions, additionallyAllowedTenantIds) ||\n tenantId;\n\n if (!getTokenOptions.authority) {\n getTokenOptions.authority = getAuthority(getTokenTenantId, authorityHost);\n }\n\n // We ensure that redirection is handled at this point.\n await handleRedirect();\n\n if (!(await getActiveAccount()) && !disableAutomaticAuthentication) {\n await login(scopes);\n }\n\n // Attempts to get the token silently; else, falls back to interactive method.\n try {\n return await getTokenSilent(scopes, getTokenOptions);\n } catch (err: any) {\n if (err.name !== \"AuthenticationRequiredError\") {\n throw err;\n }\n if (getTokenOptions?.disableAutomaticAuthentication) {\n throw new AuthenticationRequiredError({\n scopes,\n getTokenOptions,\n message:\n \"Automatic authentication has been disabled. You may call the authenticate() method.\",\n });\n }\n logger.info(`Silent authentication failed, falling back to interactive method ${loginStyle}`);\n return getTokenInteractive(scopes, getTokenOptions);\n }\n }\n return {\n getActiveAccount,\n getToken,\n };\n}\n"]}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import type { AuthenticationRecord } from "../types.js";
|
2
|
+
import type { BrowserLoginStyle } from "../../credentials/interactiveBrowserCredentialOptions.js";
|
3
|
+
import type { LogPolicyOptions } from "@azure/core-rest-pipeline";
|
4
|
+
import type { MultiTenantTokenCredentialOptions } from "../../credentials/multiTenantTokenCredentialOptions.js";
|
5
|
+
import type { CredentialLogger } from "../../util/logging.js";
|
6
|
+
/**
|
7
|
+
* Options for the MSAL browser flows.
|
8
|
+
* @internal
|
9
|
+
*/
|
10
|
+
export interface MsalBrowserFlowOptions {
|
11
|
+
logger: CredentialLogger;
|
12
|
+
/**
|
13
|
+
* The Client ID of the Microsoft Entra application that users will sign into.
|
14
|
+
* This parameter is required on the browser.
|
15
|
+
*/
|
16
|
+
clientId?: string;
|
17
|
+
/**
|
18
|
+
* The Microsoft Entra tenant (directory) ID.
|
19
|
+
*/
|
20
|
+
tenantId?: string;
|
21
|
+
/**
|
22
|
+
* The authority host to use for authentication requests.
|
23
|
+
* Possible values are available through {@link AzureAuthorityHosts}.
|
24
|
+
* The default is "https://login.microsoftonline.com".
|
25
|
+
*/
|
26
|
+
authorityHost?: string;
|
27
|
+
/**
|
28
|
+
* Result of a previous authentication that can be used to retrieve the cached credentials of each individual account.
|
29
|
+
* This is necessary to provide in case the application wants to work with more than one account per
|
30
|
+
* Client ID and Tenant ID pair.
|
31
|
+
*
|
32
|
+
* This record can be retrieved by calling to the credential's `authenticate()` method, as follows:
|
33
|
+
*
|
34
|
+
* const authenticationRecord = await credential.authenticate();
|
35
|
+
*
|
36
|
+
*/
|
37
|
+
authenticationRecord?: AuthenticationRecord;
|
38
|
+
/**
|
39
|
+
* Makes getToken throw if a manual authentication is necessary.
|
40
|
+
* Developers will need to call to `authenticate()` to control when to manually authenticate.
|
41
|
+
*/
|
42
|
+
disableAutomaticAuthentication?: boolean;
|
43
|
+
/**
|
44
|
+
* The field determines whether instance discovery is performed when attempting to authenticate.
|
45
|
+
* Setting this to `true` will completely disable both instance discovery and authority validation.
|
46
|
+
* As a result, it's crucial to ensure that the configured authority host is valid and trustworthy.
|
47
|
+
* This functionality is intended for use in scenarios where the metadata endpoint cannot be reached, such as in private clouds or Azure Stack.
|
48
|
+
* The process of instance discovery entails retrieving authority metadata from https://login.microsoft.com/ to validate the authority.
|
49
|
+
*/
|
50
|
+
disableInstanceDiscovery?: boolean;
|
51
|
+
/**
|
52
|
+
* Options for multi-tenant applications which allows for additionally allowed tenants.
|
53
|
+
*/
|
54
|
+
tokenCredentialOptions: MultiTenantTokenCredentialOptions;
|
55
|
+
/**
|
56
|
+
* Gets the redirect URI of the application. This should be same as the value
|
57
|
+
* in the application registration portal. Defaults to `window.location.href`.
|
58
|
+
* This field is no longer required for Node.js.
|
59
|
+
*/
|
60
|
+
redirectUri?: string;
|
61
|
+
/**
|
62
|
+
* Specifies whether a redirect or a popup window should be used to
|
63
|
+
* initiate the user authentication flow. Possible values are "redirect"
|
64
|
+
* or "popup" (default) for browser and "popup" (default) for node.
|
65
|
+
*
|
66
|
+
*/
|
67
|
+
loginStyle: BrowserLoginStyle;
|
68
|
+
/**
|
69
|
+
* loginHint allows a user name to be pre-selected for interactive logins.
|
70
|
+
* Setting this option skips the account selection prompt and immediately attempts to login with the specified account.
|
71
|
+
*/
|
72
|
+
loginHint?: string;
|
73
|
+
/**
|
74
|
+
* Allows users to configure settings for logging policy options, allow logging account information and personally identifiable information for customer support.
|
75
|
+
*/
|
76
|
+
loggingOptions?: LogPolicyOptions & {
|
77
|
+
/**
|
78
|
+
* Allows logging account information once the authentication flow succeeds.
|
79
|
+
*/
|
80
|
+
allowLoggingAccountIdentifiers?: boolean;
|
81
|
+
/**
|
82
|
+
* Allows logging personally identifiable information for customer support.
|
83
|
+
*/
|
84
|
+
enableUnsafeSupportLogging?: boolean;
|
85
|
+
};
|
86
|
+
}
|
87
|
+
//# sourceMappingURL=msalBrowserOptions.d.ts.map
|