Node.js 使用NodeJS中的服务主体连接到Azure SQL,但令牌被拒绝

Node.js 使用NodeJS中的服务主体连接到Azure SQL,但令牌被拒绝,node.js,azure-active-directory,azure-sql-database,azure-service-principal,Node.js,Azure Active Directory,Azure Sql Database,Azure Service Principal,我无法使用服务主体使我的NodeJS应用程序连接到Azure SQL数据库。然而,当我尝试用C代码段做同样的事情时,效果很好。我注意到,auth在两种语言上返回的令牌有点不同,如果我从C#获取正确的令牌并将其硬编码到NodeJS中,我的SQL连接现在成功了 我首先使用msrestazure执行身份验证,并提供我的clientId、tenantId和clientSecret。这将返回一个有效凭证,我将从中提取accessToken 然后,我使用Teddious尝试连接到位于*.database.w

我无法使用服务主体使我的NodeJS应用程序连接到Azure SQL数据库。然而,当我尝试用C代码段做同样的事情时,效果很好。我注意到,auth在两种语言上返回的令牌有点不同,如果我从C#获取正确的令牌并将其硬编码到NodeJS中,我的SQL连接现在成功了

我首先使用msrestazure执行身份验证,并提供我的clientId、tenantId和clientSecret。这将返回一个有效凭证,我将从中提取accessToken

然后,我使用Teddious尝试连接到位于*.database.windows.net的Azure SQL,并在配置中提供accessToken值

我刚刚获得用户“”的登录失败。

我在ms rest azure登录中给了我一个被azure SQL拒绝的令牌,这有什么错?我看到的一件事是,工作令牌的访问群体是database.windows.net,其中来自msrestazure的访问群体是management.core.windows.net

我已经被困了几天了,如果这里有任何线索的话,那就太棒了。msrestazure上的文档似乎不存在,只提供了azure销售页面的参考资料

const msRestAzure = require('ms-rest-azure');
const { reject } = require('async');


let clientSecret = "xxx";
let serverName = "xxx.database.windows.net";
let databaseName = "xxx";
let clientId = "xxx";
let tenantId = "xxx";

azureCredentials = msRestAzure.loginWithServicePrincipalSecret(clientId, clientSecret, tenantId, function(err, credentials) {
    if (err) return console.log(err);
    credentials.getToken((err, results) => {
        if(err) return reject(err);
        
        let accessToken = results.accessToken;

        var Connection = require('tedious').Connection;
        var Request = require('tedious').Request;

        var config = {
            server: serverName,
            authentication: {
                type: 'azure-active-directory-access-token',
                options: {
                    token: accessToken
                }
            }
            ,options: {
                debug: {
                packet: true,
                data: true,
                payload: true,
                token: false,
                log: true
                },
                database: databaseName,
                encrypt: true
            }  
        };

        var connection = new Connection(config);

        connection.connect();

        connection.on('connect', function(err) {
            if(err) {
                console.log(err);
            }
            executeStatement();
        }
        );

        connection.on('debug', function(text) {
            console.log(text);
        }
        );

        function executeStatement() {
        request = new Request("select * from Text", function(err, rowCount) {
            if (err) {
            console.log(err);
            } else {
            console.log(rowCount + ' rows');
            }

            connection.close();
        });

        request.on('row', function(columns) {
            columns.forEach(function(column) {
            if (column.value === null) {
                console.log('NULL');
            } else {
                console.log(column.value);
            }
            });
        });

        request.on('done', function(rowCount, more) {
            console.log(rowCount + ' rows returned');
        });

        connection.execSql(request);
        }
    });   
})

当我们使用包
msrestazure
中的证书来获取令牌时,默认情况下,令牌的访问群体是
https://management.core.windows.net/
,它只能用于调用Azure rest api。如果我们想使用Azure AD令牌连接sql,该令牌的受众应该是
https://database.windows.net/
。因此,我们应该将用于获取令牌的代码更新为

msrestAzure.loginWithServicePrincipalSecret(
    clientId,
    clientSecret,
    tenantId,
    {
      tokenAudience: "https://database.windows.net/",
    },
比如说

  • 创建服务主体
  • 配置SQL数据库
  • a

    b。将服务主体添加到需要使用的数据库中

    create user [<Azure_AD_principal_name>] from external provider
    ALTER ROLE db_owner ADD MEMBER [<Azure_AD_principal_name>]
         
    


    有关更多详细信息,请参阅当我们使用包
    ms rest azure
    中的证书来获取令牌时,默认情况下,令牌的访问群体是
    https://management.core.windows.net/
    ,它只能用于调用Azure rest api。如果我们想使用Azure AD令牌连接sql,该令牌的受众应该是
    https://database.windows.net/
    。因此,我们应该将用于获取令牌的代码更新为

    msrestAzure.loginWithServicePrincipalSecret(
        clientId,
        clientSecret,
        tenantId,
        {
          tokenAudience: "https://database.windows.net/",
        },
    
    比如说

  • 创建服务主体
  • 配置SQL数据库
  • a

    b。将服务主体添加到需要使用的数据库中

    create user [<Azure_AD_principal_name>] from external provider
    ALTER ROLE db_owner ADD MEMBER [<Azure_AD_principal_name>]
         
    


    有关更多详细信息,请参阅

    能否通过分析您的代币?能否通过分析您的代币?