azure-kusto-data
Version:
Azure Data Explorer Query SDK
253 lines • 10.1 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { AzureCliCredential, ManagedIdentityCredential, ClientSecretCredential, ClientCertificateCredential, DeviceCodeCredential, UsernamePasswordCredential, InteractiveBrowserCredential, } from "@azure/identity";
import { CloudSettings } from "./cloudSettings.js";
const BEARER_TYPE = "Bearer";
/**
* This base class abstracts token acquisition for all implementations.
* The class is build for Lazy initialization, so that the first call, take on instantiation of 'heavy' long-lived class members
*/
export class TokenProviderBase {
context() {
return {};
}
constructor(kustoUri) {
this.kustoUri = kustoUri;
if (kustoUri != null) {
const suffix = (!this.kustoUri.endsWith("/") ? "/" : "") + ".default";
this.scopes = [kustoUri + suffix];
}
}
}
/**
* Basic Token Provider keeps and returns a token received on construction
*/
export class BasicTokenProvider extends TokenProviderBase {
constructor(kustoUri, token) {
super(kustoUri);
this.token = token;
}
acquireToken() {
return Promise.resolve({
tokenType: BEARER_TYPE,
accessToken: this.token,
});
}
}
/**
* Callback Token Provider generates a token based on a callback function provided by the caller
*/
export class CallbackTokenProvider extends TokenProviderBase {
constructor(kustoUri, callback) {
super(kustoUri);
this.callback = callback;
}
async acquireToken() {
const token = await this.callback();
return { tokenType: BEARER_TYPE, accessToken: token };
}
}
/**
* Token providers that require cloud settings to be configured - msal and azure identity
*/
export class CloudSettingsTokenProvider extends TokenProviderBase {
additionalCloudSettingsInit() { }
constructor(kustoUri) {
super(kustoUri);
this.initialized = false;
}
async acquireToken() {
if (!this.initialized) {
if (this.cloudInfo == null) {
this.cloudInfo = await CloudSettings.getCloudInfoForCluster(this.kustoUri);
let resourceUri = this.cloudInfo.KustoServiceResourceId;
if (this.cloudInfo.LoginMfaRequired) {
resourceUri = resourceUri.replace(".kusto.", ".kustomfa.");
}
this.scopes = [resourceUri + "/.default"];
this.additionalCloudSettingsInit();
this.initClient();
}
this.initialized = true;
}
const token = await this.acquireTokenWithCloudSettings();
if (token) {
return { tokenType: token.tokenType, accessToken: token.accessToken };
}
throw new Error("Failed to get token from msal");
}
context() {
return Object.assign(Object.assign({}, super.context()), { kustoUri: this.kustoUri });
}
}
export class AzureIdentityProvider extends CloudSettingsTokenProvider {
constructor(kustoUri, authorityId, timeoutMs) {
super(kustoUri);
this.authorityId = authorityId;
this.timeoutMs = timeoutMs;
}
initClient() {
this.credential = this.getCredential();
}
async acquireTokenWithCloudSettings() {
const response = await this.credential.getToken(this.scopes, {
requestOptions: {
timeout: this.timeoutMs,
},
tenantId: this.authorityId,
});
if (response === null) {
throw new Error("Failed to get token from msal");
}
return { tokenType: BEARER_TYPE, accessToken: response.token };
}
context() {
let base = Object.assign(Object.assign({}, super.context()), { kustoUri: this.kustoUri, authorityId: this.authorityId });
if (this.timeoutMs) {
base = Object.assign(Object.assign({}, base), { timeoutMs: this.timeoutMs });
}
return base;
}
}
/**
* TokenCredentialProvider receives any TokenCredential to create a token with.
*/
export class TokenCredentialProvider extends AzureIdentityProvider {
constructor(kustoUri, tokenCredential, timeoutMs) {
super(kustoUri, undefined, timeoutMs);
this.tokenCredential = tokenCredential;
}
getCredential() {
return this.tokenCredential;
}
}
/**
* UserPromptProvider will pop up a login prompt to acquire a token.
*/
export class UserPromptProvider extends AzureIdentityProvider {
constructor(kustoUri, interactiveCredentialOptions, timeoutMs) {
super(kustoUri, interactiveCredentialOptions === null || interactiveCredentialOptions === void 0 ? void 0 : interactiveCredentialOptions.tenantId, timeoutMs);
this.interactiveCredentialOptions = interactiveCredentialOptions;
// The default port is 80, which can lead to permission errors, so we'll choose another port
this.MinPort = 20000;
this.MaxPort = 65536;
}
getCredential() {
var _a, _b, _c, _d;
return new InteractiveBrowserCredential(Object.assign(Object.assign({}, this.interactiveCredentialOptions), { tenantId: this.authorityId, clientId: (_b = (_a = this.interactiveCredentialOptions) === null || _a === void 0 ? void 0 : _a.clientId) !== null && _b !== void 0 ? _b : this.cloudInfo.KustoClientAppId, redirectUri: (_d = (_c = this.interactiveCredentialOptions) === null || _c === void 0 ? void 0 : _c.redirectUri) !== null && _d !== void 0 ? _d : `http://localhost:${this.getRandomPortInRange()}/` }));
}
getRandomPortInRange() {
return Math.floor(Math.random() * (this.MaxPort - this.MinPort) + this.MinPort);
}
context() {
var _a, _b;
let base = super.context();
if ((_a = this.interactiveCredentialOptions) === null || _a === void 0 ? void 0 : _a.loginHint) {
base = Object.assign(Object.assign({}, base), { loginHint: (_b = this.interactiveCredentialOptions) === null || _b === void 0 ? void 0 : _b.loginHint });
}
return base;
}
}
/**
* MSI Token Provider obtains a token from the MSI endpoint
* The args parameter is a dictionary conforming with the ManagedIdentityCredential initializer API arguments
*/
export class MsiTokenProvider extends AzureIdentityProvider {
constructor(kustoUri, clientId, authorityId, timeoutMs) {
super(kustoUri, authorityId, timeoutMs);
this.clientId = clientId;
}
getCredential() {
return this.clientId ? new ManagedIdentityCredential(this.clientId) : new ManagedIdentityCredential();
}
context() {
return Object.assign(Object.assign({}, super.context()), { clientId: this.clientId });
}
}
/**
* AzCli Token Provider obtains a refresh token from the AzCli cache and uses it to authenticate with MSAL
*/
export class AzCliTokenProvider extends AzureIdentityProvider {
getCredential() {
return new AzureCliCredential();
}
}
/**
* Acquire a token from MSAL with username and password
*/
export class UserPassTokenProvider extends AzureIdentityProvider {
constructor(kustoUri, userName, password, authorityId, timeoutMs) {
super(kustoUri, authorityId, timeoutMs);
this.userName = userName;
this.password = password;
}
getCredential() {
return new UsernamePasswordCredential(this.authorityId, this.cloudInfo.KustoClientAppId, this.userName, this.password);
}
context() {
return Object.assign(Object.assign({}, super.context()), { userName: this.userName, homeAccountId: this.homeAccountId });
}
}
/**
* Acquire a token from Device Login flow
*/
export class DeviceLoginTokenProvider extends AzureIdentityProvider {
constructor(kustoUri, deviceCodeCallback, authorityId, timeoutMs) {
super(kustoUri, authorityId, timeoutMs);
this.deviceCodeCallback = deviceCodeCallback;
}
getCredential() {
return new DeviceCodeCredential({
tenantId: this.authorityId,
clientId: this.cloudInfo.KustoClientAppId,
userPromptCallback: this.deviceCodeCallback,
});
}
}
/**
* Acquire a token from MSAL using application certificate
* Passing the public certificate is optional and will result in Subject Name & Issuer Authentication
*/
export class ApplicationCertificateTokenProvider extends AzureIdentityProvider {
constructor(kustoUri, appClientId, certPrivateKey, certPath, sendX5c, authorityId, timeoutMs) {
super(kustoUri, authorityId, timeoutMs);
this.appClientId = appClientId;
this.certPrivateKey = certPrivateKey;
this.certPath = certPath;
this.sendX5c = sendX5c;
}
getCredential() {
if (this.certPrivateKey) {
return new ClientCertificateCredential(this.authorityId, this.appClientId, {
certificate: this.certPrivateKey,
}, {
sendCertificateChain: this.sendX5c,
});
}
return new ClientCertificateCredential(this.authorityId, this.appClientId, this.certPath, {
sendCertificateChain: this.sendX5c,
});
}
context() {
return Object.assign(Object.assign({}, super.context()), { clientId: this.appClientId, sendX5c: this.sendX5c });
}
}
/**
* Acquire a token from MSAL with application id and Key
*/
export class ApplicationKeyTokenProvider extends AzureIdentityProvider {
constructor(kustoUri, appClientId, appKey, authorityId, timeoutMs) {
super(kustoUri, authorityId, timeoutMs);
this.appClientId = appClientId;
this.appKey = appKey;
}
getCredential() {
return new ClientSecretCredential(this.authorityId, // The tenant ID in Azure Active Directory
this.appClientId, // The app registration client Id in the AAD tenant
this.appKey);
}
context() {
return Object.assign(Object.assign({}, super.context()), { clientId: this.appClientId });
}
}
//# sourceMappingURL=tokenProvider.js.map