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

下一步