@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.

Files changed (88) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +50 -23
  3. package/browser/identity.js +9828 -0
  4. package/browser/identity.js.map +1 -0
  5. package/browser/identity.min.js +2 -0
  6. package/browser/identity.min.js.map +1 -0
  7. package/dist/index.js +475 -205
  8. package/dist/index.js.map +1 -1
  9. package/dist-esm/src/client/errors.d.ts +1 -1
  10. package/dist-esm/src/client/errors.d.ts.map +1 -1
  11. package/dist-esm/src/client/errors.js +9 -1
  12. package/dist-esm/src/client/errors.js.map +1 -1
  13. package/dist-esm/src/client/identityClient.d.ts +20 -17
  14. package/dist-esm/src/client/identityClient.d.ts.map +1 -1
  15. package/dist-esm/src/client/identityClient.js +42 -206
  16. package/dist-esm/src/client/identityClient.js.map +1 -1
  17. package/dist-esm/src/credentials/clientCertificateCredential.browser.d.ts +7 -0
  18. package/dist-esm/src/credentials/clientCertificateCredential.browser.d.ts.map +1 -0
  19. package/dist-esm/src/credentials/clientCertificateCredential.browser.js +12 -0
  20. package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -0
  21. package/dist-esm/src/credentials/clientCertificateCredential.d.ts +5 -5
  22. package/dist-esm/src/credentials/clientCertificateCredential.d.ts.map +1 -1
  23. package/dist-esm/src/credentials/clientCertificateCredential.js +59 -5
  24. package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
  25. package/dist-esm/src/credentials/clientSecretCredential.d.ts +3 -3
  26. package/dist-esm/src/credentials/clientSecretCredential.d.ts.map +1 -1
  27. package/dist-esm/src/credentials/clientSecretCredential.js +27 -4
  28. package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
  29. package/dist-esm/src/credentials/deviceCodeCredential.browser.d.ts +7 -0
  30. package/dist-esm/src/credentials/deviceCodeCredential.browser.d.ts.map +1 -0
  31. package/dist-esm/src/credentials/deviceCodeCredential.browser.js +12 -0
  32. package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -0
  33. package/dist-esm/src/credentials/deviceCodeCredential.d.ts +67 -0
  34. package/dist-esm/src/credentials/deviceCodeCredential.d.ts.map +1 -0
  35. package/dist-esm/src/credentials/deviceCodeCredential.js +139 -0
  36. package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -0
  37. package/dist-esm/src/credentials/environmentCredential.browser.d.ts +7 -0
  38. package/dist-esm/src/credentials/environmentCredential.browser.d.ts.map +1 -0
  39. package/dist-esm/src/credentials/environmentCredential.browser.js +12 -0
  40. package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -0
  41. package/dist-esm/src/credentials/environmentCredential.d.ts.map +1 -1
  42. package/dist-esm/src/credentials/environmentCredential.js +0 -4
  43. package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
  44. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.d.ts +32 -0
  45. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.d.ts.map +1 -0
  46. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +112 -0
  47. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -0
  48. package/dist-esm/src/credentials/interactiveBrowserCredential.d.ts +12 -0
  49. package/dist-esm/src/credentials/interactiveBrowserCredential.d.ts.map +1 -0
  50. package/dist-esm/src/credentials/interactiveBrowserCredential.js +17 -0
  51. package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -0
  52. package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.d.ts +24 -0
  53. package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.d.ts.map +1 -0
  54. package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js +3 -0
  55. package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -0
  56. package/dist-esm/src/credentials/managedIdentityCredential.browser.d.ts +7 -0
  57. package/dist-esm/src/credentials/managedIdentityCredential.browser.d.ts.map +1 -0
  58. package/dist-esm/src/credentials/managedIdentityCredential.browser.js +15 -0
  59. package/dist-esm/src/credentials/managedIdentityCredential.browser.js.map +1 -0
  60. package/dist-esm/src/credentials/managedIdentityCredential.d.ts +10 -1
  61. package/dist-esm/src/credentials/managedIdentityCredential.d.ts.map +1 -1
  62. package/dist-esm/src/credentials/managedIdentityCredential.js +144 -2
  63. package/dist-esm/src/credentials/managedIdentityCredential.js.map +1 -1
  64. package/dist-esm/src/credentials/usernamePasswordCredential.d.ts +39 -0
  65. package/dist-esm/src/credentials/usernamePasswordCredential.d.ts.map +1 -0
  66. package/dist-esm/src/credentials/usernamePasswordCredential.js +67 -0
  67. package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -0
  68. package/dist-esm/src/index.d.ts +4 -0
  69. package/dist-esm/src/index.d.ts.map +1 -1
  70. package/dist-esm/src/index.js +3 -0
  71. package/dist-esm/src/index.js.map +1 -1
  72. package/package.json +32 -14
  73. package/src/client/errors.ts +11 -3
  74. package/src/client/identityClient.ts +64 -246
  75. package/src/credentials/clientCertificateCredential.browser.ts +27 -0
  76. package/src/credentials/clientCertificateCredential.ts +72 -22
  77. package/src/credentials/clientSecretCredential.ts +32 -17
  78. package/src/credentials/deviceCodeCredential.browser.ts +27 -0
  79. package/src/credentials/deviceCodeCredential.ts +203 -0
  80. package/src/credentials/environmentCredential.browser.ts +19 -0
  81. package/src/credentials/environmentCredential.ts +5 -9
  82. package/src/credentials/interactiveBrowserCredential.browser.ts +134 -0
  83. package/src/credentials/interactiveBrowserCredential.ts +31 -0
  84. package/src/credentials/interactiveBrowserCredentialOptions.ts +30 -0
  85. package/src/credentials/managedIdentityCredential.browser.ts +22 -0
  86. package/src/credentials/managedIdentityCredential.ts +179 -8
  87. package/src/credentials/usernamePasswordCredential.ts +83 -0
  88. package/src/index.ts +4 -0
