0

我有一个不是我创建但现在维护的 Azure 应用程序服务。应用服务通过指纹在 Key Vault 中找到证书,然后使用该证书获取令牌,以便通过夜间作业执行某些 SQL 工作。

证书似乎设置为在其有效日期(12 个月)的 80% 后自动更新。证书更新我夜间工作的那一天开始失败。我有理由确定新证书是问题的根源。

尽我所能告诉它设计为这样工作:

  • 通过 Azure Logic App 触发作业
  • 异常 POST 到报告处理 API(最终结果应该是为电子邮件附件创建 .PDF 报告)
  • API 具有包含当前证书指纹的 Appsetting.json
  • 指纹在下面的代码行中用于在证书存储中查找证书
  • Cert 用于获取访问令牌并执行工作

当我在本地计算机上安装旧证书和新证书并运行整个过程时,它可以使用旧证书找到并在新的自动生成的证书上失败。我尝试在 Azure 中创建并从 Azure 导出并导入到我的开发机器的任何新证书也会失败。我已经对 appsettings 进行了两次/三次检查,以确保相关指纹正确且已更新。

var signingCert = store.Certificates.OfType<X509Certificate2>().FirstOrDefault(x => x.Thumbprint == _appSettings.AzureAD.CertificateThumbprint);

一年前进行配置时,流程是进入应用服务、TLS/SSL 设置刀片,选择私钥证书 (.pfx),最后选择 + 导入密钥库证书。

从那里选择 Key Vault 和证书,然后更改 Appsettings.Json 以拥有新的指纹。

为什么它可以与旧的(即将到期的)证书和相应的指纹条目一起使用到 appsettings,但无法使用任何新创建的证书和相应的正确指纹条目?

我已经查看了有问题的应用服务的配置,当我理解应该让应用服务看到注册到它的所有证书时,它具有以下设置,对吗?

WEBSITE_LOAD_CERTIFICATES = *

编辑:经过更多测试后,我发现我从 Azure 导出并在我的计算机上导入的任何证书都将成功迭代证书存储并找到我提供有效指纹的任何证书。它不会做的是使用该证书来获取访问令牌。完整的代码如下。

即将到期的证书将获得适当的访问令牌,并通过从数据库中获取适当的数据来运行其余的过程。

我从所有其他证书中得到的例外都暗示了一些关于 base64 编码的信息,但我不太明白这一点。有任何想法吗?

除原始证书外的所有证书均例外:

客户端断言包含无效签名

仅带有原始证书的带有此代码的成功访问令牌:

private async Task<string> GetDatabaseTokenFromCert()
    {
        X509Certificate2 cert;
        var store = new X509Store(StoreLocation.CurrentUser);
        var authContext = new AuthenticationContext(_appSettings.AzureAD.AADInstance + _appSettings.AzureAD.TenantId);

        try
        {
            store.Open(OpenFlags.ReadOnly);
            var signingCert = store.Certificates.OfType<X509Certificate2>().FirstOrDefault(x => x.Thumbprint == _appSettings.AzureAD.CertificateThumbprint);
            
            if (signingCert == null)
            {
                throw new FileNotFoundException("Cannot locate certificate for DB access!", _appSettings.AzureAD.CertificateThumbprint);
            }

            cert = signingCert;

        }
        finally
        {
            store.Close();
        }

        var certCred = new ClientAssertionCertificate(_appSettings.AzureAD.ClientId, cert);

        var result = await Retry(() => authContext.AcquireTokenAsync(_appSettings.SqlConfig.ResourceId, certCred));
        
        return result?.AccessToken;

    }
4

1 回答 1

0

事实证明,您还需要将新证书添加到应用程序注册中。显然,作为没有私钥的 .cer 文件。

因此,如果您收到错误消息:

AADSTS700027:客户端断言包含无效签名。[原因 - 未找到密钥。客户端使用的密钥指纹:'YourNewCert'

转到 Key Vault,将新证书导出为 .cer 文件并将其导入尝试从 AcquireTokenAsync 获取访问令牌的应用服务

在我的情况下,操作顺序是:

  • 逻辑应用程序将匿名调用作为 POST 发送到 Web API
  • Web API 通过 appsetting.json 使用有问题的证书指纹
  • 使用 Web API 的 App Registration 中的指纹查找证书
  • AcquireTokenAsync 获取 Azure 信息和证书并返回访问令牌

这将在原始帖子的这一行中起作用或失败

var result = await Retry(() => authContext.AcquireTokenAsync(_appSettings.SqlConfig.ResourceId, certCred));
于 2021-04-01T18:54:05.563 回答