@azure/identity 1.0.0-preview.1 → 1.0.0-preview.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/CHANGELOG.md +24 -0
- package/README.md +50 -23
- package/browser/identity.js +9828 -0
- package/browser/identity.js.map +1 -0
- package/browser/identity.min.js +2 -0
- package/browser/identity.min.js.map +1 -0
- package/dist/index.js +475 -205
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/errors.d.ts +1 -1
- package/dist-esm/src/client/errors.d.ts.map +1 -1
- package/dist-esm/src/client/errors.js +9 -1
- package/dist-esm/src/client/errors.js.map +1 -1
- package/dist-esm/src/client/identityClient.d.ts +20 -17
- package/dist-esm/src/client/identityClient.d.ts.map +1 -1
- package/dist-esm/src/client/identityClient.js +42 -206
- package/dist-esm/src/client/identityClient.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.browser.d.ts +7 -0
- package/dist-esm/src/credentials/clientCertificateCredential.browser.d.ts.map +1 -0
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js +12 -0
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/clientCertificateCredential.d.ts +5 -5
- package/dist-esm/src/credentials/clientCertificateCredential.d.ts.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.js +59 -5
- package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.d.ts +3 -3
- package/dist-esm/src/credentials/clientSecretCredential.d.ts.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.js +27 -4
- package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.d.ts +7 -0
- package/dist-esm/src/credentials/deviceCodeCredential.browser.d.ts.map +1 -0
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js +12 -0
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/deviceCodeCredential.d.ts +67 -0
- package/dist-esm/src/credentials/deviceCodeCredential.d.ts.map +1 -0
- package/dist-esm/src/credentials/deviceCodeCredential.js +139 -0
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -0
- package/dist-esm/src/credentials/environmentCredential.browser.d.ts +7 -0
- package/dist-esm/src/credentials/environmentCredential.browser.d.ts.map +1 -0
- package/dist-esm/src/credentials/environmentCredential.browser.js +12 -0
- package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/environmentCredential.d.ts.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.js +0 -4
- package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.d.ts +32 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.d.ts.map +1 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +112 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.d.ts +12 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.d.ts.map +1 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.js +17 -0
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -0
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.d.ts +24 -0
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.d.ts.map +1 -0
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js +3 -0
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential.browser.d.ts +7 -0
- package/dist-esm/src/credentials/managedIdentityCredential.browser.d.ts.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential.browser.js +15 -0
- package/dist-esm/src/credentials/managedIdentityCredential.browser.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential.d.ts +10 -1
- package/dist-esm/src/credentials/managedIdentityCredential.d.ts.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential.js +144 -2
- package/dist-esm/src/credentials/managedIdentityCredential.js.map +1 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.d.ts +39 -0
- package/dist-esm/src/credentials/usernamePasswordCredential.d.ts.map +1 -0
- package/dist-esm/src/credentials/usernamePasswordCredential.js +67 -0
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -0
- package/dist-esm/src/index.d.ts +4 -0
- package/dist-esm/src/index.d.ts.map +1 -1
- package/dist-esm/src/index.js +3 -0
- package/dist-esm/src/index.js.map +1 -1
- package/package.json +32 -14
- package/src/client/errors.ts +11 -3
- package/src/client/identityClient.ts +64 -246
- package/src/credentials/clientCertificateCredential.browser.ts +27 -0
- package/src/credentials/clientCertificateCredential.ts +72 -22
- package/src/credentials/clientSecretCredential.ts +32 -17
- package/src/credentials/deviceCodeCredential.browser.ts +27 -0
- package/src/credentials/deviceCodeCredential.ts +203 -0
- package/src/credentials/environmentCredential.browser.ts +19 -0
- package/src/credentials/environmentCredential.ts +5 -9
- package/src/credentials/interactiveBrowserCredential.browser.ts +134 -0
- package/src/credentials/interactiveBrowserCredential.ts +31 -0
- package/src/credentials/interactiveBrowserCredentialOptions.ts +30 -0
- package/src/credentials/managedIdentityCredential.browser.ts +22 -0
- package/src/credentials/managedIdentityCredential.ts +179 -8
- package/src/credentials/usernamePasswordCredential.ts +83 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import qs from "qs";
|
|
5
|
+
import { TokenCredential, GetTokenOptions, AccessToken, delay } from "@azure/core-http";
|
|
6
|
+
import { IdentityClientOptions, IdentityClient, TokenResponse } from "../client/identityClient";
|
|
7
|
+
import { AuthenticationError } from "../client/errors";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An internal interface that contains the verbatim devicecode response.
|
|
11
|
+
* This interface does not get exported from the public interface of the
|
|
12
|
+
* library.
|
|
13
|
+
*/
|
|
14
|
+
export interface DeviceCodeResponse {
|
|
15
|
+
device_code: string,
|
|
16
|
+
user_code: string,
|
|
17
|
+
verification_uri: string,
|
|
18
|
+
expires_in: number,
|
|
19
|
+
interval: number,
|
|
20
|
+
message: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Provides the user code and verification URI where the code must be
|
|
25
|
+
* entered. Also provides a message to display to the user which
|
|
26
|
+
* contains an instruction with these details.
|
|
27
|
+
*/
|
|
28
|
+
export interface DeviceCodeDetails {
|
|
29
|
+
userCode: string,
|
|
30
|
+
verificationUri: string,
|
|
31
|
+
message: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Defines the signature of a callback which will be passed to
|
|
36
|
+
* DeviceCodeCredential for the purpose of displaying authentication
|
|
37
|
+
* details to the user.
|
|
38
|
+
*/
|
|
39
|
+
export type DeviceCodePromptCallback = (deviceCodeDetails: DeviceCodeDetails) => void;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Enables authentication to Azure Active Directory using a device code
|
|
43
|
+
* that the user can enter into https://microsoft.com/devicelogin.
|
|
44
|
+
*/
|
|
45
|
+
export class DeviceCodeCredential implements TokenCredential {
|
|
46
|
+
private identityClient: IdentityClient;
|
|
47
|
+
private tenantId: string;
|
|
48
|
+
private clientId: string;
|
|
49
|
+
private userPromptCallback: DeviceCodePromptCallback;
|
|
50
|
+
private lastTokenResponse: TokenResponse | null = null;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Creates an instance of DeviceCodeCredential with the details needed
|
|
54
|
+
* to initiate the device code authorization flow with Azure Active Directory.
|
|
55
|
+
*
|
|
56
|
+
* @param tenantId The Azure Active Directory tenant (directory) ID or name.
|
|
57
|
+
* @param clientId The client (application) ID of an App Registration in the tenant.
|
|
58
|
+
* @param userPromptCallback A callback function that will be invoked to show
|
|
59
|
+
{@link DeviceCodeDetails} to the user.
|
|
60
|
+
* @param options Options for configuring the client which makes the authentication request.
|
|
61
|
+
*/
|
|
62
|
+
constructor(
|
|
63
|
+
tenantId: string,
|
|
64
|
+
clientId: string,
|
|
65
|
+
userPromptCallback: DeviceCodePromptCallback,
|
|
66
|
+
options?: IdentityClientOptions
|
|
67
|
+
) {
|
|
68
|
+
this.identityClient = new IdentityClient(options);
|
|
69
|
+
this.tenantId = tenantId;
|
|
70
|
+
this.clientId = clientId;
|
|
71
|
+
this.userPromptCallback = userPromptCallback;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private async sendDeviceCodeRequest(
|
|
75
|
+
scope: string,
|
|
76
|
+
options?: GetTokenOptions
|
|
77
|
+
): Promise<DeviceCodeResponse> {
|
|
78
|
+
const webResource = this.identityClient.createWebResource({
|
|
79
|
+
url: `${this.identityClient.authorityHost}/${this.tenantId}/oauth2/v2.0/devicecode`,
|
|
80
|
+
method: "POST",
|
|
81
|
+
disableJsonStringifyOnBody: true,
|
|
82
|
+
deserializationMapper: undefined,
|
|
83
|
+
body: qs.stringify({
|
|
84
|
+
client_id: this.clientId,
|
|
85
|
+
scope
|
|
86
|
+
}),
|
|
87
|
+
headers: {
|
|
88
|
+
Accept: "application/json",
|
|
89
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
90
|
+
},
|
|
91
|
+
abortSignal: options && options.abortSignal
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const response = await this.identityClient.sendRequest(webResource);
|
|
95
|
+
if (!(response.status === 200 || response.status === 201)) {
|
|
96
|
+
throw new AuthenticationError(response.status, response.bodyAsText);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return response.parsedBody as DeviceCodeResponse;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private async pollForToken(
|
|
103
|
+
deviceCodeResponse: DeviceCodeResponse,
|
|
104
|
+
options?: GetTokenOptions
|
|
105
|
+
): Promise<TokenResponse | null> {
|
|
106
|
+
let tokenResponse: TokenResponse | null = null;
|
|
107
|
+
|
|
108
|
+
const webResource = this.identityClient.createWebResource({
|
|
109
|
+
url: `${this.identityClient.authorityHost}/${this.tenantId}/oauth2/v2.0/token`,
|
|
110
|
+
method: "POST",
|
|
111
|
+
disableJsonStringifyOnBody: true,
|
|
112
|
+
deserializationMapper: undefined,
|
|
113
|
+
body: qs.stringify({
|
|
114
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
115
|
+
client_id: this.clientId,
|
|
116
|
+
device_code: deviceCodeResponse.device_code
|
|
117
|
+
}),
|
|
118
|
+
headers: {
|
|
119
|
+
Accept: "application/json",
|
|
120
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
121
|
+
},
|
|
122
|
+
abortSignal: options && options.abortSignal
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
while (tokenResponse === null) {
|
|
126
|
+
try {
|
|
127
|
+
await delay(deviceCodeResponse.interval * 1000);
|
|
128
|
+
|
|
129
|
+
// Check the abort signal before sending the request
|
|
130
|
+
if (options && options.abortSignal && options.abortSignal.aborted) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
tokenResponse = await this.identityClient.sendTokenRequest(webResource);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
if (err instanceof AuthenticationError) {
|
|
137
|
+
switch (err.errorResponse.error) {
|
|
138
|
+
case "authorization_pending":
|
|
139
|
+
break;
|
|
140
|
+
case "authorization_declined":
|
|
141
|
+
return null;
|
|
142
|
+
case "expired_token":
|
|
143
|
+
throw err;
|
|
144
|
+
case "bad_verification_code":
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return tokenResponse;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Authenticates with Azure Active Directory and returns an {@link AccessToken} if
|
|
158
|
+
* successful. If authentication cannot be performed at this time, this method may
|
|
159
|
+
* return null. If an error occurs during authentication, an {@link AuthenticationError}
|
|
160
|
+
* containing failure details will be thrown.
|
|
161
|
+
*
|
|
162
|
+
* @param scopes The list of scopes for which the token will have access.
|
|
163
|
+
* @param options The options used to configure any requests this
|
|
164
|
+
* TokenCredential implementation might make.
|
|
165
|
+
*/
|
|
166
|
+
public async getToken(
|
|
167
|
+
scopes: string | string[],
|
|
168
|
+
options?: GetTokenOptions
|
|
169
|
+
): Promise<AccessToken | null> {
|
|
170
|
+
let tokenResponse: TokenResponse | null = null;
|
|
171
|
+
let scopeString = typeof scopes === "string" ? scopes : scopes.join(" ");
|
|
172
|
+
if (scopeString.indexOf("offline_access") < 0) {
|
|
173
|
+
scopeString += " offline_access";
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Try to use the refresh token first
|
|
177
|
+
if (this.lastTokenResponse && this.lastTokenResponse.refreshToken) {
|
|
178
|
+
tokenResponse = await this.identityClient.refreshAccessToken(
|
|
179
|
+
this.tenantId,
|
|
180
|
+
this.clientId,
|
|
181
|
+
scopeString,
|
|
182
|
+
this.lastTokenResponse.refreshToken,
|
|
183
|
+
undefined, // clientSecret not needed for device code auth
|
|
184
|
+
undefined,
|
|
185
|
+
options);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (tokenResponse === null) {
|
|
189
|
+
const deviceCodeResponse = await this.sendDeviceCodeRequest(scopeString, options);
|
|
190
|
+
|
|
191
|
+
this.userPromptCallback({
|
|
192
|
+
userCode: deviceCodeResponse.user_code,
|
|
193
|
+
verificationUri: deviceCodeResponse.verification_uri,
|
|
194
|
+
message: deviceCodeResponse.message
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
tokenResponse = await this.pollForToken(deviceCodeResponse, options);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
this.lastTokenResponse = tokenResponse;
|
|
201
|
+
return (tokenResponse && tokenResponse.accessToken) || null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
5
|
+
|
|
6
|
+
import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-http";
|
|
7
|
+
import { IdentityClientOptions } from "../client/identityClient";
|
|
8
|
+
|
|
9
|
+
const BrowserNotSupportedError = new Error("EnvironmentCredential is not supported in the browser.");
|
|
10
|
+
|
|
11
|
+
export class EnvironmentCredential implements TokenCredential {
|
|
12
|
+
constructor(options?: IdentityClientOptions) {
|
|
13
|
+
throw BrowserNotSupportedError;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken | null> {
|
|
17
|
+
throw BrowserNotSupportedError;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
|
-
import { AccessToken, TokenCredential,
|
|
4
|
+
import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-http";
|
|
5
5
|
import { IdentityClientOptions } from "../client/identityClient";
|
|
6
6
|
import { ClientSecretCredential } from "./clientSecretCredential";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Enables authentication to Azure Active Directory using client secret
|
|
10
10
|
* details configured in the following environment variables:
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
12
|
* - AZURE_TENANT_ID: The Azure Active Directory tenant (directory) ID.
|
|
13
13
|
* - AZURE_CLIENT_ID: The client (application) ID of an App Registration in the tenant.
|
|
14
14
|
* - AZURE_CLIENT_SECRET: A client secret that was generated for the App Registration.
|
|
15
|
-
*
|
|
15
|
+
*
|
|
16
16
|
* This credential ultimately uses a {@link ClientSecretCredential} to
|
|
17
17
|
* perform the authentication using these details. Please consult the
|
|
18
18
|
* documentation of that class for more details.
|
|
@@ -24,14 +24,10 @@ export class EnvironmentCredential implements TokenCredential {
|
|
|
24
24
|
* client secret details from environment variables. If the expected
|
|
25
25
|
* environment variables are not found at this time, the getToken method
|
|
26
26
|
* will return null when invoked.
|
|
27
|
-
*
|
|
27
|
+
*
|
|
28
28
|
* @param options Options for configuring the client which makes the authentication request.
|
|
29
29
|
*/
|
|
30
30
|
constructor(options?: IdentityClientOptions) {
|
|
31
|
-
if (!isNode) {
|
|
32
|
-
throw "EnvironmentCredential is only supported when running in Node.js.";
|
|
33
|
-
}
|
|
34
|
-
|
|
35
31
|
const tenantId = process.env.AZURE_TENANT_ID,
|
|
36
32
|
clientId = process.env.AZURE_CLIENT_ID,
|
|
37
33
|
clientSecret = process.env.AZURE_CLIENT_SECRET;
|
|
@@ -46,7 +42,7 @@ export class EnvironmentCredential implements TokenCredential {
|
|
|
46
42
|
* successful. If authentication cannot be performed at this time, this method may
|
|
47
43
|
* return null. If an error occurs during authentication, an {@link AuthenticationError}
|
|
48
44
|
* containing failure details will be thrown.
|
|
49
|
-
*
|
|
45
|
+
*
|
|
50
46
|
* @param scopes The list of scopes for which the token will have access.
|
|
51
47
|
* @param options The options used to configure any requests this
|
|
52
48
|
* TokenCredential implementation might make.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import * as msal from "msal";
|
|
5
|
+
import { AccessToken, TokenCredential, GetTokenOptions } from "@azure/core-http";
|
|
6
|
+
import { IdentityClient } from "../client/identityClient";
|
|
7
|
+
import { BrowserLoginStyle, InteractiveBrowserCredentialOptions } from "./interactiveBrowserCredentialOptions";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Enables authentication to Azure Active Directory inside of the web browser
|
|
11
|
+
* using the interactive login flow, either via browser redirects or a popup
|
|
12
|
+
* window.
|
|
13
|
+
*/
|
|
14
|
+
export class InteractiveBrowserCredential implements TokenCredential {
|
|
15
|
+
private loginStyle: BrowserLoginStyle;
|
|
16
|
+
private msalConfig: msal.Configuration;
|
|
17
|
+
private msalObject: msal.UserAgentApplication;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates an instance of the InteractiveBrowserCredential with the
|
|
21
|
+
* details needed to authenticate against Azure Active Directory with
|
|
22
|
+
* a user identity.
|
|
23
|
+
*
|
|
24
|
+
* @param tenantId The Azure Active Directory tenant (directory) ID.
|
|
25
|
+
* @param clientId The client (application) ID of an App Registration in the tenant.
|
|
26
|
+
* @param options Options for configuring the client which makes the authentication request.
|
|
27
|
+
*/
|
|
28
|
+
constructor(
|
|
29
|
+
tenantId: string,
|
|
30
|
+
clientId: string,
|
|
31
|
+
options?: InteractiveBrowserCredentialOptions
|
|
32
|
+
) {
|
|
33
|
+
options = { ...IdentityClient.getDefaultOptions(), ...options };
|
|
34
|
+
|
|
35
|
+
this.loginStyle = options.loginStyle || "popup";
|
|
36
|
+
if (["redirect", "popup"].indexOf(this.loginStyle) === -1) {
|
|
37
|
+
throw new Error(`Invalid loginStyle: ${options.loginStyle}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.msalConfig = {
|
|
41
|
+
auth: {
|
|
42
|
+
clientId: clientId,
|
|
43
|
+
authority: `${options.authorityHost}/${tenantId}`,
|
|
44
|
+
...options.redirectUri && { redirectUri: options.redirectUri},
|
|
45
|
+
...options.postLogoutRedirectUri && { redirectUri: options.postLogoutRedirectUri }
|
|
46
|
+
},
|
|
47
|
+
cache: {
|
|
48
|
+
cacheLocation: "localStorage",
|
|
49
|
+
storeAuthStateInCookie: true
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
this.msalObject = new msal.UserAgentApplication(this.msalConfig);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private login(): Promise<msal.AuthResponse> {
|
|
57
|
+
switch (this.loginStyle) {
|
|
58
|
+
case "redirect": {
|
|
59
|
+
const loginPromise = new Promise<msal.AuthResponse>((resolve, reject) => {
|
|
60
|
+
this.msalObject.handleRedirectCallback(resolve, reject);
|
|
61
|
+
});
|
|
62
|
+
this.msalObject.loginRedirect();
|
|
63
|
+
return loginPromise;
|
|
64
|
+
}
|
|
65
|
+
case "popup":
|
|
66
|
+
return this.msalObject.loginPopup();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private async acquireToken(authParams: msal.AuthenticationParameters): Promise<msal.AuthResponse | undefined> {
|
|
71
|
+
let authResponse: msal.AuthResponse | undefined;
|
|
72
|
+
try {
|
|
73
|
+
authResponse = await this.msalObject.acquireTokenSilent(authParams);
|
|
74
|
+
} catch (err) {
|
|
75
|
+
if (err instanceof msal.AuthError) {
|
|
76
|
+
switch (err.errorCode) {
|
|
77
|
+
case "consent_required":
|
|
78
|
+
case "interaction_required":
|
|
79
|
+
case "login_required":
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let authPromise: Promise<msal.AuthResponse> | undefined;
|
|
88
|
+
if (authResponse === undefined) {
|
|
89
|
+
switch (this.loginStyle) {
|
|
90
|
+
case "redirect":
|
|
91
|
+
authPromise = new Promise((resolve, reject) => {
|
|
92
|
+
this.msalObject.handleRedirectCallback(resolve, reject);
|
|
93
|
+
});
|
|
94
|
+
this.msalObject.acquireTokenRedirect(authParams);
|
|
95
|
+
break;
|
|
96
|
+
case "popup":
|
|
97
|
+
authPromise = this.msalObject.acquireTokenPopup(authParams);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
authResponse = authPromise && await authPromise;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return authResponse;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @param scopes The list of scopes for which the token will have access.
|
|
110
|
+
* @param options The options used to configure any requests this
|
|
111
|
+
* TokenCredential implementation might make.
|
|
112
|
+
*/
|
|
113
|
+
async getToken(
|
|
114
|
+
scopes: string | string[],
|
|
115
|
+
options?: GetTokenOptions // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
116
|
+
): Promise<AccessToken | null> {
|
|
117
|
+
if (!this.msalObject.getAccount()) {
|
|
118
|
+
await this.login();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const authResponse = await this.acquireToken({
|
|
122
|
+
scopes: Array.isArray(scopes) ? scopes : scopes.split(',')
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
if (authResponse) {
|
|
126
|
+
return {
|
|
127
|
+
token: authResponse.accessToken,
|
|
128
|
+
expiresOnTimestamp: authResponse.expiresOn.getTime()
|
|
129
|
+
};
|
|
130
|
+
} else {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
5
|
+
|
|
6
|
+
import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http";
|
|
7
|
+
import { InteractiveBrowserCredentialOptions } from "./interactiveBrowserCredentialOptions";
|
|
8
|
+
|
|
9
|
+
const BrowserNotSupportedError = new Error("InteractiveBrowserCredential is not supported in Node.js.");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Enables authentication to Azure Active Directory inside of the web browser
|
|
13
|
+
* using the interactive login flow, either via browser redirects or a popup
|
|
14
|
+
* window. This credential is not currently supported in Node.js.
|
|
15
|
+
*/
|
|
16
|
+
export class InteractiveBrowserCredential implements TokenCredential {
|
|
17
|
+
constructor(
|
|
18
|
+
tenantId: string,
|
|
19
|
+
clientId: string,
|
|
20
|
+
options?: InteractiveBrowserCredentialOptions
|
|
21
|
+
) {
|
|
22
|
+
throw BrowserNotSupportedError;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public getToken(
|
|
26
|
+
scopes: string | string[],
|
|
27
|
+
options?: GetTokenOptions
|
|
28
|
+
): Promise<AccessToken | null> {
|
|
29
|
+
throw BrowserNotSupportedError;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import { IdentityClientOptions } from "../client/identityClient";
|
|
5
|
+
|
|
6
|
+
export type BrowserLoginStyle = "redirect" | "popup";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Defines options for the InteractiveBrowserCredential class.
|
|
10
|
+
*/
|
|
11
|
+
export interface InteractiveBrowserCredentialOptions extends IdentityClientOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Specifies whether a redirect or a popup window should be used to
|
|
14
|
+
* initiate the user authentication flow. Possible values are "redirect"
|
|
15
|
+
* or "popup" (default).
|
|
16
|
+
*/
|
|
17
|
+
loginStyle?: BrowserLoginStyle;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Gets the redirect URI of the application. This should be same as the value
|
|
21
|
+
* in the application registration portal. Defaults to `window.location.href`.
|
|
22
|
+
*/
|
|
23
|
+
redirectUri?: string | (() => string);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Gets the URI to which the user will be redirected when logging out.
|
|
27
|
+
* Defaults to `window.location.href`.
|
|
28
|
+
*/
|
|
29
|
+
postLogoutRedirectUri?: string | (() => string);
|
|
30
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
5
|
+
|
|
6
|
+
import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http";
|
|
7
|
+
import { IdentityClientOptions } from "../client/identityClient";
|
|
8
|
+
|
|
9
|
+
const BrowserNotSupportedError = new Error("ManagedIdentityCredential is not supported in the browser.");
|
|
10
|
+
|
|
11
|
+
export class ManagedIdentityCredential implements TokenCredential {
|
|
12
|
+
constructor(clientId?: string, options?: IdentityClientOptions) {
|
|
13
|
+
throw BrowserNotSupportedError;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async getToken(
|
|
17
|
+
scopes: string | string[],
|
|
18
|
+
options?: GetTokenOptions
|
|
19
|
+
): Promise<AccessToken | null> {
|
|
20
|
+
throw BrowserNotSupportedError;
|
|
21
|
+
}
|
|
22
|
+
}
|