3

我想使用托管身份(即连接到 Visual Studio 的用户的身份,而不是在我的连接字符串中提供 UserId 和密码)从在我的机器上执行的 Azure 函数中查询 Azure SQL 数据库。

我按照Microsoft 文档上的本教程进行操作,因此我的 Azure SQL Server 有一个 AD 用户作为管理员,它允许我向使用我的 Azure 函数标识和其中的用户(以及我的函数应用程序)创建的 Azure AD 组授予权限(db_datareader)部署在 Azure 中)。

如果我在 Azure 中部署并运行我的 Azure Function,它能够查询我的数据库并且一切正常。但是当我在本地运行 Azure Function 时,出现以下错误:

用户“NT AUTHORITY\ANONYMOUS LOGON”登录失败。

我的函数代码如下:

    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "test")] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");


        using (var connection = new SqlConnection(Environment.GetEnvironmentVariable("sqlConnectionString")))
        {
            connection.AccessToken = await (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net");
            log.LogInformation($"Access token : {connection.AccessToken}");
            try
            {
                await connection.OpenAsync();
                var rows = await connection.QueryAsync<Test>("select top 10 * from TestTable");
                return new OkObjectResult(rows);
            }
            catch (Exception e)
            {
                throw e;
            }

        }
    }

代码正确检索令牌,错误发生在线await connection.OpenAsync()

如果我在 Azure Data Studio 中使用与连接到 Visual Studio 的用户相同的用户(该用户是具有数据库权限的 AD 组的成员)打开数据库,我可以毫无问题地连接和查询数据库。

这是一个已知问题还是我在这里遗漏了什么?

4

2 回答 2

0

您的本地计算机的 IP 地址是否列入白名单?

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-firewall-configure

白名单IP

于 2019-08-15T04:20:21.867 回答
0

在尝试了您的特定场景之后,我测试了很多方法来尝试让它在本地工作。这不起作用,给出了与您得到的相同的错误消息。

当一个可能的解决方案出现时,我和一些人讨论了这个问题。我测试了它:它有效!

我的主要问题是我的订阅(和我的用户)是 Microsoft 帐户(Outlook)。因此,您需要tenantIdGetAccessTokenAsync()调用中指定。

显然,对于托管标识,您不必指定tenantId. 对于用户,明确指定它是个好主意。如果是个人 MS 帐户,则必须指定它。

我的代码(有点):

var tokenProvider = new AzureServiceTokenProvider();

using (var connection = new SqlConnection(CONNECTIONSTRING))
using (var command = new SqlCommand(QUERY, connection))
{
    connection.AccessToken = await tokenProvider.GetAccessTokenAsync("https://database.windows.net/", "<YOUR_TENANT_ID>");

    await connection.OpenAsync();
    var result = (await command.ExecuteScalarAsync()).ToString();

    return new OkObjectResult(result);
}

此解决方案已经过测试,并且在指定tenantId(或目录 ID,租户的 GUID)和“onmicrosoft”名称 ( xxx.onmicrosoft.com) 时均有效。

于 2019-08-19T20:11:03.443 回答