使用 ARM 将 PFX 证书添加到 Azure WebApp(不适用于 ssl)

Add PFX Certificate to Azure WebApp using ARM (not for ssl)

使用 Azure 资源管理器支持的 Rest Management APIS,以下代码将证书从 keyvault 添加到 ARM。

var secret = keyvaultClient.GetSecretAsync(vaultUri, options.CertificateName).GetAwaiter().GetResult();

var certUploaded = client.Certificates.CreateOrUpdateCertificateWithHttpMessagesAsync(
    options.ResourceGroupName, options.CertificateName,
    new Certificate {
        PfxBlob = secret.Value,
        Location = app.Body.Location
    }).GetAwaiter().GetResult();

var appSettings = client.Sites.ListSiteAppSettingsWithHttpMessagesAsync(options.ResourceGroupName, options.WebAppName).GetAwaiter().GetResult();
var existing = (appSettings.Body.Properties["WEBSITE_LOAD_CERTIFICATES"] ?? "").Split(',').ToList();
if (!existing.Contains(certUploaded.Body.Thumbprint))
    existing.Add(certUploaded.Body.Thumbprint);

appSettings.Body.Properties["WEBSITE_LOAD_CERTIFICATES"] = string.Join(",",existing);
appSettings.Body.Properties[$"CN_{options.CertificateName}"] = certUploaded.Body.Thumbprint;

var result = client.Sites.UpdateSiteAppSettingsWithHttpMessagesAsync(options.ResourceGroupName, options.WebAppName, appSettings.Body).GetAwaiter().GetResult();

问题是在 webapp 中加载它时

        X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        certStore.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certCollection = certStore.Certificates.Find(
                                   X509FindType.FindByThumbprint,
                             // Replace below with your cert's thumbprint
                             "0CE28C6246317AEB00B88C88934700865C71CBE0",
                                   false);

        Trace.TraceError($"{certCollection.Count}");
        Console.WriteLine($"{certCollection.Count}");
        // Get the first cert with the thumbprint
        if (certCollection.Count > 0)
        {
            X509Certificate2 cert = certCollection[0];
            // Use certificate
            Console.WriteLine(cert.FriendlyName);
        }
        certStore.Close();

未加载。

如果我改为使用门户上传它,一切都会按预期进行。

我也注意到在 portal 中上传的证书在 ARM 中不存在,只有在 post 开头的代码添加的证书存在。:

那么我们需要做些什么才能让webapp可以使用不需要手动上传到portal的证书呢?

问题是应该将证书添加到托管 Web 应用程序的服务器场的资源组,而不是 Web 应用程序的资源组。

更改代码以部署到正确的资源组解决了所有问题。

作为参考,我的更新代码在这里:

var vaultUri = $"https://{options.VaultName}.vault.azure.net";
var keyvaultClient = new KeyVaultClient((_, b, c) => Task.FromResult(options.VaultAccessToken));

using (var client = new WebSiteManagementClient(
    new TokenCredentials(cred.AccessToken)))
{
    client.SubscriptionId = cred.SubscriptionId;

    var app = client.Sites.GetSite(options.ResourceGroupName, options.WebAppName);
    var serverFarmRG = Regex.Match(app.ServerFarmId, "resourceGroups/(.*?)/").Groups[1];

    var secret = keyvaultClient.GetSecretAsync(vaultUri, options.CertificateName).GetAwaiter().GetResult();

    var certUploaded = client.Certificates.CreateOrUpdateCertificate(
        serverFarmRG.Value, options.CertificateName,
        new Certificate
        {
            PfxBlob = secret.Value,
            Location = app.Location
        });

    var appSettings = client.Sites.ListSiteAppSettings(options.ResourceGroupName, options.WebAppName);
    appSettings.Properties["WEBSITE_LOAD_CERTIFICATES"] = string.Join(",", client.Certificates.GetCertificates(serverFarmRG.Value).Value.Select(k => k.Thumbprint));
    appSettings.Properties[$"CN_{options.CertificateName}"] = certUploaded.Thumbprint;

    var result = client.Sites.UpdateSiteAppSettings(options.ResourceGroupName, options.WebAppName, appSettings);