azure managed identity support

This commit is contained in:
SPRINX0\prochazka
2025-02-05 13:05:02 +01:00
parent 6c8cf8e327
commit ac2128dcde
4 changed files with 131 additions and 22 deletions

View File

@@ -72,6 +72,14 @@ const driver = {
}
);
}
if (!platformInfo.isElectron) {
res.push({
title: 'Azure Managed Identity',
name: 'azureManagedIdentity',
disabledFields: ['user', 'password'],
});
}
if (res.length > 0) {
return _.uniqBy(res, 'name');
}
@@ -80,7 +88,8 @@ const driver = {
async connect(conn) {
const { authType } = conn;
const connectionType = platformInfo?.isWindows && (authType == 'sspi' || authType == 'sql') ? 'msnodesqlv8' : 'tedious';
const connectionType =
platformInfo?.isWindows && (authType == 'sspi' || authType == 'sql') ? 'msnodesqlv8' : 'tedious';
const client = connectionType == 'msnodesqlv8' ? await nativeConnect(conn) : await tediousConnect(conn);
return {

View File

@@ -1,6 +1,7 @@
const _ = require('lodash');
const stream = require('stream');
const tedious = require('tedious');
const { ManagedIdentityCredential } = require('@azure/identity');
const makeUniqueColumnNames = require('./makeUniqueColumnNames');
const { extractDbNameFromComposite } = global.DBGATE_PACKAGES['dbgate-tools'];
@@ -23,12 +24,50 @@ function extractTediousColumns(columns, addDriverNativeColumn = false) {
return res;
}
async function getDefaultAzureSqlToken() {
const credential = new ManagedIdentityCredential();
const tokenResponse = await credential.getToken('https://database.windows.net/.default');
return tokenResponse.token;
}
async function getAuthentication({ authType, accessToken, user, password, windowsDomain }) {
switch (authType) {
case 'azureManagedIdentity':
const token = await getDefaultAzureSqlToken();
return {
type: 'azure-active-directory-access-token',
options: {
token,
},
};
case 'msentra':
return {
type: 'azure-active-directory-access-token',
options: {
token: accessToken,
},
};
default:
return {
type: windowsDomain ? 'ntlm' : 'default',
options: {
userName: user,
password: password,
...(windowsDomain ? { domain: windowsDomain } : {}),
},
};
}
}
async function tediousConnect(storedConnection) {
const { server, port, user, password, database, ssl, trustServerCertificate, windowsDomain, authType, accessToken } =
storedConnection;
const { server, port, database, ssl, trustServerCertificate, authType } = storedConnection;
const authentication = await getAuthentication(storedConnection);
return new Promise((resolve, reject) => {
const connectionOptions = {
encrypt: !!ssl || authType == 'msentra',
encrypt: !!ssl || authType == 'msentra' || authType == 'azureManagedIdentity',
cryptoCredentialsDetails: ssl ? _.pick(ssl, ['ca', 'cert', 'key']) : undefined,
trustServerCertificate: ssl ? (!ssl.ca && !ssl.cert && !ssl.key ? true : ssl.rejectUnauthorized) : undefined,
enableArithAbort: true,
@@ -43,23 +82,6 @@ async function tediousConnect(storedConnection) {
connectionOptions.database = extractDbNameFromComposite(database);
}
const authentication =
authType == 'msentra'
? {
type: 'azure-active-directory-access-token',
options: {
token: accessToken,
},
}
: {
type: windowsDomain ? 'ntlm' : 'default',
options: {
userName: user,
password: password,
...(windowsDomain ? { domain: windowsDomain } : {}),
},
};
const connection = new tedious.Connection({
server,
authentication,