首页 > 解决方案 > 在 Azure Functions 中获取连接到 PostgreSQL 的访问令牌

问题描述

我已经创建了一些 Azure Functions,我想使用访问令牌连接到 Postgres 数据库(因为用户的连接正在向 Azure Function 的端点发出请求)。我一直在关注这个页面:https ://docs.microsoft.com/en-us/azure/postgresql/howto-configure-sign-in-aad-authentication

对于我的函数中的身份验证/授权,我创建了一个 Azure Active Directory 应用程序(在应用程序注册中)。在这个应用程序中,(不确定这是否有用)我已经授予了 OSSRDBMS API 的权限:

在此处输入图像描述

然后,我得到我的应用服务的下一个端点的访问令牌(我的函数在哪里):

MYAPP_SERVICE.azurewebsites.net/.auth/me

我正在尝试与此访问令牌建立联系,但似乎不是一个好的。我错过了什么或如何获得正确的访问令牌?我了解 Azure CLI 的工作原理,但我正在尝试使用我的应用服务端点的访问令牌......或者我可以执行 HTTP 请求来获取正确的令牌吗?
在这件事上我需要一些指导。



预先感谢

标签: postgresqlazureazure-active-directoryazure-functionsazure-app-service-envrmnt

解决方案


如果要在 Azure 函数中连接 Postgres 数据库和 Azure AD 身份验证,我们可以通过 Azure Managed Identity 进行 Azure AD 身份验证,然后获取 Azure AD 访问令牌并连接数据库。

详细步骤如下

  1. 从 Azure 函数应用启用 Azure MSI 在此处输入图像描述

  2. 获取 MSI 的客户端 ID

az login
az ad sp show --id <the object id of the msi> --query appId --output tsv
  1. 在 Postgres 数据库中配置 Azure AD 管理员

  2. 使用 Azure AD 管理员连接数据库。(我使用 PgAdmin 连接)

SET aad_validate_oids_in_tenant = off;
CREATE ROLE <userName> WITH LOGIN PASSWORD '<the appid of the MSI>' IN ROLE azure_ad_user;
  1. 配置 Postgres 服务器防火墙。请在防火墙中添加 Azure 函数应用出站 IP 地址。关于如何获取 Azure 函数应用出站 IP 地址和配置 Postgres 服务器防火墙,请参考这里这里

  2. 如果您启用 SSL,请通过链接下载SSL 证书

  3. 功能。(我使用 .net core 编写示例)

一个。sdk

 <PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.5.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.8" />
    <PackageReference Include="Npgsql" Version="4.1.3.1" />

湾。在项目中添加上述 SSL 证书。例如,我cert在我的项目中创建一个文件夹并将证书保存在文件夹中

C。代码


        [FunctionName("Http")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log, ExecutionContext context)
        {

            var azureServiceTokenProvider = new AzureServiceTokenProvider();
            string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://ossrdbms-aad.database.windows.net");
         
            string Host = "test05.postgres.database.azure.com";
            string User = "testuer@test05";
            string Database = "postgres";
            string connString =
                String.Format(
                    "Server={0}; User Id={1}; Database={2}; Port={3}; Password={4};SSLMode=Require",
                    Host,
                    User,
                    Database,
                    5432,
                    accessToken);
            string result = string.Empty;
            using (var conn = new NpgsqlConnection(connString))
            {
                ProvideClientCertificatesCallback provideClientCertificates = clientCerts =>
                {
                    string clientCertPath = context.FunctionAppDirectory + "\\cert\\BaltimoreCyberTrustRoot.crt.pem";
                    var cert = new X509Certificate2(clientCertPath);
                    clientCerts.Add(cert);
                };
                conn.ProvideClientCertificatesCallback += provideClientCertificates;
                Console.Out.WriteLine("Opening connection using access token...");
                conn.Open();

                using (var command = new NpgsqlCommand("SELECT version()", conn))
                {

                    var reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        Console.WriteLine("\nConnected!\n\nPostgres version: {0}", reader.GetString(0));
                        result = reader.GetString(0);
                    }
                }
            }
            return new OkObjectResult(result);

        }

在此处输入图像描述

更多详情,请参考这里


推荐阅读