@@ -1,26 +1,197 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
- import { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-http";
4
+ import qs from "qs";
5
+ import {
6
+ AccessToken,
7
+ GetTokenOptions,
8
+ RequestPrepareOptions,
9
+ RestError,
10
+ TokenCredential
11
+ } from "@azure/core-http";
5
12
  import { IdentityClientOptions, IdentityClient } from "../client/identityClient";
6
13
 
14
+ const DefaultScopeSuffix = "/.default";
15
+ export const ImdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";
16
+ export const ImdsApiVersion = "2018-02-01";
17
+ export const AppServiceMsiApiVersion = "2017-09-01";
18
+
7
19
  /**
8
20
  * Attempts authentication using a managed identity that has been assigned
9
21
  * to the deployment environment. This authentication type works in Azure VMs,
10
22
  * App Service and Azure Functions applications, and inside of Azure Cloud Shell.
11
- *
23
+ *
12
24
  * More information about configuring managed identities can be found here:
13
- *
25
+ *
14
26
  * https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
15
27
  */
16
28
  export class ManagedIdentityCredential implements TokenCredential {
17
29
  private identityClient: IdentityClient;
18
- private _clientId: string | undefined;
30
+ private clientId: string | undefined;
19
31
  private isEndpointUnavailable: boolean | null = null;
20
32
 
21
33
  constructor(clientId?: string, options?: IdentityClientOptions) {
22
34
  this.identityClient = new IdentityClient(options);
23
- this._clientId = clientId;
35
+ this.clientId = clientId;
36
+ }
37
+
38
+ private mapScopesToResource(scopes: string | string[]): string {
39
+ let scope = "";
40
+ if (Array.isArray(scopes)) {
41
+ if (scopes.length !== 1) {
42
+ throw "To convert to a resource string the specified array must be exactly length 1";
43
+ }
44
+
45
+ scope = scopes[0];
46
+ } else if (typeof scopes === "string") {
47
+ scope = scopes;
48
+ }
49
+
50
+ if (!scope.endsWith(DefaultScopeSuffix)) {
51
+ return scope;
52
+ }
53
+
54
+ return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
55
+ }
56
+
57
+ private createImdsAuthRequest(resource: string, clientId?: string): RequestPrepareOptions {
58
+ const queryParameters: any = {
59
+ resource,
60
+ "api-version": ImdsApiVersion
61
+ };
62
+
63
+ if (clientId) {
64
+ queryParameters.client_id = clientId;
65
+ }
66
+
67
+ return {
68
+ url: ImdsEndpoint,
69
+ method: "GET",
70
+ queryParameters,
71
+ headers: {
72
+ Accept: "application/json",
73
+ Metadata: true
74
+ }
75
+ };
76
+ }
77
+
78
+ private createAppServiceMsiAuthRequest(resource: string, clientId?: string): RequestPrepareOptions {
79
+ const queryParameters: any = {
80
+ resource,
81
+ "api-version": AppServiceMsiApiVersion,
82
+ };
83
+
84
+ if (clientId) {
85
+ queryParameters.client_id = clientId;
86
+ }
87
+
88
+ return {
89
+ url: process.env.MSI_ENDPOINT,
90
+ method: "GET",
91
+ queryParameters,
92
+ headers: {
93
+ Accept: "application/json",
94
+ secret: process.env.MSI_SECRET
95
+ }
96
+ };
97
+ }
98
+
99
+ private createCloudShellMsiAuthRequest(resource: string, clientId?: string): RequestPrepareOptions {
100
+ const body: any = {
101
+ resource
102
+ };
103
+
104
+ if (clientId) {
105
+ body.client_id = clientId;
106
+ }
107
+
108
+ return {
109
+ url: process.env.MSI_ENDPOINT,
110
+ method: "POST",
111
+ body: qs.stringify(body),
112
+ headers: {
113
+ Accept: "application/json",
114
+ Metadata: true,
115
+ "Content-Type": "application/x-www-form-urlencoded"
116
+ }
117
+ };
118
+ }
119
+
120
+ private async pingImdsEndpoint(resource: string, clientId?: string): Promise<boolean> {
121
+ const request = this.createImdsAuthRequest(resource, clientId);
122
+
123
+ // This will always be populated, but let's make TypeScript happy
124
+ if (request.headers) {
125
+ // Remove the Metadata header to invoke a request error from
126
+ // IMDS endpoint
127
+ delete request.headers.Metadata;
128
+ }
129
+
130
+ // Create a request with a 500 msec timeout since we expect that
131
+ // not having a "Metadata" header should cause an error to be
132
+ // returned quickly from the endpoint, proving its availability.
133
+ const webResource = this.identityClient.createWebResource(request);
134
+ webResource.timeout = 500;
135
+
136
+ try {
137
+ await this.identityClient.sendRequest(webResource);
138
+ } catch (err) {
139
+ if (err instanceof RestError && err.code === RestError.REQUEST_SEND_ERROR) {
140
+ // Either request failed or IMDS endpoint isn't available
141
+ return false;
142
+ }
143
+ }
144
+
145
+ // If we received any response, the endpoint is available
146
+ return true;
147
+ }
148
+
149
+ private async authenticateManagedIdentity(
150
+ scopes: string | string[],
151
+ checkIfImdsEndpointAvailable: boolean,
152
+ clientId?: string,
153
+ getTokenOptions?: GetTokenOptions
154
+ ): Promise<AccessToken | null> {
155
+ let authRequestOptions: RequestPrepareOptions;
156
+ const resource = this.mapScopesToResource(scopes);
157
+ let expiresInParser: ((requestBody: any) => number) | undefined;
158
+
159
+ // Detect which type of environment we are running in
160
+ if (process.env.MSI_ENDPOINT) {
161
+ if (process.env.MSI_SECRET) {
162
+ // Running in App Service
163
+ authRequestOptions = this.createAppServiceMsiAuthRequest(resource, clientId);
164
+ expiresInParser = (requestBody: any) => {
165
+ // Parse a date format like "06/20/2019 02:57:58 +00:00" and
166
+ // convert it into a JavaScript-formatted date
167
+ const m = requestBody.expires_on.match(/(\d\d)\/(\d\d)\/(\d\d\d\d) (\d\d):(\d\d):(\d\d) (\+|-)(\d\d):(\d\d)/)
168
+ return Date.parse(`${m[3]}-${m[1]}-${m[2]}T${m[4]}:${m[5]}:${m[6]}${m[7]}${m[8]}:${m[9]}`)
169
+ };
170
+ } else {
171
+ // Running in Cloud Shell
172
+ authRequestOptions = this.createCloudShellMsiAuthRequest(resource, clientId);
173
+ }
174
+ } else {
175
+ // Ping the IMDS endpoint to see if it's available
176
+ if (!checkIfImdsEndpointAvailable || await this.pingImdsEndpoint(resource, clientId)) {
177
+ // Running in an Azure VM
178
+ authRequestOptions = this.createImdsAuthRequest(resource, clientId);
179
+ } else {
180
+ // Returning null tells the ManagedIdentityCredential that
181
+ // no MSI authentication endpoints are available
182
+ return null;
183
+ }
184
+ }
185
+
186
+ const webResource = this.identityClient.createWebResource({
187
+ disableJsonStringifyOnBody: true,
188
+ deserializationMapper: undefined,
189
+ abortSignal: getTokenOptions && getTokenOptions.abortSignal,
190
+ ...authRequestOptions
191
+ });
192
+
193
+ const tokenResponse = await this.identityClient.sendTokenRequest(webResource, expiresInParser);
194
+ return (tokenResponse && tokenResponse.accessToken) || null;
24
195
  }
25
196
 
26
197
  /**
@@ -28,7 +199,7 @@ export class ManagedIdentityCredential implements TokenCredential {
28
199
  * successful. If authentication cannot be performed at this time, this method may
29
200
  * return null. If an error occurs during authentication, an {@link AuthenticationError}
30
201
  * containing failure details will be thrown.
31
- *
202
+ *
32
203
  * @param scopes The list of scopes for which the token will have access.
33
204
  * @param options The options used to configure any requests this
34
205
  * TokenCredential implementation might make.
@@ -44,10 +215,10 @@ export class ManagedIdentityCredential implements TokenCredential {
44
215
  // the endpoint is available and need to check for it.
45
216
  if (this.isEndpointUnavailable !== true) {
46
217
  result =
47
- await this.identityClient.authenticateManagedIdentity(
218
+ await this.authenticateManagedIdentity(
48
219
  scopes,
49
220
  this.isEndpointUnavailable === null,
50
- this._clientId,
221
+ this.clientId,
51
222
  options);
52
223
 
53
224
  // If authenticateManagedIdentity returns null, it means no MSI
@@ -0,0 +1,83 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import qs from "qs";
5
+ import { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http";
6
+ import { IdentityClientOptions, IdentityClient } from "../client/identityClient";
7
+
8
+ /**
9
+ * Enables authentication to Azure Active Directory with a user's
10
+ * username and password. This credential requires a high degree of
11
+ * trust so you should only use it when other, more secure credential
12
+ * types can't be used.
13
+ */
14
+ export class UsernamePasswordCredential implements TokenCredential {
15
+ private identityClient: IdentityClient;
16
+ private tenantId: string;
17
+ private clientId: string;
18
+ private username: string;
19
+ private password: string;
20
+
21
+ /**
22
+ * Creates an instance of the UsernamePasswordCredential with the details
23
+ * needed to authenticate against Azure Active Directory with a username
24
+ * and password.
25
+ *
26
+ * @param tenantIdOrName The Azure Active Directory tenant (directory) ID or name.
27
+ * @param clientId The client (application) ID of an App Registration in the tenant.
28
+ * @param username The user account's e-mail address (user name).
29
+ * @param password The user account's account password
30
+ * @param options Options for configuring the client which makes the authentication request.
31
+ */
32
+ constructor(
33
+ tenantIdOrName: string,
34
+ clientId: string,
35
+ username: string,
36
+ password: string,
37
+ options?: IdentityClientOptions
38
+ ) {
39
+ this.identityClient = new IdentityClient(options);
40
+ this.tenantId = tenantIdOrName;
41
+ this.clientId = clientId;
42
+ this.username = username;
43
+ this.password = password;
44
+ }
45
+
46
+ /**
47
+ * Authenticates with Azure Active Directory and returns an {@link AccessToken} if
48
+ * successful. If authentication cannot be performed at this time, this method may
49
+ * return null. If an error occurs during authentication, an {@link AuthenticationError}
50
+ * containing failure details will be thrown.
51
+ *
52
+ * @param scopes The list of scopes for which the token will have access.
53
+ * @param options The options used to configure any requests this
54
+ * TokenCredential implementation might make.
55
+ */
56
+ public async getToken(
57
+ scopes: string | string[],
58
+ options?: GetTokenOptions
59
+ ): Promise<AccessToken | null> {
60
+ const webResource = this.identityClient.createWebResource({
61
+ url: `${this.identityClient.authorityHost}/${this.tenantId}/oauth2/v2.0/token`,
62
+ method: "POST",
63
+ disableJsonStringifyOnBody: true,
64
+ deserializationMapper: undefined,
65
+ body: qs.stringify({
66
+ response_type: "token",
67
+ grant_type: "password",
68
+ client_id: this.clientId,
69
+ username: this.username,
70
+ password: this.password,
71
+ scope: typeof scopes === "string" ? scopes : scopes.join(" ")
72
+ }),
73
+ headers: {
74
+ Accept: "application/json",
75
+ "Content-Type": "application/x-www-form-urlencoded"
76
+ },
77
+ abortSignal: options && options.abortSignal
78
+ });
79
+
80
+ const tokenResponse = await this.identityClient.sendTokenRequest(webResource);
81
+ return (tokenResponse && tokenResponse.accessToken) || null;
82
+ }
83
+ }
package/src/index.ts CHANGED
@@ -9,8 +9,12 @@ export { IdentityClientOptions } from "./client/identityClient";
9
9
  export { EnvironmentCredential } from "./credentials/environmentCredential";
10
10
  export { ClientSecretCredential } from "./credentials/clientSecretCredential";
11
11
  export { ClientCertificateCredential } from "./credentials/clientCertificateCredential";
12
+ export { InteractiveBrowserCredential } from "./credentials/interactiveBrowserCredential";
13
+ export { InteractiveBrowserCredentialOptions, BrowserLoginStyle } from "./credentials/interactiveBrowserCredentialOptions";
12
14
  export { ManagedIdentityCredential } from "./credentials/managedIdentityCredential";
15
+ export { DeviceCodeCredential } from "./credentials/deviceCodeCredential";
13
16
  export { DefaultAzureCredential } from "./credentials/defaultAzureCredential";
17
+ export { UsernamePasswordCredential } from "./credentials/usernamePasswordCredential";
14
18
  export { AuthenticationError, AggregateAuthenticationError } from "./client/errors";
15
19
 
16
20
  export { TokenCredential, GetTokenOptions, AccessToken } from "@azure/core-http";