繁体   English   中英

使用托管身份从本地Azure功能查询Azure SQL数据库

[英]Query Azure SQL Database from local Azure Function using Managed Identities

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

我按照Microsoft文档上的本教程进行操作,因此我的Azure SQL Server以AD用户身份为admin,这使我可以授予我使用Azure Function Identity和其中的用户(以及我的Function App)创建的Azure AD组的权限(db_datareader)部署在Azure中)。

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

用户“ 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组的成员),则可以连接和查询数据库而没有任何问题。

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

在尝试了您的特定情况之后,我测试了很多方法来尝试使其在本地工作。 这不起作用,给出的错误信息与您得到的相同。

当可能的解决方案出现时,我与一些人进行了讨论。 我测试了它:它有效!

我遇到的主要问题是我的订阅(和我的用户)是一个Microsoft帐户(Outlook)。 因此,您需要在GetAccessTokenAsync()调用中指定tenantId

显然,对于托管身份,您不必指定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 (或Directory ID,Tenant的GUID)和'onmicrosoft'名称( xxx.onmicrosoft.com )时都可以使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM