first commit
SAP-ERP Portal CI/CD / build (push) Failing after 5m20s

This commit is contained in:
John
2026-09-23 17:31:02 +05:30
commit 69b4e68baf
51657 changed files with 3864077 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+375
View File
@@ -0,0 +1,375 @@
# Azure Identity client library for JavaScript
The Azure Identity library provides [Azure Active Directory (Azure AD)](https://docs.microsoft.com/azure/active-directory/fundamentals/active-directory-whatis) token authentication through a set of convenient [TokenCredential](https://docs.microsoft.com/javascript/api/@azure/core-auth/tokencredential) implementations.
For examples of various credentials, see the [Azure Identity examples page](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md).
Key links:
- [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity)
- [Package (npm)](https://www.npmjs.com/package/@azure/identity)
- [API Reference Documentation](https://docs.microsoft.com/javascript/api/@azure/identity)
- [Product documentation](https://azure.microsoft.com/services/active-directory/)
- [Samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/v2)
## Getting started
### Migrate from v1 to v2 of @azure/identity
If you're using v1 of `@azure/identity`, see the [migration guide](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/migration-v1-v2.md) to update to v2.
### Currently supported environments
- [LTS versions of Node.js](https://nodejs.org/about/releases/)
- **Note:** If your application runs on Node.js v8 or lower and you cannot upgrade your Node.js version to latest stable version, then pin your `@azure/identity` dependency to version 1.1.0.
- Latest versions of Safari, Chrome, Edge, and Firefox.
- **Note**: Among the different credentials exported in this library, `InteractiveBrowserCredential` is the only one that is supported in the browser.
See our [support policy](https://github.com/Azure/azure-sdk-for-js/blob/main/SUPPORT.md) for more details.
### Install the package
Install Azure Identity with `npm`:
```sh
npm install --save @azure/identity
```
### Prerequisites
- An [Azure subscription](https://azure.microsoft.com/free/).
- Optional: The [Azure CLI][azure_cli] and/or [Azure PowerShell][azure_powershell] can also be useful for authenticating in a development environment and managing account roles.
### When to use @azure/identity
The credential classes exposed by `@azure/identity` are focused on providing the most straightforward way to authenticate the Azure SDK clients locally, in your development environments, and in production. We aim for simplicity and reasonable support of the authentication protocols to cover most of the authentication scenarios possible on Azure. We're actively expanding to cover more scenarios. For a full list of the credentials offered, see the [Credential Classes](#credential-classes) section.
All credential types provided by `@azure/identity` are supported in Node.js. For browsers, `InteractiveBrowserCredential` is the credential type to be used for basic authentication scenarios.
Most of the credential types offered by `@azure/identity` use the [Microsoft Authentication Library for JavaScript (MSAL.js)](https://github.com/AzureAD/microsoft-authentication-library-for-js). Specifically, we use the v2 MSAL.js libraries, which use [OAuth 2.0 Authorization Code Flow with PKCE](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) and are [OpenID-compliant](https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc). While `@azure/identity` focuses on simplicity, the MSAL.js libraries, such as [@azure/msal-common](https://www.npmjs.com/package/@azure/msal-common), [@azure/msal-node](https://www.npmjs.com/package/@azure/msal-node), and [@azure/msal-browser](https://www.npmjs.com/package/@azure/msal-browser), are designed to provide robust support for the authentication protocols that Azure supports.
#### When to use something else
The `@azure/identity` credential types are implementations of [@azure/core-auth](https://www.npmjs.com/package/@azure/core-auth)'s `TokenCredential` class. In principle, any object with a `getToken` method that satisfies `getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken | null>` will work as a `TokenCredential`. This means developers can write their own credential types to support authentication cases not covered by `@azure/identity`. To learn more, see [Custom Credentials](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#custom-credentials).
Though our credential types support many advanced cases, developers may want full control of the authentication protocol. For that use case, we recommend using [Microsoft Authentication Library for JavaScript (MSAL.js)](https://github.com/AzureAD/microsoft-authentication-library-for-js) directly. You can read more through the following links:
- We portray some advanced use cases of `@azure/identity` on the [Azure Identity Examples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md) page.
- There, we specifically have an [Advanced Examples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#advanced-examples) section.
- We also have a section that shows how to [Authenticate with MSAL directly](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-msal-directly).
For advanced authentication workflows in the browser, we have a section where we showcase how to use the [@azure/msal-browser](https://www.npmjs.com/package/@azure/msal-browser) library directly to authenticate Azure SDK clients.
### Authenticate the client in development environment
While we recommend using managed identity or service principal authentication in your production application, it is typical for a developer to use their own account for authenticating calls to Azure services when debugging and executing code locally. There are several developer tools which can be used to perform this authentication in your development environment.
#### Authenticating via the Azure CLI
Applications using the `AzureCliCredential`, whether directly or via the `DefaultAzureCredential`, can use the Azure CLI account to authenticate calls in the application when running locally.
To authenticate with the [Azure CLI][azure_cli] users can run the command `az login`. For users running on a system with a default web browser the Azure cli will launch the browser to authenticate the user.
![Azure CLI Account Sign In][azureclilogin_image]
For systems without a default web browser, the `az login` command will use the device code authentication flow. The user can also force the Azure CLI to use the device code flow rather than launching a browser by specifying the `--use-device-code` argument.
![Azure CLI Account Device Code Sign In][azureclilogindevicecode_image]
#### Authenticating via Azure PowerShell
Applications using the `AzurePowerShellCredential`, whether directly or via the `DefaultAzureCredential`, can use the account connected to Azure PowerShell to authenticate calls in the application when running locally.
To authenticate with [Azure PowerShell][azure_powershell] users can run the `Connect-AzAccount` cmdlet. By default, ike the Azure CLI, `Connect-AzAccount` will launch the default web browser to authenticate a user account.
![Azure PowerShell Account Sign In][azurepowershelllogin_image]
If interactive authentication cannot be supported in the session, then the `-UseDeviceAuthentication` argument will force the cmdlet to use a device code authentication flow instead, similar to the corresponding option in the Azure CLI credential.
#### Authenticate via Visual Studio Code
Developers using Visual Studio Code can use the [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account) to authenticate via the editor. Apps using `DefaultAzureCredential` or `VisualStudioCodeCredential` can then use this account to authenticate calls in their app when running locally.
To authenticate in Visual Studio Code, ensure the Azure Account extension is installed. Once installed, open the **Command Palette** and run the **Azure: Sign In** command.
Additionally, use the [`@azure/identity-vscode`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode) plugin package. This package provides the dependencies of `VisualStudioCodeCredential` and enables it. See [Plugins](##plugins).
It's a [known issue](https://github.com/Azure/azure-sdk-for-js/issues/20500) that `VisualStudioCodeCredential` doesn't work with [Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account) versions newer than **0.9.11**. A long-term fix to this problem is in progress. In the meantime, consider [authenticating via the Azure CLI](#authenticating-via-the-azure-cli).
### Authenticate the client in browsers
To authenticate Azure SDKs within web browsers, we currently offer the `InteractiveBrowserCredential`, which can be set to use redirection or popups to complete the authentication flow. It is necessary to [create an Azure App Registration](https://docs.microsoft.com/azure/active-directory/develop/scenario-spa-app-registration) in the portal for your web application first.
## Key concepts
If this is your first time using `@azure/identity` or the Microsoft identity platform (Azure Active Directory), we recommend that you read [Using `@azure/identity` with Microsoft Identity Platform](https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/using-azure-identity.md) first. This document will give you a deeper understanding of the platform and how to configure your Azure account correctly.
### Credentials
A credential is a class which contains or can obtain the data needed for a service client to authenticate requests. Service clients across Azure SDK accept credentials when they are constructed, and service clients use those credentials to authenticate requests to the service.
The Azure Identity library focuses on OAuth authentication with Azure Active directory, and it offers a variety of credential classes capable of acquiring an AAD token to authenticate service requests. All of the credential classes in this library are implementations of the [TokenCredential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-auth/src/tokenCredential.ts) abstract class, and any of them can be used by to construct service clients capable of authenticating with a TokenCredential.
See [Credential Classes](#credential-classes).
### DefaultAzureCredential
The `DefaultAzureCredential` is appropriate for most scenarios where the application is intended to ultimately be run in the Azure Cloud. This is because the `DefaultAzureCredential` combines credentials commonly used to authenticate when deployed with credentials used to authenticate in a development environment.
> Note: `DefaultAzureCredential` is intended to simplify getting started with the SDK by handling common scenarios with reasonable default behaviors. Developers who want more control or whose scenario isn't served by the default settings should use other credential types.
If used from Node.js, the `DefaultAzureCredential` will attempt to authenticate via the following mechanisms in order:
![DefaultAzureCredential authentication flow][defaultauthflow_image]
1. **Environment** - The `DefaultAzureCredential` will read account information specified via [environment variables](#environment-variables) and use it to authenticate.
1. **Managed Identity** - If the application is deployed to an Azure host with Managed Identity enabled, the `DefaultAzureCredential` will authenticate with that account.
1. **Visual Studio Code** - If the developer has authenticated with the [Visual Studio Code Azure Account extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account), the `DefaultAzureCredential` will authenticate using that account.
- In `@azure/identity` version 2.0 or later, the [`@azure/identity-vscode`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode) package must be installed for the Visual Studio Code authentication to work.
1. **Azure CLI** - If the developer has authenticated an account via the Azure CLI `az login` command, the `DefaultAzureCredential` will authenticate with that account.
1. **Azure PowerShell** - If the developer has authenticated using the Azure PowerShell module `Connect-AzAccount` command, the `DefaultAzureCredential` will authenticate with that account.
## Plugins
Azure Identity for JavaScript provides a plugin API that allows us to provide certain functionality through separate _plugin packages_. The `@azure/identity` package exports a top-level function (`useIdentityPlugin`) that can be used to enable a plugin. We provide two plugin packages:
- [`@azure/identity-cache-persistence`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-cache-persistence), which provides persistent token caching in Node.js using a native secure storage system provided by your operating system. This plugin allows cached `access_token` values to persist across sessions, meaning that an interactive login flow does not need to be repeated as long as a cached token is available.
- [`@azure/identity-vscode`](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity-vscode), which provides the dependencies of `VisualStudioCodeCredential` and enables it. Without this plugin, the `VisualStudioCodeCredential` in this package will throw a `CredentialUnavailableError`. The plugin provides the underlying implementation of this credential, enabling it for use both on its own and as part of the `DefaultAzureCredential` described above.
## Environment Variables
`DefaultAzureCredential` and `EnvironmentCredential` can be configured with environment variables. Each type of authentication requires values for specific variables:
#### Service principal with secret
| variable name | value |
| --------------------- | ----------------------------------------------------- |
| `AZURE_CLIENT_ID` | id of an Azure Active Directory application |
| `AZURE_TENANT_ID` | id of the application's Azure Active Directory tenant |
| `AZURE_CLIENT_SECRET` | one of the application's client secrets |
#### Service principal with certificate
| variable name | value |
| ------------------------------- | ------------------------------------------------------------------------------------------ |
| `AZURE_CLIENT_ID` | id of an Azure Active Directory application |
| `AZURE_TENANT_ID` | id of the application's Azure Active Directory tenant |
| `AZURE_CLIENT_CERTIFICATE_PATH` | path to a PEM-encoded certificate file including private key (without password protection) |
#### Username and password
| variable name | value |
| ----------------- | ------------------------------------------- |
| `AZURE_CLIENT_ID` | id of an Azure Active Directory application |
| `AZURE_USERNAME` | a username (usually an email address) |
| `AZURE_PASSWORD` | that user's password |
Configuration is attempted in the above order. For example, if values for a client secret and certificate are both present, the client secret will be used.
## Examples
You can find more examples of using various credentials in [Azure Identity Examples Page](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md)
### Authenticating with the `DefaultAzureCredential`
This example demonstrates authenticating the `KeyClient` from the [@azure/keyvault-keys](https://www.npmjs.com/package/@azure/keyvault-keys) client library using the `DefaultAzureCredential`.
```javascript
// The default credential first checks environment variables for configuration as described above.
// If environment configuration is incomplete, it will try managed identity.
// Azure Key Vault service to use
const { KeyClient } = require("@azure/keyvault-keys");
// Azure authentication library to access Azure Key Vault
const { DefaultAzureCredential } = require("@azure/identity");
// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();
// Create authenticated client
const client = new KeyClient(vaultUrl, credential);
```
### Specifying a user assigned managed identity with the `DefaultAzureCredential`
A relatively common scenario involves authenticating using a user assigned managed identity for an Azure resource. Explore the [example on Authenticating a user assigned managed identity with DefaultAzureCredential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-assigned-managed-identity-with-defaultazurecredential) to see how this is made a relatively straightforward task that can be configured using environment variables or in code.
### Define a custom authentication flow with the `ChainedTokenCredential`
While the `DefaultAzureCredential` is generally the quickest way to get started developing applications for Azure, more advanced users may want to customize the credentials considered when authenticating. The `ChainedTokenCredential` enables users to combine multiple credential instances to define a customized chain of credentials. This example demonstrates creating a `ChainedTokenCredential` which will attempt to authenticate using two differently configured instances of `ClientSecretCredential`, to then authenticate the `KeyClient` from the [@azure/keyvault-keys](https://www.npmjs.com/package/@azure/keyvault-keys):
```javascript
const { ClientSecretCredential, ChainedTokenCredential } = require("@azure/identity");
// When an access token is requested, the chain will try each
// credential in order, stopping when one provides a token
const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
// The chain can be used anywhere a credential is required
const { KeyClient } = require("@azure/keyvault-keys");
const client = new KeyClient(vaultUrl, credentialChain);
```
## Managed Identity Support
The [Managed identity authentication](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview) is supported via either the `DefaultAzureCredential` or the `ManagedIdentityCredential` credential classes directly for the following Azure hosts:
- [Azure Virtual Machines](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token)
- [Azure App Service](https://docs.microsoft.com/azure/app-service/overview-managed-identity)
- [Azure Kubernetes Service](https://docs.microsoft.com/azure/aks/use-managed-identity)
- [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/msi-authorization)
- [Azure Arc](https://docs.microsoft.com/azure/azure-arc/servers/managed-identity-authentication)
- [Azure Service Fabric](https://docs.microsoft.com/azure/service-fabric/concepts-managed-identity)
For examples of how to use managed identity for authentication please refer to [the examples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-in-azure-with-managed-identity)
## Cloud configuration
Credentials default to authenticating to the Azure AD endpoint for Azure Public Cloud. To access resources in other clouds, such as Azure Government or a private cloud, configure credentials with the `authorityHost` argument in the constructor. The `AzureAuthorityHosts` interface defines authorities for well-known clouds. For the US Government cloud, you could instantiate a credential this way:
```ts
import { AzureAuthorityHosts, ClientSecretCredential } from "@azure/identity";
const credential = new ClientSecretCredential(
"<YOUR_TENANT_ID>",
"<YOUR_CLIENT_ID>",
"<YOUR_CLIENT_SECRET>",
{
authorityHost: AzureAuthorityHosts.AzureGovernment,
}
);
```
Not all credentials require this configuration. Credentials that authenticate through a development tool, such as `AzureCliCredential`, use that tool's configuration. Similarly, `VisualStudioCodeCredential` accepts an `authorityHost` argument but defaults to the `authorityHost` matching Visual Studio Code's **Azure: Cloud** setting.
## Credential Classes
### Authenticating Azure-hosted applications
| Credential | Usage | Example |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`DefaultAzureCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/defaultazurecredential?view=azure-node-latest) | Provides a simplified authentication experience to quickly start developing applications run in the Azure cloud. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-defaultazurecredential) |
| [`ChainedTokenCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/chainedtokencredential?view=azure-node-latest) | Allows users to define custom authentication flows composing multiple credentials. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#chaining-credentials) |
| [`EnvironmentCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/environmentcredential?view=azure-node-latest) | Authenticates a service principal or user via credential information specified in environment variables. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-service-principal-with-environment-credentials) |
| [`ManagedIdentityCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/managedidentitycredential?view=azure-node-latest) | Authenticates the managed identity of an Azure resource. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-in-azure-with-managed-identity) |
### Authenticating Service Principals
| Credential | Usage | Example | Reference |
| --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `ClientAssertionCredential` | Authenticates a service principal using a certificate. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-service-principal-with-a-client-assertion) | [Service principal authentication](https://docs.microsoft.com/azure/active-directory/develop/app-objects-and-service-principals) |
| [`ClientCertificateCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/clientcertificatecredential?view=azure-node-latest) | Authenticates a service principal using a certificate. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-service-principal-with-a-client-certificate) | [Service principal authentication](https://docs.microsoft.com/azure/active-directory/develop/app-objects-and-service-principals) |
| [`ClientSecretCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/clientsecretcredential?view=azure-node-latest) | Authenticates a service principal using a secret. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-service-principal-with-a-client-secret) | [Service principal authentication](https://docs.microsoft.com/azure/active-directory/develop/app-objects-and-service-principals) |
### Authenticating Users
| Credential | Usage | Example | Reference |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| [`AuthorizationCodeCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/authorizationcodecredential?view=azure-node-latest) | Authenticates a user with a previously obtained authorization code. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-auth-code-flow) | [OAuth2 authentication code](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) |
| [`DeviceCodeCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/devicecodecredential?view=azure-node-latest) | Interactively authenticates a user on devices with limited UI. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-device-code-flow) | [Device code authentication](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-device-code) |
| [`InteractiveBrowserCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/interactivebrowsercredential?view=azure-node-latest) | Interactively authenticates a user with the default system browser. Read more about how this happens [here](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/interactive-browser-credential.md). | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-interactively-in-the-browser) | [OAuth2 authentication code](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) |
| [`OnBehalfOfCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/onbehalfofcredential?view=azure-node-latest) | Propagates the delegated user identity and permissions through the request chain |
| [`UsernamePasswordCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/usernamepasswordcredential?view=azure-node-latest) | Authenticates a user with a username and password. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-username-and-password) | [Username + password authentication](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth-ropc) |
### Authenticating via Development Tools
| Credential | Usage | Example | Reference |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| [`AzureCliCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/azureclicredential?view=azure-node-latest) | Authenticate in a development environment with the Azure CLI. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-azure-cli) | [Azure CLI authentication](https://docs.microsoft.com/cli/azure/authenticate-azure-cli) |
| [`AzurePowerShellCredential`](https://docs.microsoft.com/javascript/api/@azure/identity/azurepowershellcredential?view=azure-node-latest) | Authenticate in a development environment using Azure PowerShell. | [example](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-a-user-account-with-azure-powershell) | [Azure PowerShell authentication](https://docs.microsoft.com/powershell/azure/authenticate-azureps) |
## Troubleshooting
### Error Handling
Credentials raise `AuthenticationError` when they fail to authenticate. This class has a `message` field which describes why authentication failed. An `AggregateAuthenticationError` will be raised by `ChainedTokenCredential` with an `errors` field containing an array of errors from each credential in the chain.
### Logging
Enabling logging may help uncover useful information about failures.
To see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`.
You can read this environment variable from the _.env_ file by explicitly specifying a file path:
```javascript
require("dotenv").config({ path: ".env" });
```
Alternatively, logging can be enabled at runtime by calling `setLogLevel` from the `@azure/logger` package:
```javascript
import { setLogLevel } from "@azure/logger";
setLogLevel("info");
```
In cases where the authenticate code might be running in an environment with more than one credential available,
the `@azure/identity` package offers a unique form of logging. On the optional parameters for every credential,
developers can set `allowLoggingAccountIdentifiers` to true in the
`loggingOptions` to log information specific to the authenticated account after
each successful authentication, including the Client ID, the Tenant ID, the
Object ID of the authenticated user, and if possible the User Principal Name.
For example, using the `DefaultAzureCredential`:
```js
import { setLogLevel } from "@azure/logger";
setLogLevel("info");
const credential = new DefaultAzureCredential({
loggingOptions: { allowLoggingAccountIdentifiers: true },
});
```
Once that credential authenticates, the following message will appear in the logs (with the real information instead of `HIDDEN`):
```
azure:identity:info [Authenticated account] Client ID: HIDDEN. Tenant ID: HIDDEN. User Principal Name: HIDDEN. Object ID (user): HIDDEN
```
For assistance with troubleshooting, see the [troubleshooting guide](https://aka.ms/azsdk/js/identity/troubleshoot).
## Next steps
### Read the documentation
API documentation for this library can be found on our [documentation site](https://docs.microsoft.com/javascript/api/@azure/identity).
### Client library support
Client and management libraries listed on the [Azure SDK releases page](https://azure.github.io/azure-sdk/releases/latest/js.html) that support Azure AD authentication accept credentials from this library. Learn more about using these libraries in their documentation, which is linked from the releases page.
### Known Issues
#### Azure AD B2C support
This library does not support the [Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/overview) service.
### Provide Feedback
If you encounter bugs or have suggestions, please [open an issue](https://github.com/Azure/azure-sdk-for-js/issues).
## Contributing
If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/main/CONTRIBUTING.md) to learn more about how to build and test the code.
[1]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/defaultazurecredential.html
[2]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/managedidentitycredential.html
[3]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/environmentcredential.html
[4]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/clientsecretcredential.html
[5]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/clientcertificatecredential.html
[6]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/devicecodecredential.html
[7]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/authorizationcodecredential.html
[8]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/interactivebrowsercredential.html
[9]: https://azuresdkdocs.blob.core.windows.net/$web/javascript/azure-identity/1.0.0/classes/usernamepasswordcredential.html
[azure_cli]: https://docs.microsoft.com/cli/azure
[azure_powershell]: https://docs.microsoft.com/powershell/azure/
[azureclilogin_image]: https://raw.githubusercontent.com/Azure/azure-sdk-for-js/main/sdk/identity/identity/images/AzureCliLogin.png
[azureclilogindevicecode_image]: https://raw.githubusercontent.com/Azure/azure-sdk-for-js/main/sdk/identity/identity/images/AzureCliLoginDeviceCode.png
[azurepowershelllogin_image]: https://raw.githubusercontent.com/Azure/azure-sdk-for-js/main/sdk/identity/identity/images/AzurePowerShellLogin.png
[defaultauthflow_image]: https://raw.githubusercontent.com/Azure/azure-sdk-for-js/main/sdk/identity/identity/images/mermaidjs/DefaultAzureCredentialAuthFlow.svg
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%2Fidentity%2Fidentity%2FREADME.png)
+235
View File
@@ -0,0 +1,235 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ServiceClient } from "@azure/core-client";
import { isNode } from "@azure/core-util";
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { AbortController } from "@azure/abort-controller";
import { AuthenticationError, AuthenticationErrorName } from "../errors";
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
import { DefaultAuthorityHost, SDK_VERSION } from "../constants";
import { tracingClient } from "../util/tracing";
import { logger } from "../util/logging";
const noCorrelationId = "noCorrelationId";
/**
* @internal
*/
export function getIdentityClientAuthorityHost(options) {
// The authorityHost can come from options or from the AZURE_AUTHORITY_HOST environment variable.
let authorityHost = options === null || options === void 0 ? void 0 : options.authorityHost;
// The AZURE_AUTHORITY_HOST environment variable can only be provided in Node.js.
if (isNode) {
authorityHost = authorityHost !== null && authorityHost !== void 0 ? authorityHost : process.env.AZURE_AUTHORITY_HOST;
}
// If the authorityHost is not provided, we use the default one from the public cloud: https://login.microsoftonline.com
return authorityHost !== null && authorityHost !== void 0 ? authorityHost : DefaultAuthorityHost;
}
/**
* The network module used by the Identity credentials.
*
* It allows for credentials to abort any pending request independently of the MSAL flow,
* by calling to the `abortRequests()` method.
*
*/
export class IdentityClient extends ServiceClient {
constructor(options) {
var _a, _b;
const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;
const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
: `${packageDetails}`;
const baseUri = getIdentityClientAuthorityHost(options);
if (!baseUri.startsWith("https:")) {
throw new Error("The authorityHost address must use the 'https' protocol.");
}
super(Object.assign(Object.assign({ requestContentType: "application/json; charset=utf-8", retryOptions: {
maxRetries: 3,
} }, options), { userAgentOptions: {
userAgentPrefix,
}, baseUri }));
this.authorityHost = baseUri;
this.abortControllers = new Map();
this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
}
async sendTokenRequest(request, expiresOnParser) {
logger.info(`IdentityClient: sending token request to [${request.url}]`);
const response = await this.sendRequest(request);
expiresOnParser =
expiresOnParser ||
((responseBody) => {
return Date.now() + responseBody.expires_in * 1000;
});
if (response.bodyAsText && (response.status === 200 || response.status === 201)) {
const parsedBody = JSON.parse(response.bodyAsText);
if (!parsedBody.access_token) {
return null;
}
this.logIdentifiers(response);
const token = {
accessToken: {
token: parsedBody.access_token,
expiresOnTimestamp: expiresOnParser(parsedBody),
},
refreshToken: parsedBody.refresh_token,
};
logger.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
return token;
}
else {
const error = new AuthenticationError(response.status, response.bodyAsText);
logger.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
throw error;
}
}
async refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, expiresOnParser, options = {}) {
if (refreshToken === undefined) {
return null;
}
logger.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
const refreshParams = {
grant_type: "refresh_token",
client_id: clientId,
refresh_token: refreshToken,
scope: scopes,
};
if (clientSecret !== undefined) {
refreshParams.client_secret = clientSecret;
}
const query = new URLSearchParams(refreshParams);
return tracingClient.withSpan("IdentityClient.refreshAccessToken", options, async (updatedOptions) => {
try {
const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);
const request = createPipelineRequest({
url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,
method: "POST",
body: query.toString(),
abortSignal: options.abortSignal,
headers: createHttpHeaders({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
}),
tracingOptions: updatedOptions.tracingOptions,
});
const response = await this.sendTokenRequest(request, expiresOnParser);
logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
return response;
}
catch (err) {
if (err.name === AuthenticationErrorName &&
err.errorResponse.error === "interaction_required") {
// It's likely that the refresh token has expired, so
// return null so that the credential implementation will
// initiate the authentication flow again.
logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);
return null;
}
else {
logger.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`);
throw err;
}
}
});
}
// Here is a custom layer that allows us to abort requests that go through MSAL,
// since MSAL doesn't allow us to pass options all the way through.
generateAbortSignal(correlationId) {
const controller = new AbortController();
const controllers = this.abortControllers.get(correlationId) || [];
controllers.push(controller);
this.abortControllers.set(correlationId, controllers);
const existingOnAbort = controller.signal.onabort;
controller.signal.onabort = (...params) => {
this.abortControllers.set(correlationId, undefined);
if (existingOnAbort) {
existingOnAbort(...params);
}
};
return controller.signal;
}
abortRequests(correlationId) {
const key = correlationId || noCorrelationId;
const controllers = [
...(this.abortControllers.get(key) || []),
// MSAL passes no correlation ID to the get requests...
...(this.abortControllers.get(noCorrelationId) || []),
];
if (!controllers.length) {
return;
}
for (const controller of controllers) {
controller.abort();
}
this.abortControllers.set(key, undefined);
}
getCorrelationId(options) {
var _a;
const parameter = (_a = options === null || options === void 0 ? void 0 : options.body) === null || _a === void 0 ? void 0 : _a.split("&").map((part) => part.split("=")).find(([key]) => key === "client-request-id");
return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;
}
// The MSAL network module methods follow
async sendGetRequestAsync(url, options) {
const request = createPipelineRequest({
url,
method: "GET",
body: options === null || options === void 0 ? void 0 : options.body,
headers: createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
abortSignal: this.generateAbortSignal(noCorrelationId),
});
const response = await this.sendRequest(request);
this.logIdentifiers(response);
return {
body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
headers: response.headers.toJSON(),
status: response.status,
};
}
async sendPostRequestAsync(url, options) {
const request = createPipelineRequest({
url,
method: "POST",
body: options === null || options === void 0 ? void 0 : options.body,
headers: createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
// MSAL doesn't send the correlation ID on the get requests.
abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),
});
const response = await this.sendRequest(request);
this.logIdentifiers(response);
return {
body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
headers: response.headers.toJSON(),
status: response.status,
};
}
/**
* If allowLoggingAccountIdentifiers was set on the constructor options
* we try to log the account identifiers by parsing the received access token.
*
* The account identifiers we try to log are:
* - `appid`: The application or Client Identifier.
* - `upn`: User Principal Name.
* - It might not be available in some authentication scenarios.
* - If it's not available, we put a placeholder: "No User Principal Name available".
* - `tid`: Tenant Identifier.
* - `oid`: Object Identifier of the authenticated user.
*/
logIdentifiers(response) {
if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {
return;
}
const unavailableUpn = "No User Principal Name available";
try {
const parsed = response.parsedBody || JSON.parse(response.bodyAsText);
const accessToken = parsed.access_token;
if (!accessToken) {
// Without an access token allowLoggingAccountIdentifiers isn't useful.
return;
}
const base64Metadata = accessToken.split(".")[1];
const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8"));
logger.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`);
}
catch (e) {
logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
}
}
}
//# sourceMappingURL=identityClient.js.map
File diff suppressed because one or more lines are too long
+46
View File
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* Current version of the `@azure/identity` package.
*/
export const SDK_VERSION = `2.1.0`;
/**
* The default client ID for authentication
* @internal
*/
// TODO: temporary - this is the Azure CLI clientID - we'll replace it when
// Developer Sign On application is available
// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
export const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
/**
* The default tenant for authentication
* @internal
*/
export const DefaultTenantId = "common";
/**
* A list of known Azure authority hosts
*/
export var AzureAuthorityHosts;
(function (AzureAuthorityHosts) {
/**
* China-based Azure Authority Host
*/
AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
/**
* Germany-based Azure Authority Host
*/
AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
/**
* US Government Azure Authority Host
*/
AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
/**
* Public Cloud Azure Authority Host
*/
AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
})(AzureAuthorityHosts || (AzureAuthorityHosts = {}));
/**
* The default authority host.
*/
export const DefaultAuthorityHost = AzureAuthorityHosts.AzurePublicCloud;
//# sourceMappingURL=constants.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAEnC;;;GAGG;AACH,2EAA2E;AAC3E,6CAA6C;AAC7C,uGAAuG;AACvG,MAAM,CAAC,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;AAExC;;GAEG;AACH,MAAM,CAAN,IAAY,mBAiBX;AAjBD,WAAY,mBAAmB;IAC7B;;OAEG;IACH,oEAA6C,CAAA;IAC7C;;OAEG;IACH,wEAAiD,CAAA;IACjD;;OAEG;IACH,2EAAoD,CAAA;IACpD;;OAEG;IACH,6EAAsD,CAAA;AACxD,CAAC,EAjBW,mBAAmB,KAAnB,mBAAmB,QAiB9B;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,gBAAgB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Current version of the `@azure/identity` package.\n */\nexport const SDK_VERSION = `2.1.0`;\n\n/**\n * The default client ID for authentication\n * @internal\n */\n// TODO: temporary - this is the Azure CLI clientID - we'll replace it when\n// Developer Sign On application is available\n// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9\nexport const DeveloperSignOnClientId = \"04b07795-8ddb-461a-bbee-02f9e1bf7b46\";\n\n/**\n * The default tenant for authentication\n * @internal\n */\nexport const DefaultTenantId = \"common\";\n\n/**\n * A list of known Azure authority hosts\n */\nexport enum AzureAuthorityHosts {\n /**\n * China-based Azure Authority Host\n */\n AzureChina = \"https://login.chinacloudapi.cn\",\n /**\n * Germany-based Azure Authority Host\n */\n AzureGermany = \"https://login.microsoftonline.de\",\n /**\n * US Government Azure Authority Host\n */\n AzureGovernment = \"https://login.microsoftonline.us\",\n /**\n * Public Cloud Azure Authority Host\n */\n AzurePublicCloud = \"https://login.microsoftonline.com\",\n}\n\n/**\n * The default authority host.\n */\nexport const DefaultAuthorityHost = AzureAuthorityHosts.AzurePublicCloud;\n"]}
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("AuthorizationCodeCredential is not supported in the browser. InteractiveBrowserCredential is more appropriate for this use case.");
const logger = credentialLogger("AuthorizationCodeCredential");
export class AuthorizationCodeCredential {
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=authorizationCodeCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"authorizationCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/authorizationCodeCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,kIAAkI,CACnI,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;AAE/D,MAAM,OAAO,2BAA2B;IAmBtC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"AuthorizationCodeCredential is not supported in the browser. InteractiveBrowserCredential is more appropriate for this use case.\"\n);\nconst logger = credentialLogger(\"AuthorizationCodeCredential\");\n\nexport class AuthorizationCodeCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n clientSecret: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { checkTenantId } from "../util/checkTenantId";
import { MsalAuthorizationCode } from "../msal/nodeFlows/msalAuthorizationCode";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("AuthorizationCodeCredential");
/**
* Enables authentication to Azure Active Directory using an authorization code
* that was obtained through the authorization code flow, described in more detail
* in the Azure Active Directory documentation:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
*/
export class AuthorizationCodeCredential {
/**
* @hidden
* @internal
*/
constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
checkTenantId(logger, tenantId);
let clientSecret = clientSecretOrAuthorizationCode;
if (typeof redirectUriOrOptions === "string") {
// the clientId+clientSecret constructor
this.authorizationCode = authorizationCodeOrRedirectUri;
this.redirectUri = redirectUriOrOptions;
// in this case, options are good as they come
}
else {
// clientId only
this.authorizationCode = clientSecretOrAuthorizationCode;
this.redirectUri = authorizationCodeOrRedirectUri;
clientSecret = undefined;
options = redirectUriOrOptions;
}
this.msalFlow = new MsalAuthorizationCode(Object.assign(Object.assign({}, options), { clientSecret,
clientId,
tenantId, tokenCredentialOptions: options || {}, logger, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
}
//# sourceMappingURL=authorizationCodeCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
import { ChainedTokenCredential } from "./chainedTokenCredential";
const BrowserNotSupportedError = new Error("ApplicationCredential is not supported in the browser. Use InteractiveBrowserCredential instead.");
const logger = credentialLogger("ApplicationCredential");
/**
* Provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js
*/
export class AzureApplicationCredential extends ChainedTokenCredential {
/**
* Creates an instance of the AzureApplicationCredential class.
*
* The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(_tokenCredentialOptions) {
super();
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=azureApplicationCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureApplicationCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azureApplicationCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,kGAAkG,CACnG,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,OAAO,0BAA2B,SAAQ,sBAAsB;IACpE;;;;;;;;;OASG;IACH,YAAY,uBAAgD;QAC1D,KAAK,EAAE,CAAC;QACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport { ChainedTokenCredential } from \"./chainedTokenCredential\";\n\nconst BrowserNotSupportedError = new Error(\n \"ApplicationCredential is not supported in the browser. Use InteractiveBrowserCredential instead.\"\n);\nconst logger = credentialLogger(\"ApplicationCredential\");\n\n/**\n * Provides a default {@link ChainedTokenCredential} configuration for\n * applications that will be deployed to Azure.\n *\n * Only available in Node.js\n */\nexport class AzureApplicationCredential extends ChainedTokenCredential {\n /**\n * Creates an instance of the AzureApplicationCredential class.\n *\n * The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration for\n * applications that will be deployed to Azure.\n *\n * Only available in Node.js\n *\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(_tokenCredentialOptions?: TokenCredentialOptions) {\n super();\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ChainedTokenCredential } from "./chainedTokenCredential";
import { EnvironmentCredential } from "./environmentCredential";
import { DefaultManagedIdentityCredential } from "./defaultAzureCredential";
export const AzureApplicationCredentials = [
EnvironmentCredential,
DefaultManagedIdentityCredential,
];
/**
* Provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications that use the Azure SDK.
*/
export class AzureApplicationCredential extends ChainedTokenCredential {
/**
* Creates an instance of the AzureApplicationCredential class.
*
* The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications deployed on Azure. The following credential types will be tried, in order:
*
* - {@link EnvironmentCredential}
* - {@link ManagedIdentityCredential}
*
* Consult the documentation of these credential types for more information
* on how they attempt authentication.
*
* @param options - Optional parameters. See {@link AzureApplicationCredentialOptions}.
*/
constructor(options) {
super(...AzureApplicationCredentials.map((ctor) => new ctor(options)));
this.UnavailableMessage =
"ApplicationCredential => failed to retrieve a token from the included credentials. To troubleshoot, visit https://aka.ms/azsdk/js/identity/applicationcredential/troubleshoot.";
}
}
//# sourceMappingURL=azureApplicationCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureApplicationCredential.js","sourceRoot":"","sources":["../../../src/credentials/azureApplicationCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAOlC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAuB5E,MAAM,CAAC,MAAM,2BAA2B,GAA4C;IAClF,qBAAqB;IACrB,gCAAgC;CACjC,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,0BAA2B,SAAQ,sBAAsB;IACpE;;;;;;;;;;;;;OAaG;IACH,YAAY,OAA2C;QACrD,KAAK,CAAC,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,kBAAkB;YACrB,gLAAgL,CAAC;IACrL,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential } from \"@azure/core-auth\";\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { ChainedTokenCredential } from \"./chainedTokenCredential\";\nimport { EnvironmentCredential } from \"./environmentCredential\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\nimport { DefaultManagedIdentityCredential } from \"./defaultAzureCredential\";\n\n/**\n * Provides options to configure the {@link AzureApplicationCredential} class.\n */\nexport interface AzureApplicationCredentialOptions\n extends TokenCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * Optionally pass in a user assigned client ID to be used by the {@link ManagedIdentityCredential}.\n * This client ID can also be passed through to the {@link ManagedIdentityCredential} through the environment variable: AZURE_CLIENT_ID.\n */\n managedIdentityClientId?: string;\n}\n\n/**\n * The type of a class that implements TokenCredential and accepts\n * `ApplicationCredentialOptions`.\n */\ninterface AzureApplicationCredentialConstructor {\n new (options?: AzureApplicationCredentialOptions): TokenCredential;\n}\n\nexport const AzureApplicationCredentials: AzureApplicationCredentialConstructor[] = [\n EnvironmentCredential,\n DefaultManagedIdentityCredential,\n];\n\n/**\n * Provides a default {@link ChainedTokenCredential} configuration that should\n * work for most applications that use the Azure SDK.\n */\nexport class AzureApplicationCredential extends ChainedTokenCredential {\n /**\n * Creates an instance of the AzureApplicationCredential class.\n *\n * The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration that should\n * work for most applications deployed on Azure. The following credential types will be tried, in order:\n *\n * - {@link EnvironmentCredential}\n * - {@link ManagedIdentityCredential}\n *\n * Consult the documentation of these credential types for more information\n * on how they attempt authentication.\n *\n * @param options - Optional parameters. See {@link AzureApplicationCredentialOptions}.\n */\n constructor(options?: AzureApplicationCredentialOptions) {\n super(...AzureApplicationCredentials.map((ctor) => new ctor(options)));\n this.UnavailableMessage =\n \"ApplicationCredential => failed to retrieve a token from the included credentials. To troubleshoot, visit https://aka.ms/azsdk/js/identity/applicationcredential/troubleshoot.\";\n }\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("AzureCliCredential is not supported in the browser.");
const logger = credentialLogger("AzureCliCredential");
/**
* This credential will use the currently logged-in user login information
* via the Azure CLI ('az') commandline tool.
*/
export class AzureCliCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=azureCliCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureCliCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;AAClG,MAAM,MAAM,GAAG,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;AAEtD;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\"AzureCliCredential is not supported in the browser.\");\nconst logger = credentialLogger(\"AzureCliCredential\");\n\n/**\n * This credential will use the currently logged-in user login information\n * via the Azure CLI ('az') commandline tool.\n */\nexport class AzureCliCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,139 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { tracingClient } from "../util/tracing";
import { CredentialUnavailableError } from "../errors";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import child_process from "child_process";
import { ensureValidScope, getScopeResource } from "../util/scopeUtils";
import { processMultiTenantRequest } from "../util/validateMultiTenant";
import { checkTenantId } from "../util/checkTenantId";
/**
* Mockable reference to the CLI credential cliCredentialFunctions
* @internal
*/
export const cliCredentialInternals = {
/**
* @internal
*/
getSafeWorkingDir() {
if (process.platform === "win32") {
if (!process.env.SystemRoot) {
throw new Error("Azure CLI credential expects a 'SystemRoot' environment variable");
}
return process.env.SystemRoot;
}
else {
return "/bin";
}
},
/**
* Gets the access token from Azure CLI
* @param resource - The resource to use when getting the token
* @internal
*/
async getAzureCliAccessToken(resource, tenantId) {
let tenantSection = [];
if (tenantId) {
tenantSection = ["--tenant", tenantId];
}
return new Promise((resolve, reject) => {
try {
child_process.execFile("az", [
"account",
"get-access-token",
"--output",
"json",
"--resource",
resource,
...tenantSection,
], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true }, (error, stdout, stderr) => {
resolve({ stdout: stdout, stderr: stderr, error });
});
}
catch (err) {
reject(err);
}
});
},
};
const logger = credentialLogger("AzureCliCredential");
/**
* This credential will use the currently logged-in user login information
* via the Azure CLI ('az') commandline tool.
* To do so, it will read the user access token and expire time
* with Azure CLI command "az account get-access-token".
*/
export class AzureCliCredential {
/**
* Creates an instance of the {@link AzureCliCredential}.
*
* To use this credential, ensure that you have already logged
* in via the 'az' tool using the command "az login" from the commandline.
*
* @param options - Options, to optionally allow multi-tenant requests.
*/
constructor(options) {
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
const tenantId = processMultiTenantRequest(this.tenantId, options);
if (tenantId) {
checkTenantId(logger, tenantId);
}
const scope = typeof scopes === "string" ? scopes : scopes[0];
logger.getToken.info(`Using the scope ${scope}`);
ensureValidScope(scope, logger);
const resource = getScopeResource(scope);
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
var _a, _b, _c, _d;
try {
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId);
const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
if (isNotInstallError) {
const error = new CredentialUnavailableError("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");
logger.getToken.info(formatError(scopes, error));
throw error;
}
if (isLoginError) {
const error = new CredentialUnavailableError("Please run 'az login' from a command prompt to authenticate before using this credential.");
logger.getToken.info(formatError(scopes, error));
throw error;
}
try {
const responseData = obj.stdout;
const response = JSON.parse(responseData);
logger.getToken.info(formatSuccess(scopes));
const returnValue = {
token: response.accessToken,
expiresOnTimestamp: new Date(response.expiresOn).getTime(),
};
return returnValue;
}
catch (e) {
if (obj.stderr) {
throw new CredentialUnavailableError(obj.stderr);
}
throw e;
}
}
catch (err) {
const error = err.name === "CredentialUnavailableError"
? err
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
logger.getToken.info(formatError(scopes, error));
throw error;
}
});
}
}
//# sourceMappingURL=azureCliCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=azureCliCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureCliCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\n\n/**\n * Options for the {@link AzureCliCredential}\n */\nexport interface AzureCliCredentialOptions extends TokenCredentialOptions {\n /**\n * Allows specifying a tenant ID\n */\n tenantId?: string;\n}\n"]}
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("AzurePowerShellCredential is not supported in the browser.");
const logger = credentialLogger("AzurePowerShellCredential");
/**
* This credential will use the currently-logged-in user's login information via the Azure Power Shell command line tool.
*/
export class AzurePowerShellCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=azurePowerShellCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azurePowerShellCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azurePowerShellCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,yBAAyB;IACpC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"AzurePowerShellCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"AzurePowerShellCredential\");\n\n/**\n * This credential will use the currently-logged-in user's login information via the Azure Power Shell command line tool.\n */\nexport class AzurePowerShellCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,173 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { CredentialUnavailableError } from "../errors";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { ensureValidScope, getScopeResource } from "../util/scopeUtils";
import { processUtils } from "../util/processUtils";
import { processMultiTenantRequest } from "../util/validateMultiTenant";
import { checkTenantId } from "../util/checkTenantId";
const logger = credentialLogger("AzurePowerShellCredential");
const isWindows = process.platform === "win32";
/**
* Returns a platform-appropriate command name by appending ".exe" on Windows.
*
* @internal
*/
export function formatCommand(commandName) {
if (isWindows) {
return `${commandName}.exe`;
}
else {
return commandName;
}
}
/**
* Receives a list of commands to run, executes them, then returns the outputs.
* If anything fails, an error is thrown.
* @internal
*/
async function runCommands(commands) {
const results = [];
for (const command of commands) {
const [file, ...parameters] = command;
const result = (await processUtils.execFile(file, parameters, { encoding: "utf8" }));
results.push(result);
}
return results;
}
/**
* Known PowerShell errors
* @internal
*/
export const powerShellErrors = {
login: "Run Connect-AzAccount to login",
installed: "The specified module 'Az.Accounts' with version '2.2.0' was not loaded because no valid module file was found in any module directory",
};
/**
* Messages to use when throwing in this credential.
* @internal
*/
export const powerShellPublicErrorMessages = {
login: "Please run 'Connect-AzAccount' from PowerShell to authenticate before using this credential.",
installed: `The 'Az.Account' module >= 2.2.0 is not installed. Install the Azure Az PowerShell module with: "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force".`,
troubleshoot: `To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot.`,
};
// PowerShell Azure User not logged in error check.
const isLoginError = (err) => err.message.match(`(.*)${powerShellErrors.login}(.*)`);
// Az Module not Installed in Azure PowerShell check.
const isNotInstalledError = (err) => err.message.match(powerShellErrors.installed);
/**
* The PowerShell commands to be tried, in order.
*
* @internal
*/
export const commandStack = [formatCommand("pwsh")];
if (isWindows) {
commandStack.push(formatCommand("powershell"));
}
/**
* This credential will use the currently logged-in user information from the
* Azure PowerShell module. To do so, it will read the user access token and
* expire time with Azure PowerShell command `Get-AzAccessToken -ResourceUrl {ResourceScope}`
*/
export class AzurePowerShellCredential {
/**
* Creates an instance of the {@link AzurePowerShellCredential}.
*
* To use this credential:
* - Install the Azure Az PowerShell module with:
* `Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force`.
* - You have already logged in to Azure PowerShell using the command
* `Connect-AzAccount` from the command line.
*
* @param options - Options, to optionally allow multi-tenant requests.
*/
constructor(options) {
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
}
/**
* Gets the access token from Azure PowerShell
* @param resource - The resource to use when getting the token
*/
async getAzurePowerShellAccessToken(resource, tenantId) {
// Clone the stack to avoid mutating it while iterating
for (const powerShellCommand of [...commandStack]) {
try {
await runCommands([[powerShellCommand, "/?"]]);
}
catch (e) {
// Remove this credential from the original stack so that we don't try it again.
commandStack.shift();
continue;
}
let tenantSection = "";
if (tenantId) {
tenantSection = `-TenantId "${tenantId}"`;
}
const results = await runCommands([
[
powerShellCommand,
"-Command",
"Import-Module Az.Accounts -MinimumVersion 2.2.0 -PassThru",
],
[
powerShellCommand,
"-Command",
`Get-AzAccessToken ${tenantSection} -ResourceUrl "${resource}" | ConvertTo-Json`,
],
]);
const result = results[1];
try {
return JSON.parse(result);
}
catch (e) {
throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`);
}
}
throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`);
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If the authentication cannot be performed through PowerShell, a {@link CredentialUnavailableError} will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
const tenantId = processMultiTenantRequest(this.tenantId, options);
if (tenantId) {
checkTenantId(logger, tenantId);
}
const scope = typeof scopes === "string" ? scopes : scopes[0];
ensureValidScope(scope, logger);
logger.getToken.info(`Using the scope ${scope}`);
const resource = getScopeResource(scope);
try {
const response = await this.getAzurePowerShellAccessToken(resource, tenantId);
logger.getToken.info(formatSuccess(scopes));
return {
token: response.Token,
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
};
}
catch (err) {
if (isNotInstalledError(err)) {
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
logger.getToken.info(formatError(scope, error));
throw error;
}
else if (isLoginError(err)) {
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
logger.getToken.info(formatError(scope, error));
throw error;
}
const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
logger.getToken.info(formatError(scope, error));
throw error;
}
});
}
}
//# sourceMappingURL=azurePowerShellCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=azurePowerShellCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azurePowerShellCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/azurePowerShellCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\n\n/**\n * Options for the {@link AzurePowerShellCredential}\n */\nexport interface AzurePowerShellCredentialOptions extends TokenCredentialOptions {\n /**\n * Allows specifying a tenant ID\n */\n tenantId?: string;\n}\n"]}
@@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { AggregateAuthenticationError, CredentialUnavailableError } from "../errors";
import { tracingClient } from "../util/tracing";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
/**
* @internal
*/
export const logger = credentialLogger("ChainedTokenCredential");
/**
* Enables multiple `TokenCredential` implementations to be tried in order
* until one of the getToken methods returns an access token.
*/
export class ChainedTokenCredential {
/**
* Creates an instance of ChainedTokenCredential using the given credentials.
*
* @param sources - `TokenCredential` implementations to be tried in order.
*
* Example usage:
* ```javascript
* const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
* const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
* const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
* ```
*/
constructor(...sources) {
/**
* The message to use when the chained token fails to get a token
*/
this.UnavailableMessage = "ChainedTokenCredential => failed to retrieve a token from the included credentials";
this._sources = [];
this._sources = sources;
}
/**
* Returns the first access token returned by one of the chained
* `TokenCredential` implementations. Throws an {@link AggregateAuthenticationError}
* when one or more credentials throws an {@link AuthenticationError} and
* no credentials have returned an access token.
*
* This method is called automatically by Azure SDK client libraries. You may call this method
* directly, but you must also handle token caching and token refreshing.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* `TokenCredential` implementation might make.
*/
async getToken(scopes, options = {}) {
let token = null;
let successfulCredentialName = "";
const errors = [];
return tracingClient.withSpan("ChainedTokenCredential.getToken", options, async (updatedOptions) => {
for (let i = 0; i < this._sources.length && token === null; i++) {
try {
token = await this._sources[i].getToken(scopes, updatedOptions);
successfulCredentialName = this._sources[i].constructor.name;
}
catch (err) {
if (err.name === "CredentialUnavailableError" ||
err.name === "AuthenticationRequiredError") {
errors.push(err);
}
else {
logger.getToken.info(formatError(scopes, err));
throw err;
}
}
}
if (!token && errors.length > 0) {
const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed.");
logger.getToken.info(formatError(scopes, err));
throw err;
}
logger.getToken.info(`Result for ${successfulCredentialName}: ${formatSuccess(scopes)}`);
if (token === null) {
throw new CredentialUnavailableError("Failed to retrieve a valid token");
}
return token;
});
}
}
//# sourceMappingURL=chainedTokenCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("ClientAssertionCredential is not supported in the browser.");
const logger = credentialLogger("ClientAssertionCredential");
/**
* Authenticates a service principal with a JWT assertion.
*/
export class ClientAssertionCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=clientAssertionCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientAssertionCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/clientAssertionCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,yBAAyB;IACpC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ClientAssertionCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ClientAssertionCredential\");\n\n/**\n * Authenticates a service principal with a JWT assertion.\n */\nexport class ClientAssertionCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { MsalClientAssertion } from "../msal/nodeFlows/msalClientAssertion";
const logger = credentialLogger("ClientAssertionCredential");
/**
* Authenticates a service principal with a JWT assertion.
*/
export class ClientAssertionCredential {
/**
* Creates an instance of the ClientAssertionCredential with the details
* needed to authenticate against Azure Active Directory with a client
* assertion provided by the developer through the `getAssertion` function parameter.
*
* @param tenantId - The Azure Active Directory tenant (directory) ID.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param getAssertion - A function that retrieves the assertion for the credential to use.
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, getAssertion, options = {}) {
if (!tenantId || !clientId || !getAssertion) {
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
}
this.tenantId = tenantId;
this.clientId = clientId;
this.options = options;
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=clientAssertionCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientAssertionCredential.js","sourceRoot":"","sources":["../../../src/credentials/clientAssertionCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,yBAAyB;IAMpC;;;;;;;;;OASG;IACH,YACE,QAAgB,EAChB,QAAgB,EAChB,YAAmC,EACnC,UAAkC,EAAE;QAEpC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;SACH;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,iCAClC,OAAO,KACV,MAAM,EACN,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,sBAAsB,EAAE,IAAI,CAAC,OAAO,EACpC,YAAY,IACZ,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAyB,EAAE,UAA2B,EAAE;QACrE,OAAO,aAAa,CAAC,QAAQ,CAC3B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,WAAW,EACnC,OAAO,EACP,KAAK,EAAE,UAAU,EAAE,EAAE;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC,CACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger } from \"../util/logging\";\nimport { tracingClient } from \"../util/tracing\";\nimport { MsalFlow } from \"../msal/flows\";\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { MsalClientAssertion } from \"../msal/nodeFlows/msalClientAssertion\";\n\nconst logger = credentialLogger(\"ClientAssertionCredential\");\n\n/**\n * Authenticates a service principal with a JWT assertion.\n */\nexport class ClientAssertionCredential implements TokenCredential {\n private msalFlow: MsalFlow;\n private tenantId: string;\n private clientId: string;\n private options: TokenCredentialOptions;\n\n /**\n * Creates an instance of the ClientAssertionCredential with the details\n * needed to authenticate against Azure Active Directory with a client\n * assertion provided by the developer through the `getAssertion` function parameter.\n *\n * @param tenantId - The Azure Active Directory tenant (directory) ID.\n * @param clientId - The client (application) ID of an App Registration in the tenant.\n * @param getAssertion - A function that retrieves the assertion for the credential to use.\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n getAssertion: () => Promise<string>,\n options: TokenCredentialOptions = {}\n ) {\n if (!tenantId || !clientId || !getAssertion) {\n throw new Error(\n \"ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.\"\n );\n }\n this.tenantId = tenantId;\n this.clientId = clientId;\n this.options = options;\n this.msalFlow = new MsalClientAssertion({\n ...options,\n logger,\n clientId: this.clientId,\n tenantId: this.tenantId,\n tokenCredentialOptions: this.options,\n getAssertion,\n });\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(\n `${this.constructor.name}.getToken`,\n options,\n async (newOptions) => {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n return this.msalFlow.getToken(arrayScopes, newOptions);\n }\n );\n }\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("ClientCertificateCredential is not supported in the browser.");
const logger = credentialLogger("ClientCertificateCredential");
/**
* Enables authentication to Azure Active Directory using a PEM-encoded
* certificate that is assigned to an App Registration.
*/
export class ClientCertificateCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=clientCertificateCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientCertificateCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/clientCertificateCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,8DAA8D,CAC/D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;AAE/D;;;GAGG;AACH,MAAM,OAAO,2BAA2B;IACtC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ClientCertificateCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ClientCertificateCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using a PEM-encoded\n * certificate that is assigned to an App Registration.\n */\nexport class ClientCertificateCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MsalClientCertificate } from "../msal/nodeFlows/msalClientCertificate";
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
const credentialName = "ClientCertificateCredential";
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using a PEM-encoded
* certificate that is assigned to an App Registration. More information
* on how to configure certificate authentication can be found here:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad
*
*/
export class ClientCertificateCredential {
constructor(tenantId, clientId, certificatePathOrConfiguration, options = {}) {
if (!tenantId || !clientId) {
throw new Error(`${credentialName}: tenantId and clientId are required parameters.`);
}
const configuration = Object.assign({}, (typeof certificatePathOrConfiguration === "string"
? {
certificatePath: certificatePathOrConfiguration,
}
: certificatePathOrConfiguration));
const certificate = configuration
.certificate;
const certificatePath = configuration.certificatePath;
if (!configuration || !(certificate || certificatePath)) {
throw new Error(`${credentialName}: Provide either a PEM certificate in string form, or the path to that certificate in the filesystem. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
}
if (certificate && certificatePath) {
throw new Error(`${credentialName}: To avoid unexpected behaviors, providing both the contents of a PEM certificate and the path to a PEM certificate is forbidden. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
}
this.msalFlow = new MsalClientCertificate(Object.assign(Object.assign({}, options), { configuration,
logger,
clientId,
tenantId, sendCertificateChain: options.sendCertificateChain, tokenCredentialOptions: options }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=clientCertificateCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=clientCertificateCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientCertificateCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/clientCertificateCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Optional parameters for the {@link ClientCertificateCredential} class.\n */\nexport interface ClientCertificateCredentialOptions\n extends TokenCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n // TODO: Export again once we're ready to release this feature.\n // /**\n // * Specifies a regional authority. Please refer to the {@link RegionalAuthority} type for the accepted values.\n // * If {@link RegionalAuthority.AutoDiscoverRegion} is specified, we will try to discover the regional authority endpoint.\n // * If the property is not specified, the credential uses the global authority endpoint.\n // */\n // regionalAuthority?: string;\n}\n"]}
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
import { IdentityClient } from "../client/identityClient";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("ClientSecretCredential");
// This credential is exported on browser bundles for development purposes.
// For this credential to work in browsers, browsers would need to have security features disabled.
// Please do not disable your browser security features.
/**
* Enables authentication to Azure Active Directory using a client secret
* that was generated for an App Registration. More information on how
* to configure a client secret can be found here:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
*
*/
export class ClientSecretCredential {
/**
* Creates an instance of the ClientSecretCredential with the details
* needed to authenticate against Azure Active Directory with a client
* secret.
*
* @param tenantId - The Azure Active Directory tenant (directory) ID.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param clientSecret - A client secret that was generated for the App Registration.
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, clientSecret, options) {
this.identityClient = new IdentityClient(options);
this.tenantId = tenantId;
this.clientId = clientId;
this.clientSecret = clientSecret;
}
/**
* Authenticates with Azure Active Directory and returns an access token if
* successful. If authentication cannot be performed at this time, this method may
* return null. If an error occurs during authentication, an {@link AuthenticationError}
* containing failure details will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const query = new URLSearchParams({
response_type: "token",
grant_type: "client_credentials",
client_id: this.clientId,
client_secret: this.clientSecret,
scope: typeof scopes === "string" ? scopes : scopes.join(" "),
});
try {
const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
const request = createPipelineRequest({
url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
method: "POST",
body: query.toString(),
headers: createHttpHeaders({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
}),
abortSignal: options && options.abortSignal,
tracingOptions: newOptions === null || newOptions === void 0 ? void 0 : newOptions.tracingOptions,
});
const tokenResponse = await this.identityClient.sendTokenRequest(request);
logger.getToken.info(formatSuccess(scopes));
return (tokenResponse && tokenResponse.accessToken) || null;
}
catch (err) {
logger.getToken.info(formatError(scopes, err));
throw err;
}
});
}
}
//# sourceMappingURL=clientSecretCredential.browser.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MsalClientSecret } from "../msal/nodeFlows/msalClientSecret";
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("ClientSecretCredential");
/**
* Enables authentication to Azure Active Directory using a client secret
* that was generated for an App Registration. More information on how
* to configure a client secret can be found here:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
*
*/
export class ClientSecretCredential {
/**
* Creates an instance of the ClientSecretCredential with the details
* needed to authenticate against Azure Active Directory with a client
* secret.
*
* @param tenantId - The Azure Active Directory tenant (directory) ID.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param clientSecret - A client secret that was generated for the App Registration.
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, clientSecret, options = {}) {
if (!tenantId || !clientId || !clientSecret) {
throw new Error("ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.");
}
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger,
clientId,
tenantId,
clientSecret, tokenCredentialOptions: options }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=clientSecretCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientSecretCredential.js","sourceRoot":"","sources":["../../../src/credentials/clientSecretCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAsB;IAGjC;;;;;;;;;OASG;IACH,YACE,QAAgB,EAChB,QAAgB,EAChB,YAAoB,EACpB,UAAyC,EAAE;QAE3C,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,IAAI,KAAK,CACb,4LAA4L,CAC7L,CAAC;SACH;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAgB,iCAC/B,OAAO,KACV,MAAM;YACN,QAAQ;YACR,QAAQ;YACR,YAAY,EACZ,sBAAsB,EAAE,OAAO,IAC/B,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAyB,EAAE,UAA2B,EAAE;QACrE,OAAO,aAAa,CAAC,QAAQ,CAC3B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,WAAW,EACnC,OAAO,EACP,KAAK,EAAE,UAAU,EAAE,EAAE;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC,CACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport { MsalClientSecret } from \"../msal/nodeFlows/msalClientSecret\";\nimport { credentialLogger } from \"../util/logging\";\nimport { tracingClient } from \"../util/tracing\";\nimport { MsalFlow } from \"../msal/flows\";\nimport { ClientSecretCredentialOptions } from \"./clientSecretCredentialOptions\";\n\nconst logger = credentialLogger(\"ClientSecretCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using a client secret\n * that was generated for an App Registration. More information on how\n * to configure a client secret can be found here:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application\n *\n */\nexport class ClientSecretCredential implements TokenCredential {\n private msalFlow: MsalFlow;\n\n /**\n * Creates an instance of the ClientSecretCredential with the details\n * needed to authenticate against Azure Active Directory with a client\n * secret.\n *\n * @param tenantId - The Azure Active Directory tenant (directory) ID.\n * @param clientId - The client (application) ID of an App Registration in the tenant.\n * @param clientSecret - A client secret that was generated for the App Registration.\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n clientSecret: string,\n options: ClientSecretCredentialOptions = {}\n ) {\n if (!tenantId || !clientId || !clientSecret) {\n throw new Error(\n \"ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.\"\n );\n }\n this.msalFlow = new MsalClientSecret({\n ...options,\n logger,\n clientId,\n tenantId,\n clientSecret,\n tokenCredentialOptions: options,\n });\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(\n `${this.constructor.name}.getToken`,\n options,\n async (newOptions) => {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n return this.msalFlow.getToken(arrayScopes, newOptions);\n }\n );\n }\n}\n"]}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=clientSecretCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientSecretCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/clientSecretCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Optional parameters for the {@link ClientSecretCredential} class.\n */\nexport interface ClientSecretCredentialOptions\n extends TokenCredentialOptions,\n CredentialPersistenceOptions {\n // TODO: Export again once we're ready to release this feature.\n // /**\n // * Specifies a regional authority. Please refer to the {@link RegionalAuthority} type for the accepted values.\n // * If {@link RegionalAuthority.AutoDiscoverRegion} is specified, we will try to discover the regional authority endpoint.\n // * If the property is not specified, the credential uses the global authority endpoint.\n // */\n // regionalAuthority?: string;\n}\n"]}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=credentialPersistenceOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"credentialPersistenceOptions.js","sourceRoot":"","sources":["../../../src/credentials/credentialPersistenceOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCachePersistenceOptions } from \"../msal/nodeFlows/tokenCachePersistenceOptions\";\n\n/**\n * Shared configuration options for credentials that support persistent token\n * caching.\n */\nexport interface CredentialPersistenceOptions {\n /**\n * Options to provide to the persistence layer (if one is available) when\n * storing credentials.\n *\n * You must first register a persistence provider plugin. See the\n * `@azure/identity-cache-persistence` package on NPM.\n *\n * Example:\n *\n * ```javascript\n * import { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\n * import { useIdentityPlugin, DeviceCodeCredential } from \"@azure/identity\";\n *\n * useIdentityPlugin(cachePersistencePlugin);\n *\n * async function main() {\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true\n * }\n * });\n * }\n *\n * main().catch((error) => {\n * console.error(\"An error occurred:\", error);\n * process.exit(1);\n * });\n * ```\n */\n\n tokenCachePersistenceOptions?: TokenCachePersistenceOptions;\n}\n"]}
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
import { ChainedTokenCredential } from "./chainedTokenCredential";
const BrowserNotSupportedError = new Error("DefaultAzureCredential is not supported in the browser. Use InteractiveBrowserCredential instead.");
const logger = credentialLogger("DefaultAzureCredential");
/**
* Provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js.
*/
export class DefaultAzureCredential extends ChainedTokenCredential {
/**
* Creates an instance of the DefaultAzureCredential class.
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(_tokenCredentialOptions) {
super();
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=defaultAzureCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"defaultAzureCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/defaultAzureCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,mGAAmG,CACpG,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,OAAO,sBAAuB,SAAQ,sBAAsB;IAChE;;;;OAIG;IACH,YAAY,uBAAgD;QAC1D,KAAK,EAAE,CAAC;QACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport { ChainedTokenCredential } from \"./chainedTokenCredential\";\n\nconst BrowserNotSupportedError = new Error(\n \"DefaultAzureCredential is not supported in the browser. Use InteractiveBrowserCredential instead.\"\n);\nconst logger = credentialLogger(\"DefaultAzureCredential\");\n\n/**\n * Provides a default {@link ChainedTokenCredential} configuration for\n * applications that will be deployed to Azure.\n *\n * Only available in Node.js.\n */\nexport class DefaultAzureCredential extends ChainedTokenCredential {\n /**\n * Creates an instance of the DefaultAzureCredential class.\n *\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(_tokenCredentialOptions?: TokenCredentialOptions) {\n super();\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ChainedTokenCredential } from "./chainedTokenCredential";
import { AzureCliCredential } from "./azureCliCredential";
import { AzurePowerShellCredential } from "./azurePowerShellCredential";
import { EnvironmentCredential } from "./environmentCredential";
import { ManagedIdentityCredential, } from "./managedIdentityCredential";
import { VisualStudioCodeCredential } from "./visualStudioCodeCredential";
/**
* A shim around ManagedIdentityCredential that adapts it to accept
* `DefaultAzureCredentialOptions`.
*
* @internal
*/
export class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
// Constructor overload with just the other default options
// Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
constructor(options) {
var _a;
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
// ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
if (managedResourceId) {
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
super(managedIdentityResourceIdOptions);
}
else if (managedIdentityClientId) {
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
super(managedIdentityClientOptions);
}
else {
super(options);
}
}
}
export const defaultCredentials = [
EnvironmentCredential,
DefaultManagedIdentityCredential,
VisualStudioCodeCredential,
AzureCliCredential,
AzurePowerShellCredential,
];
/**
* Provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications that use the Azure SDK.
*/
export class DefaultAzureCredential extends ChainedTokenCredential {
constructor(options) {
super(...defaultCredentials.map((ctor) => new ctor(options)));
this.UnavailableMessage =
"DefaultAzureCredential => failed to retrieve a token from the included credentials. To troubleshoot, visit https://aka.ms/azsdk/js/identity/defaultazurecredential/troubleshoot.";
}
}
//# sourceMappingURL=defaultAzureCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("DeviceCodeCredential is not supported in the browser.");
const logger = credentialLogger("DeviceCodeCredential");
/**
* Enables authentication to Azure Active Directory using a device code
* that the user can enter into https://microsoft.com/devicelogin.
*/
export class DeviceCodeCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=deviceCodeCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"deviceCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/deviceCodeCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;AACpG,MAAM,MAAM,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAC/B;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\"DeviceCodeCredential is not supported in the browser.\");\nconst logger = credentialLogger(\"DeviceCodeCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using a device code\n * that the user can enter into https://microsoft.com/devicelogin.\n */\nexport class DeviceCodeCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,79 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { MsalDeviceCode } from "../msal/nodeFlows/msalDeviceCode";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("DeviceCodeCredential");
/**
* Method that logs the user code from the DeviceCodeCredential.
* @param deviceCodeInfo - The device code.
*/
export function defaultDeviceCodePromptCallback(deviceCodeInfo) {
console.log(deviceCodeInfo.message);
}
/**
* Enables authentication to Azure Active Directory using a device code
* that the user can enter into https://microsoft.com/devicelogin.
*/
export class DeviceCodeCredential {
/**
* Creates an instance of DeviceCodeCredential with the details needed
* to initiate the device code authorization flow with Azure Active Directory.
*
* A message will be logged, giving users a code that they can use to authenticate once they go to https://microsoft.com/devicelogin
*
* Developers can configure how this message is shown by passing a custom `userPromptCallback`:
*
* ```js
* const credential = new DeviceCodeCredential({
* tenantId: env.AZURE_TENANT_ID,
* clientId: env.AZURE_CLIENT_ID,
* userPromptCallback: (info) => {
* console.log("CUSTOMIZED PROMPT CALLBACK", info.message);
* }
* });
* ```
*
* @param options - Options for configuring the client which makes the authentication requests.
*/
constructor(options) {
this.msalFlow = new MsalDeviceCode(Object.assign(Object.assign({}, options), { logger, userPromptCallback: (options === null || options === void 0 ? void 0 : options.userPromptCallback) || defaultDeviceCodePromptCallback, tokenCredentialOptions: options || {} }));
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async authenticate(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
await this.msalFlow.getToken(arrayScopes, newOptions);
return this.msalFlow.getActiveAccount();
});
}
}
//# sourceMappingURL=deviceCodeCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=deviceCodeCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"deviceCodeCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/deviceCodeCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { InteractiveCredentialOptions } from \"./interactiveCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Provides the user code and verification URI where the code must be\n * entered. Also provides a message to display to the user which\n * contains an instruction with these details.\n */\nexport interface DeviceCodeInfo {\n /**\n * The device code that the user must enter into the verification page.\n */\n userCode: string;\n\n /**\n * The verification URI to which the user must navigate to enter the device\n * code.\n */\n verificationUri: string;\n\n /**\n * A message that may be shown to the user to instruct them on how to enter\n * the device code in the page specified by the verification URI.\n */\n message: string;\n}\n\n/**\n * Defines the signature of a callback which will be passed to\n * DeviceCodeCredential for the purpose of displaying authentication\n * details to the user.\n */\nexport type DeviceCodePromptCallback = (deviceCodeInfo: DeviceCodeInfo) => void;\n\n/**\n * Defines options for the InteractiveBrowserCredential class for Node.js.\n */\nexport interface DeviceCodeCredentialOptions\n extends InteractiveCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId?: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId?: string;\n /**\n * A callback function that will be invoked to show {@link DeviceCodeInfo} to the user.\n * If left unassigned, we will automatically log the device code information\n * and the authentication instructions in the console.\n */\n userPromptCallback?: DeviceCodePromptCallback;\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("EnvironmentCredential is not supported in the browser.");
const logger = credentialLogger("EnvironmentCredential");
/**
* Enables authentication to Azure Active Directory using client secret
* details configured in environment variables
*/
export class EnvironmentCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=environmentCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"environmentCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/environmentCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,wDAAwD,CACzD,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAChC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"EnvironmentCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"EnvironmentCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using client secret\n * details configured in environment variables\n */\nexport class EnvironmentCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError, formatSuccess, processEnvVars } from "../util/logging";
import { ClientSecretCredential } from "./clientSecretCredential";
import { AuthenticationError, CredentialUnavailableError } from "../errors";
import { checkTenantId } from "../util/checkTenantId";
import { tracingClient } from "../util/tracing";
import { ClientCertificateCredential } from "./clientCertificateCredential";
import { UsernamePasswordCredential } from "./usernamePasswordCredential";
/**
* Contains the list of all supported environment variable names so that an
* appropriate error message can be generated when no credentials can be
* configured.
*
* @internal
*/
export const AllSupportedEnvironmentVariables = [
"AZURE_TENANT_ID",
"AZURE_CLIENT_ID",
"AZURE_CLIENT_SECRET",
"AZURE_CLIENT_CERTIFICATE_PATH",
"AZURE_USERNAME",
"AZURE_PASSWORD",
];
const credentialName = "EnvironmentCredential";
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using client secret
* details configured in environment variables
*/
export class EnvironmentCredential {
/**
* Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables.
*
* Required environment variables:
* - `AZURE_TENANT_ID`: The Azure Active Directory tenant (directory) ID.
* - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant.
*
* Environment variables used for client credential authentication:
* - `AZURE_CLIENT_SECRET`: A client secret that was generated for the App Registration.
* - `AZURE_CLIENT_CERTIFICATE_PATH`: The path to a PEM certificate to use during the authentication, instead of the client secret.
*
* Alternatively, users can provide environment variables for username and password authentication:
* - `AZURE_USERNAME`: Username to authenticate with.
* - `AZURE_PASSWORD`: Password to authenticate with.
*
* If the environment variables required to perform the authentication are missing, a {@link CredentialUnavailableError} will be thrown.
* If the authentication fails, or if there's an unknown error, an {@link AuthenticationError} will be thrown.
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(options) {
// Keep track of any missing environment variables for error details
this._credential = undefined;
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
logger.info(`Found the following environment variables: ${assigned}`);
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
if (tenantId) {
checkTenantId(logger, tenantId);
}
if (tenantId && clientId && clientSecret) {
logger.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
return;
}
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
if (tenantId && clientId && certificatePath) {
logger.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath }, options);
return;
}
const username = process.env.AZURE_USERNAME;
const password = process.env.AZURE_PASSWORD;
if (tenantId && clientId && username && password) {
logger.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, options);
}
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - Optional parameters. See {@link GetTokenOptions}.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
if (this._credential) {
try {
const result = await this._credential.getToken(scopes, newOptions);
logger.getToken.info(formatSuccess(scopes));
return result;
}
catch (err) {
const authenticationError = new AuthenticationError(400, {
error: `${credentialName} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
error_description: err.message.toString().split("More details:").join(""),
});
logger.getToken.info(formatError(scopes, authenticationError));
throw authenticationError;
}
}
throw new CredentialUnavailableError(`${credentialName} is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`);
});
}
}
//# sourceMappingURL=environmentCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { MSALAuthCode } from "../msal/browserFlows/msalAuthCode";
const logger = credentialLogger("InteractiveBrowserCredential");
/**
* Enables authentication to Azure Active Directory inside of the web browser
* using the interactive login flow.
*/
export class InteractiveBrowserCredential {
/**
* Creates an instance of the InteractiveBrowserCredential with the
* details needed to authenticate against Azure Active Directory with
* a user identity.
*
* This credential uses the [Authorization Code Flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
* On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
*
* It's recommended that the AAD Applications used are configured to authenticate using Single Page Applications.
* More information here: [link](https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-app-registration#redirect-uri-msaljs-20-with-auth-code-flow).
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(options) {
if (!(options === null || options === void 0 ? void 0 : options.clientId)) {
const error = new Error("The parameter `clientId` cannot be left undefined for the `InteractiveBrowserCredential`");
logger.info(formatError("", error));
throw error;
}
const browserOptions = options;
const loginStyle = browserOptions.loginStyle || "popup";
const loginStyles = ["redirect", "popup"];
if (loginStyles.indexOf(loginStyle) === -1) {
const error = new Error(`Invalid loginStyle: ${browserOptions.loginStyle}. Should be any of the following: ${loginStyles.join(", ")}.`);
logger.info(formatError("", error));
throw error;
}
const msalOptions = Object.assign(Object.assign({}, options), { logger, loginStyle: loginStyle, redirectUri: typeof options.redirectUri === "function" ? options.redirectUri() : options.redirectUri });
this.msalFlow = new MSALAuthCode(msalOptions);
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async authenticate(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
await this.msalFlow.getToken(arrayScopes, newOptions);
return this.msalFlow.getActiveAccount();
});
}
}
//# sourceMappingURL=interactiveBrowserCredential.browser.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { MsalOpenBrowser } from "../msal/nodeFlows/msalOpenBrowser";
const logger = credentialLogger("InteractiveBrowserCredential");
/**
* Enables authentication to Azure Active Directory inside of the web browser
* using the interactive login flow.
*/
export class InteractiveBrowserCredential {
/**
* Creates an instance of InteractiveBrowserCredential with the details needed.
*
* This credential uses the [Authorization Code Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
* On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
*
* For Node.js, if a `clientId` is provided, the Azure Active Directory application will need to be configured to have a "Mobile and desktop applications" redirect endpoint.
* Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://docs.microsoft.com/azure/active-directory/develop/scenario-desktop-app-registration#redirect-uris).
*
* @param options - Options for configuring the client which makes the authentication requests.
*/
constructor(options = {}) {
const redirectUri = typeof options.redirectUri === "function"
? options.redirectUri()
: options.redirectUri || "http://localhost";
this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger,
redirectUri }));
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
*
* On Node.js, this credential has [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636) enabled by default.
* PKCE is a security feature that mitigates authentication code interception attacks.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async authenticate(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
await this.msalFlow.getToken(arrayScopes, newOptions);
return this.msalFlow.getActiveAccount();
});
}
}
//# sourceMappingURL=interactiveBrowserCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=interactiveBrowserCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"interactiveBrowserCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/interactiveBrowserCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { InteractiveCredentialOptions } from \"./interactiveCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * (Browser-only feature)\n * The \"login style\" to use in the authentication flow:\n * - \"redirect\" redirects the user to the authentication page and then\n * redirects them back to the page once authentication is completed.\n * - \"popup\" opens a new browser window through with the redirect flow\n * is initiated. The user's existing browser window does not leave\n * the current page\n */\nexport type BrowserLoginStyle = \"redirect\" | \"popup\";\n\n/**\n * Defines the common options for the InteractiveBrowserCredential class.\n */\nexport interface InteractiveBrowserCredentialNodeOptions\n extends InteractiveCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * Gets the redirect URI of the application. This should be same as the value\n * in the application registration portal. Defaults to `window.location.href`.\n */\n redirectUri?: string | (() => string);\n\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId?: string;\n\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId?: string;\n\n /**\n * loginHint allows a user name to be pre-selected for interactive logins.\n * Setting this option skips the account selection prompt and immediately attempts to login with the specified account.\n */\n loginHint?: string;\n}\n\n/**\n * Defines the common options for the InteractiveBrowserCredential class.\n */\nexport interface InteractiveBrowserCredentialInBrowserOptions extends InteractiveCredentialOptions {\n /**\n * Gets the redirect URI of the application. This should be same as the value\n * in the application registration portal. Defaults to `window.location.href`.\n */\n redirectUri?: string | (() => string);\n\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId?: string;\n\n /**\n * The client (application) ID of an App Registration in the tenant.\n * This parameter is required on the browser.\n */\n clientId: string;\n\n /**\n * Specifies whether a redirect or a popup window should be used to\n * initiate the user authentication flow. Possible values are \"redirect\"\n * or \"popup\" (default) for browser and \"popup\" (default) for node.\n *\n */\n loginStyle?: BrowserLoginStyle;\n\n /**\n * loginHint allows a user name to be pre-selected for interactive logins.\n * Setting this option skips the account selection prompt and immediately attempts to login with the specified account.\n */\n loginHint?: string;\n}\n"]}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=interactiveCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"interactiveCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/interactiveCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { AuthenticationRecord } from \"../msal/types\";\n\n/**\n * Common constructor options for the Identity credentials that requires user interaction.\n */\nexport interface InteractiveCredentialOptions extends TokenCredentialOptions {\n /**\n * Result of a previous authentication that can be used to retrieve the cached credentials of each individual account.\n * This is necessary to provide in case the application wants to work with more than one account per\n * Client ID and Tenant ID pair.\n *\n * This record can be retrieved by calling to the credential's `authenticate()` method, as follows:\n *\n * const authenticationRecord = await credential.authenticate();\n *\n */\n authenticationRecord?: AuthenticationRecord;\n\n /**\n * Makes getToken throw if a manual authentication is necessary.\n * Developers will need to call to `authenticate()` to control when to manually authenticate.\n */\n disableAutomaticAuthentication?: boolean;\n}\n"]}
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - AppServiceMSI 2017";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
// App Service always returns string expires_on values.
return Date.parse(requestBody.expires_on);
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": "2017-09-01",
};
if (clientId) {
queryParameters.clientid = clientId;
}
const query = new URLSearchParams(queryParameters);
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.MSI_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: MSI_ENDPOINT`);
}
if (!process.env.MSI_SECRET) {
throw new Error(`${msiName}: Missing environment variable: MSI_SECRET`);
}
return {
url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
secret: process.env.MSI_SECRET,
}),
};
}
/**
* Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
*/
export const appServiceMsi2017 = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const env = process.env;
const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
if (resourceId) {
logger.warning(`${msiName}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
}
logger.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=appServiceMsi2017.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
// App Service always returns string expires_on values.
return Date.parse(requestBody.expires_on);
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": "2019-08-01",
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.mi_res_id = resourceId;
}
const query = new URLSearchParams(queryParameters);
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.IDENTITY_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
}
if (!process.env.IDENTITY_HEADER) {
throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
}
return {
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
"X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
}),
};
}
/**
* Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
*/
export const appServiceMsi2019 = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const env = process.env;
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
logger.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=appServiceMsi2019.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,116 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { readFile } from "fs";
import { AuthenticationError } from "../../errors";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
import { azureArcAPIVersion } from "./constants";
const msiName = "ManagedIdentityCredential - Azure Arc MSI";
const logger = credentialLogger(msiName);
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": azureArcAPIVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.IDENTITY_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
}
const query = new URLSearchParams(queryParameters);
return createPipelineRequest({
// Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
Metadata: "true",
}),
});
}
/**
* Retrieves the file contents at the given path using promises.
* Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
*/
function readFileAsync(path, options) {
return new Promise((resolve, reject) => readFile(path, options, (err, data) => {
if (err) {
reject(err);
}
resolve(data);
}));
}
/**
* Does a request to the authentication provider that results in a file path.
*/
async function filePathRequest(identityClient, requestPrepareOptions) {
const response = await identityClient.sendRequest(createPipelineRequest(requestPrepareOptions));
if (response.status !== 401) {
let message = "";
if (response.bodyAsText) {
message = ` Response: ${response.bodyAsText}`;
}
throw new AuthenticationError(response.status, `${msiName}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
}
const authHeader = response.headers.get("www-authenticate") || "";
try {
return authHeader.split("=").slice(1)[0];
}
catch (e) {
throw Error(`Invalid www-authenticate header format: ${authHeader}`);
}
}
/**
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
*/
export const arcMsi = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
if (!result) {
logger.info(`${msiName}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
var _a;
const { identityClient, scopes, clientId, resourceId } = configuration;
if (clientId) {
logger.warning(`${msiName}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
}
if (resourceId) {
logger.warning(`${msiName}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
}
logger.info(`${msiName}: Authenticating.`);
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true });
const filePath = await filePathRequest(identityClient, requestOptions);
if (!filePath) {
throw new Error(`${msiName}: Failed to find the token file.`);
}
const key = await readFileAsync(filePath, { encoding: "utf-8" });
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
const request = createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=arcMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - CloudShellMSI";
export const logger = credentialLogger(msiName);
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const body = {
resource,
};
if (clientId) {
body.client_id = clientId;
}
if (resourceId) {
body.msi_res_id = resourceId;
}
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.MSI_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: MSI_ENDPOINT`);
}
const params = new URLSearchParams(body);
return {
url: process.env.MSI_ENDPOINT,
method: "POST",
body: params.toString(),
headers: createHttpHeaders({
Accept: "application/json",
Metadata: "true",
"Content-Type": "application/x-www-form-urlencoded",
}),
};
}
/**
* Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
* Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
*/
export const cloudShellMsi = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const result = Boolean(process.env.MSI_ENDPOINT);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
if (clientId) {
logger.warning(`${msiName}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
}
if (resourceId) {
logger.warning(`${msiName}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
}
logger.info(`${msiName}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=cloudShellMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export const DefaultScopeSuffix = "/.default";
export const imdsHost = "http://169.254.169.254";
export const imdsEndpointPath = "/metadata/identity/oauth2/token";
export const imdsApiVersion = "2018-02-01";
export const azureArcAPIVersion = "2019-11-01";
export const azureFabricVersion = "2019-07-01-preview";
//# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC9C,MAAM,CAAC,MAAM,QAAQ,GAAG,wBAAwB,CAAC;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,iCAAiC,CAAC;AAClE,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nexport const DefaultScopeSuffix = \"/.default\";\nexport const imdsHost = \"http://169.254.169.254\";\nexport const imdsEndpointPath = \"/metadata/identity/oauth2/token\";\nexport const imdsApiVersion = \"2018-02-01\";\nexport const azureArcAPIVersion = \"2019-11-01\";\nexport const azureFabricVersion = \"2019-07-01-preview\";\n"]}
@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import https from "https";
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
import { azureFabricVersion } from "./constants";
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
//
// FROM node:12
// RUN wget https://host.any/path/bash.sh
// CMD ["bash", "bash.sh"]
//
// Where the bash script contains:
//
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
//
const msiName = "ManagedIdentityCredential - Fabric MSI";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
// Parses a string representation of the milliseconds since epoch into a number value
return Number(requestBody.expires_on);
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": azureFabricVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
const query = new URLSearchParams(queryParameters);
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.IDENTITY_ENDPOINT) {
throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
}
if (!process.env.IDENTITY_HEADER) {
throw new Error("Missing environment variable: IDENTITY_HEADER");
}
return {
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
secret: process.env.IDENTITY_HEADER,
}),
};
}
/**
* Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
*/
export const fabricMsi = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const env = process.env;
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { scopes, identityClient, clientId, resourceId } = configuration;
if (resourceId) {
logger.warning(`${msiName}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
}
logger.info([
`${msiName}:`,
"Using the endpoint and the secret coming from the environment variables:",
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
"IDENTITY_HEADER=[REDACTED] and",
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
].join(" "));
const request = createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)));
request.agent = new https.Agent({
// This is necessary because Service Fabric provides a self-signed certificate.
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
rejectUnauthorized: false,
});
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=fabricMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,161 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { delay } from "@azure/core-util";
import { RestError, createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { AuthenticationError } from "../../errors";
import { tracingClient } from "../../util/tracing";
import { imdsApiVersion, imdsEndpointPath, imdsHost } from "./constants";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - IMDS";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
if (requestBody.expires_on) {
// Use the expires_on timestamp if it's available
const expires = +requestBody.expires_on * 1000;
logger.info(`${msiName}: Using expires_on: ${expires} (original value: ${requestBody.expires_on})`);
return expires;
}
else {
// If these aren't possible, use expires_in and calculate a timestamp
const expires = Date.now() + requestBody.expires_in * 1000;
logger.info(`${msiName}: IMDS using expires_in: ${expires} (original value: ${requestBody.expires_in})`);
return expires;
}
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId, options) {
var _a;
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const { skipQuery, skipMetadataHeader } = options || {};
let query = "";
// Pod Identity will try to process this request even if the Metadata header is missing.
// We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
if (!skipQuery) {
const queryParameters = {
resource,
"api-version": imdsApiVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
const params = new URLSearchParams(queryParameters);
query = `?${params.toString()}`;
}
const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
const rawHeaders = {
Accept: "application/json",
Metadata: "true",
};
// Remove the Metadata header to invoke a request error from some IMDS endpoints.
if (skipMetadataHeader) {
delete rawHeaders.Metadata;
}
return {
// In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
url: `${url}${query}`,
method: "GET",
headers: createHttpHeaders(rawHeaders),
};
}
// 800ms -> 1600ms -> 3200ms
export const imdsMsiRetryConfig = {
maxRetries: 3,
startDelayInMs: 800,
intervalIncrement: 2,
};
/**
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
*/
export const imdsMsi = {
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
return true;
}
if (!identityClient) {
throw new Error("Missing IdentityClient");
}
const requestOptions = prepareRequestOptions(resource, clientId, resourceId, {
skipMetadataHeader: true,
skipQuery: true,
});
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
var _a, _b;
requestOptions.tracingOptions = options.tracingOptions;
try {
// Create a request with a timeout since we expect that
// not having a "Metadata" header should cause an error to be
// returned quickly from the endpoint, proving its availability.
const request = createPipelineRequest(requestOptions);
request.timeout = (_b = (_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) !== null && _b !== void 0 ? _b : 300;
// This MSI uses the imdsEndpoint to get the token, which only uses http://
request.allowInsecureConnection = true;
try {
logger.info(`${msiName}: Pinging the Azure IMDS endpoint`);
await identityClient.sendRequest(request);
}
catch (err) {
if ((err.name === "RestError" && err.code === RestError.REQUEST_SEND_ERROR) ||
err.name === "AbortError" ||
err.code === "ENETUNREACH" || // Network unreachable
err.code === "ECONNREFUSED" || // connection refused
err.code === "EHOSTDOWN" // host is down
) {
// If the request failed, or Node.js was unable to establish a connection,
// or the host was down, we'll assume the IMDS endpoint isn't available.
logger.info(`${msiName}: The Azure IMDS endpoint is unavailable`);
return false;
}
}
// If we received any response, the endpoint is available
logger.info(`${msiName}: The Azure IMDS endpoint is available`);
return true;
}
catch (err) {
// createWebResource failed.
// This error should bubble up to the user.
logger.info(`${msiName}: Error when creating the WebResource for the Azure IMDS endpoint: ${err.message}`);
throw err;
}
});
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
logger.info(`${msiName}: Using the Azure IMDS endpoint coming from the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
try {
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
}
catch (error) {
if (error.statusCode === 404) {
await delay(nextDelayInMs);
nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
continue;
}
throw error;
}
}
throw new AuthenticationError(404, `${msiName}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
},
};
//# sourceMappingURL=imdsMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../../util/logging";
const BrowserNotSupportedError = new Error("ManagedIdentityCredential is not supported in the browser.");
const logger = credentialLogger("ManagedIdentityCredential");
export class ManagedIdentityCredential {
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
async getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=index.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D,MAAM,OAAO,yBAAyB;IAGpC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ManagedIdentityCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\nexport class ManagedIdentityCredential implements TokenCredential {\n constructor(clientId: string, options?: TokenCredentialOptions);\n constructor(options?: TokenCredentialOptions);\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public async getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,194 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { IdentityClient } from "../../client/identityClient";
import { AuthenticationError, CredentialUnavailableError } from "../../errors";
import { credentialLogger, formatError, formatSuccess } from "../../util/logging";
import { appServiceMsi2017 } from "./appServiceMsi2017";
import { tracingClient } from "../../util/tracing";
import { cloudShellMsi } from "./cloudShellMsi";
import { imdsMsi } from "./imdsMsi";
import { arcMsi } from "./arcMsi";
import { tokenExchangeMsi } from "./tokenExchangeMsi";
import { fabricMsi } from "./fabricMsi";
import { appServiceMsi2019 } from "./appServiceMsi2019";
const logger = credentialLogger("ManagedIdentityCredential");
/**
* Attempts authentication using a managed identity available at the deployment environment.
* This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
* Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.
*
* More information about configuring managed identities can be found here:
* https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
*/
export class ManagedIdentityCredential {
/**
* @internal
* @hidden
*/
constructor(clientIdOrOptions, options) {
this.isEndpointUnavailable = null;
let _options;
if (typeof clientIdOrOptions === "string") {
this.clientId = clientIdOrOptions;
_options = options;
}
else {
this.clientId = clientIdOrOptions === null || clientIdOrOptions === void 0 ? void 0 : clientIdOrOptions.clientId;
_options = clientIdOrOptions;
}
this.resourceId = _options === null || _options === void 0 ? void 0 : _options.resourceId;
// For JavaScript users.
if (this.clientId && this.resourceId) {
throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
}
this.identityClient = new IdentityClient(_options);
this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
maxRetries: 0,
} }));
}
async cachedAvailableMSI(scopes, getTokenOptions) {
if (this.cachedMSI) {
return this.cachedMSI;
}
const MSIs = [
arcMsi,
fabricMsi,
appServiceMsi2019,
appServiceMsi2017,
cloudShellMsi,
tokenExchangeMsi(),
imdsMsi,
];
for (const msi of MSIs) {
if (await msi.isAvailable({
scopes,
identityClient: this.isAvailableIdentityClient,
clientId: this.clientId,
resourceId: this.resourceId,
getTokenOptions,
})) {
this.cachedMSI = msi;
return msi;
}
}
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
}
async authenticateManagedIdentity(scopes, getTokenOptions) {
const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
try {
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
return availableMSI.getToken({
identityClient: this.identityClient,
scopes,
clientId: this.clientId,
resourceId: this.resourceId,
}, updatedOptions);
}
catch (err) {
span.setStatus({
status: "error",
error: err,
});
throw err;
}
finally {
span.end();
}
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
* If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options) {
let result = null;
const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.getToken`, options);
try {
// isEndpointAvailable can be true, false, or null,
// If it's null, it means we don't yet know whether
// the endpoint is available and need to check for it.
if (this.isEndpointUnavailable !== true) {
result = await this.authenticateManagedIdentity(scopes, updatedOptions);
if (result === null) {
// If authenticateManagedIdentity returns null,
// it means no MSI endpoints are available.
// If so, we avoid trying to reach to them in future requests.
this.isEndpointUnavailable = true;
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
// yet we had no access token. For this reason, we'll throw once with a specific message:
const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
logger.getToken.info(formatError(scopes, error));
throw error;
}
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
// We will assume that this endpoint is reachable from this point forward,
// and avoid pinging again to it.
this.isEndpointUnavailable = false;
}
else {
// We've previously determined that the endpoint was unavailable,
// either because it was unreachable or permanently unable to authenticate.
const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
logger.getToken.info(formatError(scopes, error));
throw error;
}
logger.getToken.info(formatSuccess(scopes));
return result;
}
catch (err) {
// CredentialUnavailable errors are expected to reach here.
// We intend them to bubble up, so that DefaultAzureCredential can catch them.
if (err.name === "AuthenticationRequiredError") {
throw err;
}
// Expected errors to reach this point:
// - Errors coming from a method unexpectedly breaking.
// - When identityClient.sendTokenRequest throws, in which case
// if the status code was 400, it means that the endpoint is working,
// but no identity is available.
span.setStatus({
status: "error",
error: err,
});
// If either the network is unreachable,
// we can safely assume the credential is unavailable.
if (err.code === "ENETUNREACH") {
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
logger.getToken.info(formatError(scopes, error));
throw error;
}
// If either the host was unreachable,
// we can safely assume the credential is unavailable.
if (err.code === "EHOSTUNREACH") {
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
logger.getToken.info(formatError(scopes, error));
throw error;
}
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
// and it means that the endpoint is working, but that no identity is available.
if (err.statusCode === 400) {
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
}
// If the error has no status code, we can assume there was no available identity.
// This will throw silently during any ChainedTokenCredential.
if (err.statusCode === undefined) {
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Authentication failed. Message ${err.message}`);
}
// Any other error should break the chain.
throw new AuthenticationError(err.statusCode, {
error: `${ManagedIdentityCredential.name} authentication failed.`,
error_description: err.message,
});
}
finally {
// Finally is always called, both if we return and if we throw in the above try/catch.
span.end();
}
}
}
//# sourceMappingURL=index.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { IdentityClient, TokenResponseParsedBody } from \"../../client/identityClient\";\n\n/**\n * @internal\n */\nexport type MSIExpiresInParser = (requestBody: TokenResponseParsedBody) => number;\n\n/**\n * @internal\n */\nexport interface MSIConfiguration {\n identityClient: IdentityClient;\n scopes: string | string[];\n clientId?: string;\n resourceId?: string;\n}\n\n/**\n * @internal\n */\nexport interface MSI {\n isAvailable(options: {\n scopes: string | string[];\n identityClient?: IdentityClient;\n clientId?: string;\n resourceId?: string;\n getTokenOptions?: GetTokenOptions;\n }): Promise<boolean>;\n getToken(\n configuration: MSIConfiguration,\n getTokenOptions?: GetTokenOptions\n ): Promise<AccessToken | null>;\n}\n"]}
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import fs from "fs";
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { promisify } from "util";
import { DefaultAuthorityHost } from "../../constants";
import { credentialLogger } from "../../util/logging";
const msiName = "ManagedIdentityCredential - Token Exchange";
const logger = credentialLogger(msiName);
const readFileAsync = promisify(fs.readFile);
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientAssertion, clientId) {
var _a;
const bodyParams = {
scope: Array.isArray(scopes) ? scopes.join(" ") : scopes,
client_assertion: clientAssertion,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_id: clientId,
grant_type: "client_credentials",
};
const urlParams = new URLSearchParams(bodyParams);
const url = new URL(`${process.env.AZURE_TENANT_ID}/oauth2/v2.0/token`, (_a = process.env.AZURE_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : DefaultAuthorityHost);
return {
url: url.toString(),
method: "POST",
body: urlParams.toString(),
headers: createHttpHeaders({
Accept: "application/json",
}),
};
}
/**
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
*/
export function tokenExchangeMsi() {
const azureFederatedTokenFilePath = process.env.AZURE_FEDERATED_TOKEN_FILE;
let azureFederatedTokenFileContent = undefined;
let cacheDate = undefined;
// Only reads from the assertion file once every 5 minutes
async function readAssertion() {
// Cached assertions expire after 5 minutes
if (cacheDate !== undefined && Date.now() - cacheDate >= 1000 * 60 * 5) {
azureFederatedTokenFileContent = undefined;
}
if (!azureFederatedTokenFileContent) {
const file = await readFileAsync(azureFederatedTokenFilePath, "utf8");
const value = file.trim();
if (!value) {
throw new Error(`No content on the file ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
}
else {
azureFederatedTokenFileContent = value;
cacheDate = Date.now();
}
}
return azureFederatedTokenFileContent;
}
return {
async isAvailable({ clientId }) {
const env = process.env;
const result = Boolean((clientId || env.AZURE_CLIENT_ID) && env.AZURE_TENANT_ID && azureFederatedTokenFilePath);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId } = configuration;
logger.info(`${msiName}: Using the client assertion coming from environment variables.`);
let assertion;
try {
assertion = await readAssertion();
}
catch (err) {
throw new Error(`${msiName}: Failed to read ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
}
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
}
//# sourceMappingURL=tokenExchangeMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { DefaultScopeSuffix } from "./constants";
/**
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
* These are GET requests that require sending a `resource` parameter on the query.
* This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
* Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
*
* For that reason, when we encounter multiple scopes, we return undefined.
* It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).
*/
export function mapScopesToResource(scopes) {
let scope = "";
if (Array.isArray(scopes)) {
if (scopes.length !== 1) {
return;
}
scope = scopes[0];
}
else if (typeof scopes === "string") {
scope = scopes;
}
if (!scope.endsWith(DefaultScopeSuffix)) {
return scope;
}
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
}
//# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACzB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB,OAAO;SACR;QAED,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;KACnB;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACrC,KAAK,GAAG,MAAM,CAAC;KAChB;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QACvC,OAAO,KAAK,CAAC;KACd;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAChE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { DefaultScopeSuffix } from \"./constants\";\n\n/**\n * Most MSIs send requests to the IMDS endpoint, or a similar endpoint.\n * These are GET requests that require sending a `resource` parameter on the query.\n * This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.\n * Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.\n *\n * For that reason, when we encounter multiple scopes, we return undefined.\n * It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).\n */\nexport function mapScopesToResource(scopes: string | string[]): string | undefined {\n let scope = \"\";\n if (Array.isArray(scopes)) {\n if (scopes.length !== 1) {\n return;\n }\n\n scope = scopes[0];\n } else if (typeof scopes === \"string\") {\n scope = scopes;\n }\n\n if (!scope.endsWith(DefaultScopeSuffix)) {\n return scope;\n }\n\n return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const credentialName = "OnBehalfOfCredential";
const BrowserNotSupportedError = new Error(`${credentialName}: Not supported in the browser.`);
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
*/
export class OnBehalfOfCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=onBehalfOfCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"onBehalfOfCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/onBehalfOfCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAC9C,MAAM,wBAAwB,GAAG,IAAI,KAAK,CAAC,GAAG,cAAc,iCAAiC,CAAC,CAAC;AAC/F,MAAM,MAAM,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAC/B;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst credentialName = \"OnBehalfOfCredential\";\nconst BrowserNotSupportedError = new Error(`${credentialName}: Not supported in the browser.`);\nconst logger = credentialLogger(credentialName);\n\n/**\n * Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).\n */\nexport class OnBehalfOfCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MsalOnBehalfOf } from "../msal/nodeFlows/msalOnBehalfOf";
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
const credentialName = "OnBehalfOfCredential";
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
*/
export class OnBehalfOfCredential {
constructor(options) {
this.options = options;
const { clientSecret } = options;
const { certificatePath } = options;
const { tenantId, clientId, userAssertionToken } = options;
if (!tenantId || !clientId || !(clientSecret || certificatePath) || !userAssertionToken) {
throw new Error(`${credentialName}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`);
}
this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger, tokenCredentialOptions: this.options }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure the underlying network requests.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=onBehalfOfCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=onBehalfOfCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"onBehalfOfCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/onBehalfOfCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with a secret.\n */\nexport interface OnBehalfOfCredentialSecretOptions {\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * A client secret that was generated for the App Registration.\n */\n clientSecret: string;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n}\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with a certificate.\n */\nexport interface OnBehalfOfCredentialCertificateOptions {\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * The path to a PEM-encoded public/private key certificate on the filesystem.\n */\n certificatePath: string;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n}\n\n/**\n * Optional parameters for the {@link OnBehalfOfCredential} class.\n */\nexport type OnBehalfOfCredentialOptions = (\n | OnBehalfOfCredentialSecretOptions\n | OnBehalfOfCredentialCertificateOptions\n) &\n TokenCredentialOptions &\n CredentialPersistenceOptions;\n"]}
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { IdentityClient } from "../client/identityClient";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
import { tracingClient } from "../util/tracing";
import { checkTenantId } from "../util/checkTenantId";
const logger = credentialLogger("UsernamePasswordCredential");
/**
* Enables authentication to Azure Active Directory with a user's
* username and password. This credential requires a high degree of
* trust so you should only use it when other, more secure credential
* types can't be used.
*/
export class UsernamePasswordCredential {
/**
* Creates an instance of the UsernamePasswordCredential with the details
* needed to authenticate against Azure Active Directory with a username
* and password.
*
* @param tenantIdOrName - The Azure Active Directory tenant (directory) ID or name.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param username - The user account's e-mail address (user name).
* @param password - The user account's account password
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantIdOrName, clientId, username, password, options) {
checkTenantId(logger, tenantIdOrName);
this.identityClient = new IdentityClient(options);
this.tenantId = tenantIdOrName;
this.clientId = clientId;
this.username = username;
this.password = password;
}
/**
* Authenticates with Azure Active Directory and returns an access token if
* successful. If authentication cannot be performed at this time, this method may
* return null. If an error occurs during authentication, an {@link AuthenticationError}
* containing failure details will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options) {
const { span, updatedOptions: newOptions } = tracingClient.startSpan("UsernamePasswordCredential.getToken", options);
try {
const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
const params = new URLSearchParams({
response_type: "token",
grant_type: "password",
client_id: this.clientId,
username: this.username,
password: this.password,
scope: typeof scopes === "string" ? scopes : scopes.join(" "),
});
const webResource = createPipelineRequest({
url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
method: "POST",
body: params.toString(),
headers: createHttpHeaders({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
}),
abortSignal: options && options.abortSignal,
tracingOptions: newOptions.tracingOptions,
});
const tokenResponse = await this.identityClient.sendTokenRequest(webResource);
logger.getToken.info(formatSuccess(scopes));
return (tokenResponse && tokenResponse.accessToken) || null;
}
catch (err) {
span.setStatus({
status: "error",
error: err,
});
logger.getToken.info(formatError(scopes, err));
throw err;
}
finally {
span.end();
}
}
}
//# sourceMappingURL=usernamePasswordCredential.browser.js.map
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More