在 Service Fabric 應用程式中管理已加密的祕密

本指南將逐步引導您完成管理 Service Fabric 應用程式中密碼的步驟。 密碼可以是任何機密資訊,例如儲存體連接字串、密碼或其他不會以純文字處理的值。

在 Service Fabric 應用程式中使用加密的祕密包含三個步驟:

  • 設定加密憑證並將祕密加密。
  • 指定應用程式中已加密的祕密。
  • 從服務程式碼解開已加密的祕密。

設定加密憑證並將祕密加密

設定加密憑證,並使用該憑證來對 Windows 和 Linux 之間不同的祕密進行加密。

指定應用程式中已加密的祕密

上一個步驟說明了如何以憑證對祕密進行加密,並產生要在應用程式中使用的 base-64 編碼字串。 此 base-64 編碼字串可以在服務的 Settings.xml 中指定為已加密的參數,或在服務的 ServiceManifest.xml 中指定為已加密的環境變數

在服務的 Settings.xml 組態檔中指定已加密的參數,並將 IsEncrypted 屬性設為 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

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

您也應在應用程式資訊清單中指定憑證,以將秘密包含在 Service Fabric 應用程式中。 將 SecretsCertificate 元素新增至 ApplicationManifest.xml,並包含所需憑證的指紋。

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

注意

在啟動指定了 SecretsCertificate 的應用程式時,Service Fabric 會尋找相符的憑證,並向用以執行應用程式的身分識別授與憑證私密金鑰的完整權限。 Service Fabric 也會監視憑證的變更,並據以重新套用權限。 為了偵測以一般名稱宣告的憑證所發生的變更,Service Fabric 會定期執行工作來尋找所有相符的憑證,並將其與已快取的指紋清單進行比較。 如果偵測到新的指紋,就表示該主體的憑證已更新。 此工作會每分鐘在叢集的每個節點上執行一次。

雖然 SecretsCertificate 允許以主體為基礎的宣告,但請注意,已加密的設定會繫結至用來加密用戶端設定的金鑰組。 您必須確定原始加密憑證 (或同等憑證) 符合以主體為基礎的宣告,並且該憑證 (包括其對應的私密金鑰) 已安裝在可裝載應用程式的每個叢集節點上。 如果憑證仍在有效時間內、符合以主體為基礎的宣告,並且透過與原始加密憑證相同的金鑰組所建置,便屬於同等憑證。

將應用程式密碼插入應用程式執行個體內

在理想情況下,部署至不同的環境應儘可能自動化。 這可以藉由在建置環境中執行密碼加密,並在建立應用程式執行個體時提供加密的密碼做為參數來實現。

在 Settings.xml 中使用可覆寫參數

Settings.xml 組態檔允許可以在應用程式建立時提供的可覆寫參數。 使用 MustOverride 屬性而非提供參數的值︰

<?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 中服務的覆寫參數︰

<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>

現在可以在建立應用程式執行個體時,將值指定為「應用程式參數」 。 可以使用 PowerShell 編寫指令碼 (或以 C# 撰寫) 來建立應用程式執行個體,使其在建置流程中很容易整合。

若使用 PowerShell,則參數會提供給 New-ServiceFabricApplication 命令當做 雜湊表

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

若使用 C#,則應用程式參數在 ApplicationDescription 中會指定為 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);

從服務程式碼解開已加密的祕密

用於存取參數環境變數的 API 可輕易地對已加密的值進行解密。 由於加密的字串包含用於加密的憑證相關資訊,因此您不需要手動指定憑證。 只需要在執行服務的節點上安裝憑證。

// 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");

下一步