在 Azure 应用服务中通过代码使用 TLS/SSL 证书

在应用程序代码中,可以访问已添加到应用服务的公用证书或私用证书。 应用代码可以充当客户端并可访问需要证书身份验证的外部服务,否则可能需要执行加密任务。 本操作方法指南介绍如何在应用程序代码中使用公共或专用证书。

这种在代码中使用证书的方法利用了应用服务中的 TLS 功能,要求应用属于“基本”层或更高层。 如果应用位于“免费”或“共享”层,则你可以在应用存储库中包含证书文件

让应用服务管理 TLS/SSL 证书时,可以分开维护证书和应用程序代码,并保护敏感数据。

先决条件

按照本操作方法指南操作:

查找指纹

Azure 门户的左侧菜单中,选择“应用程序服务”>“<app-name>”。

在应用的左侧导航栏中,选择“证书”,然后选择“自使用自己的证书(.pfx)”或“公钥证书(.cer)”。

找到要使用的证书并复制指纹。

Copy the certificate thumbprint

使证书可供访问

若要在应用代码中访问某个证书,请在 Azure CLI 中运行以下命令,将其指纹添加到 WEBSITE_LOAD_CERTIFICATES 应用设置:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_LOAD_CERTIFICATES=<comma-separated-certificate-thumbprints>

若要使所有证书可供访问,请将值设置为 *

注意

WEBSITE_LOAD_CERTIFICATES 设置为 * 时,应用程序代码可以访问所有以前添加的证书。 如果稍后将证书添加到应用,请重启该应用,使新证书可供应用访问。 有关详细信息,请参阅更新(续订)证书时

在 Windows 应用中加载证书

Current User\My 中的 Windows 证书存储中的 Windows 托管应用可以通过 WEBSITE_LOAD_CERTIFICATES 应用设置访问指定的证书。

在 C# 代码中,可按证书指纹访问证书。 以下代码加载具有指纹 E661583E8FABEF4C0BEF694CBC41C28FB81CD870 的证书。

using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;

string certThumbprint = "E661583E8FABEF4C0BEF694CBC41C28FB81CD870";
bool validOnly = false;

using (X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
  certStore.Open(OpenFlags.ReadOnly);

  X509Certificate2Collection certCollection = certStore.Certificates.Find(
                              X509FindType.FindByThumbprint,
                              // Replace below with your certificate's thumbprint
                              certThumbprint,
                              validOnly);
  // Get the first cert with the thumbprint
  X509Certificate2 cert = certCollection.OfType<X509Certificate2>().FirstOrDefault();

  if (cert is null)
      throw new Exception($"Certificate with thumbprint {certThumbprint} was not found");

  // Use certificate
  Console.WriteLine(cert.FriendlyName);
  
  // Consider to call Dispose() on the certificate after it's being used, available in .NET 4.6 and later
}

在 Java 代码中,可以使用“使用者公用名”字段从“Windows-MY”存储访问证书。 以下代码演示如何加载私钥证书:

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.PrivateKey;

...
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null); 
Certificate cert = ks.getCertificate("<subject-cn>");
PrivateKey privKey = (PrivateKey) ks.getKey("<subject-cn>", ("<password>").toCharArray());

// Use the certificate and key
...

对于不支持或不充分支持 Windows 证书存储的语言,请参阅从文件加载证书

从文件加载证书

例如,如需加载手动上传的证书文件,则最好是使用 FTPS 而不是 Git 上传证书。 应将专用证书之类的敏感信息置于源代码管理之外。

注意

即使从文件加载证书,Windows 上的 ASP.NET 和 ASP.NET Core 也必须访问证书存储。 若要在 Windows .NET 应用中加载证书文件,请在 Azure CLI 中使用以下命令加载当前用户配置文件:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_LOAD_USER_PROFILE=1

这种在代码中使用证书的方法利用了应用服务中的 TLS 功能,要求应用属于“基本”层或更高层。

以下 C# 示例从应用中的相对路径加载公用证书:

using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;

...
var bytes = File.ReadAllBytes("~/<relative-path-to-cert-file>");
var cert = new X509Certificate2(bytes);

// Use the loaded certificate

若要了解如何从 Node.js、PHP、Python 或 Java 文件加载 TLS/SSL 证书,请参阅适用于相应语言或 Web 平台的文档。

在 Linux/Windows 容器中加载证书

WEBSITE_LOAD_CERTIFICATES 应用设置使指定的证书可作为文件供 Windows 或 Linux 自定义容器(包括内置 Linux 容器)访问。 这些文件位于以下目录中:

容器平台 公用证书 私有证书
Windows 容器 C:\appservice\certificates\public C:\appservice\certificates\private
Linux 容器 /var/ssl/certs /var/ssl/private

证书文件名是证书指纹。

注意

应用服务将证书路径作为以下环境变量 WEBSITE_PRIVATE_CERTS_PATHWEBSITE_INTERMEDIATE_CERTS_PATHWEBSITE_PUBLIC_CERTS_PATHWEBSITE_ROOT_CERTS_PATH 注入到 Windows 容器中。 最好使用环境变量引用证书路径,而不是对证书路径进行硬编码,以防将来证书路径发生更改。

此外,Windows Server Core 容器自动将证书加载到 LocalMachine\My 中的证书存储中。 若要加载证书,请遵循与在 Windows 应用中加载证书相同的模式。 对于基于 Windows Nano 的容器,请使用这些文件路径直接从文件加载证书

以下 C# 代码演示了如何在 Linux 应用中加载公共证书。

using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;

...
var bytes = File.ReadAllBytes("/var/ssl/certs/<thumbprint>.der");
var cert = new X509Certificate2(bytes);

// Use the loaded certificate

以下 C# 代码演示了如何在 Linux 应用中加载专用证书。

using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
...
var bytes = File.ReadAllBytes("/var/ssl/private/<thumbprint>.p12");
var cert = new X509Certificate2(bytes);

// Use the loaded certificate

若要了解如何从 Node.js、PHP、Python 或 Java 文件加载 TLS/SSL 证书,请参阅适用于相应语言或 Web 平台的文档。

更新(续订)证书时

续订证书并将其添加到应用时,它会获得一个新的指纹,该指纹也需要是可供访问的。 工作原理取决于证书类型。

如果手动上传公共专用证书:

  • 如果在 WEBSITE_LOAD_CERTIFICATES 中明确列出指纹,请将新指纹添加到应用设置中。
  • 如果 WEBSITE_LOAD_CERTIFICATES 设置为 *,请重启应用以使新证书可供访问。

如果续订 Key Vault 中的证书(例如使用应用服务证书来这样做),则在将应用与续订的证书同步时,来自 Key Vault 的每日同步会自动进行必要的更新。

  • 如果 WEBSITE_LOAD_CERTIFICATES 包含已续订证书的旧指纹,则每日同步会自动将旧指纹更新为新指纹。
  • 如果 WEBSITE_LOAD_CERTIFICATES 设置为 *,则每日同步会自动使新证书可供访问。

更多资源