管理 Service Fabric 应用程序中的已加密机密Manage encrypted secrets in Service Fabric applications

本指南逐步讲解管理 Service Fabric 应用程序中的机密的步骤。This guide walks you through the steps of managing secrets in a Service Fabric application. 机密可以是任何敏感信息,例如存储连接字符串、密码或其他不应以明文形式处理的值。Secrets can be any sensitive information, such as storage connection strings, passwords, or other values that should not be handled in plain text.

在 Service Fabric 应用程序中使用加密的机密涉及三个步骤:Using encrypted secrets in a Service Fabric application involves three steps:

  • 设置加密证书并对机密进行加密。Set up an encryption certificate and encrypt secrets.
  • 在应用程序中指定加密的机密。Specify encrypted secrets in an application.
  • 对服务代码中的已加密机密进行解密。Decrypt encrypted secrets from service code.

设置加密证书并对机密进行加密Set up an encryption certificate and encrypt secrets

设置加密证书和使用它来加密机密在 Windows 与 Linux 之间所有不同。Setting up an encryption certificate and using it to encrypt secrets varies between Windows and Linux.

在应用程序中指定加密的机密Specify encrypted secrets in an application

上一步骤介绍了如何使用证书来加密机密,并生成要在应用程序中使用的 base-64 编码的字符串。The previous step describes how to encrypt a secret with a certificate and produce a base-64 encoded string for use in an application. 可以在服务的 Settings.xml 中将此 base-64 编码的字符串指定为加密的参数,也可以在服务的 ServiceManifest.xml 中将其指定为加密的环境变量This base-64 encoded string can be specified as an encrypted parameter in a service's Settings.xml or as an encrypted environment variable in a service's ServiceManifest.xml.

通过在服务的 Settings.xml 配置文件中将 IsEncrypted 属性设置为 true 来指定加密的参数Specify an encrypted parameter in your service's Settings.xml configuration file with the IsEncrypted attribute set to true:

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Section Name="MySettings">
    <Parameter Name="MySecret" IsEncrypted="true" Value="I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=" />
  </Section>
</Settings>

通过在服务的 ServiceManifest.xml 文件中将 Type 属性设置为 Encrypted 来指定加密的环境变量Specify an encrypted environment variable in your service's ServiceManifest.xml file with the Type attribute set to Encrypted:

<CodePackage Name="Code" Version="1.0.0">
  <EnvironmentVariables>
    <EnvironmentVariable Name="MyEnvVariable" Type="Encrypted" Value="I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=" />
  </EnvironmentVariables>
</CodePackage>

机密也应包括在 Service Fabric 应用程序中,只需在应用程序清单中指定证书即可。 SecretsCertificate 元素添加到 ApplicationManifest.xml,并包括所需证书的指纹。Add a SecretsCertificate element to ApplicationManifest.xml and include the desired certificate's thumbprint.

<ApplicationManifest … >
  ...
  <Certificates>
    <SecretsCertificate Name="MyCert" X509FindType="FindByThumbprint" X509FindValue="[YourCertThumbrint]"/>
  </Certificates>
</ApplicationManifest>

将应用程序机密注入应用程序实例Inject application secrets into application instances

理想情况下,部署到不同环境的过程应尽可能自动化。Ideally, deployment to different environments should be as automated as possible. 这可以通过在生成环境中执行机密加密,并在创建应用程序实例时提供加密机密作为参数来实现。This can be accomplished by performing secret encryption in a build environment and providing the encrypted secrets as parameters when creating application instances.

在 Settings.xml 中使用可重写参数Use overridable parameters in Settings.xml

Settings.xml 配置文件允许使用可在创建应用程序时提供的可重写参数。The Settings.xml configuration file allows overridable parameters that can be provided at application creation time. 使用 MustOverride 属性而不要提供参数值:Use the MustOverride attribute instead of providing a value for a parameter:

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Section Name="MySettings">
    <Parameter Name="MySecret" IsEncrypted="true" Value="" MustOverride="true" />
  </Section>
</Settings>

若要重写 Settings.xml 中的值,可在 ApplicationManifest.xml 中声明服务的 override 参数:To override values in Settings.xml, declare an override parameter for the service in ApplicationManifest.xml:

<ApplicationManifest ... >
  <Parameters>
    <Parameter Name="MySecret" DefaultValue="" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Stateful1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides>
      <ConfigOverride Name="Config">
        <Settings>
          <Section Name="MySettings">
            <Parameter Name="MySecret" Value="[MySecret]" IsEncrypted="true" />
          </Section>
        </Settings>
      </ConfigOverride>
    </ConfigOverrides>
  </ServiceManifestImport>

现在,可以在创建应用程序实例时将值指定为应用程序参数Now the value can be specified as an application parameter when creating an instance of the application. 可以使用 PowerShell 或 C# 编写用于创建应用程序实例的脚本,方便在生成过程中轻松集成。Creating an application instance can be scripted using PowerShell, or written in C#, for easy integration in a build process.

使用 PowerShell 时,参数将以哈希表的形式提供给 New-ServiceFabricApplicationUsing PowerShell, the parameter is supplied to the New-ServiceFabricApplication command as a hash table:

New-ServiceFabricApplication -ApplicationName fabric:/MyApp -ApplicationTypeName MyAppType -ApplicationTypeVersion 1.0.0 -ApplicationParameter @{"MySecret" = "I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM="}

使用 C# 时,应用程序参数将以 NameValueCollection 的形式在 ApplicationDescription 中指定:Using C#, application parameters are specified in an ApplicationDescription as a NameValueCollection:

FabricClient fabricClient = new FabricClient();

NameValueCollection applicationParameters = new NameValueCollection();
applicationParameters["MySecret"] = "I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=";

ApplicationDescription applicationDescription = new ApplicationDescription(
    applicationName: new Uri("fabric:/MyApp"),
    applicationTypeName: "MyAppType",
    applicationTypeVersion: "1.0.0",
    applicationParameters: applicationParameters)
);

await fabricClient.ApplicationManager.CreateApplicationAsync(applicationDescription);

对服务代码中的已加密机密进行解密Decrypt encrypted secrets from service code

用于访问参数环境变量的 API 使已加密的值可以轻松解密。The APIs for accessing parameters and environment variables allow for easy decryption of encrypted values. 由于加密的字符串包含用于加密的证书的相关信息,因此不需要手动指定证书。Since the encrypted string contains information about the certificate used for encryption, you do not need to manually specify the certificate. 只需在运行服务的节点上安装该证书。The certificate just needs to be installed on the node that the service is running on.

// Access decrypted parameters from Settings.xml
ConfigurationPackage configPackage = FabricRuntime.GetActivationContext().GetConfigurationPackageObject("Config");
bool MySecretIsEncrypted = configPackage.Settings.Sections["MySettings"].Parameters["MySecret"].IsEncrypted;
if (MySecretIsEncrypted)
{
    SecureString MySecretDecryptedValue = configPackage.Settings.Sections["MySettings"].Parameters["MySecret"].DecryptValue();
}

// Access decrypted environment variables from ServiceManifest.xml
// Note: you do not have to call any explicit API to decrypt the environment variable.
string MyEnvVariable = Environment.GetEnvironmentVariable("MyEnvVariable");

后续步骤Next steps