为本地群集安装证书

Dis*_*ile 10 c# azure-service-fabric

我有一些代码可以使用Azure Key Vault进行身份验证,以便检索一些秘密.我使用客户端ID和证书而不是客户端ID和密码进行身份验证.此代码在普通的控制台应用程序中运行良好:

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
    store.Open(OpenFlags.ReadOnly);

    var matchingCertificates = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
    if (matchingCertificates.Count != 1)
    {
        return null;
    }

    return matchingCertificates[0];
}
finally
{
    if (store != null) store.Close();
}
Run Code Online (Sandbox Code Playgroud)

只要我在有状态服务应用程序中尝试使用此代码,它就再也无法找到证书.

如何安装证书以使其可用于我的本地群集?

Mat*_*att 9

这不起作用的原因是因为Service Fabric在NETWORK SERVICE帐户下运行,该帐户在没有配置的情况下无法访问证书.

至少对于我们来说,当使用KeyVaultClientMicrosoft.Azure.KeyVault提供的使用证书连接到Key Vault 时,此方案导致"Keyset不存在"异常.

解决方案是在您的证书中包含证书,该证书ApplicationManifest.xml指示Service Fabric授予NETWORK SERVICE帐户访问证书的权限;

<ApplicationManifest>
   <!-- snip -->
   <Principals>
      <Users>
         <User Name="NetworkServiceAccount" AccountType="NetworkService" />
      </Users>
   </Principals>
   <Policies>
      <SecurityAccessPolicies>
         <SecurityAccessPolicy ResourceRef="KeyVaultCert" PrincipalRef="NetworkServiceAccount" GrantRights="Full" ResourceType="Certificate" />
      </SecurityAccessPolicies>
   </Policies>
   <Certificates>
      <SecretsCertificate X509FindValue="1ABCD86B815F37123459A34C1BA9EDEBABCEDF1" Name="KeyVaultCert" />
   </Certificates>
</ApplicationManifest>
Run Code Online (Sandbox Code Playgroud)

...其中两个NetworkServiceAccountKeyVaultCert是所使用的任意名称<SecurityAccessPolicy />元素来引用用户和证书.

另见https://azure.microsoft.com/en-us/documentation/articles/service-fabric-application-runas-security/#a-complete-application-manifest-example


cha*_*isk 6

Service Fabric 应用程序在 NETWORK SERVICE 帐户下运行,因此您需要确保该帐户具有对证书的访问/权限。

编辑:

对于在本地机器上运行的集群,您可以使用 certmgr.msc 或相关的 mmc 管理单元查找证书,然后右键单击 > 所有任务 > 管理私钥,然后向 NETWORK SERVICE 授予读取权限。

对于 Azure 中的远程群集,可以在规模集的 VM 上使用自定义脚本扩展来执行此操作,该扩展将运行 PowerShell 脚本来设置所需的权限。例如,它可以执行以下操作:

$certificate = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Thumbprint -eq $certificateThumbprint}

# Get file path
$certificateFilePath = "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\" + $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName

# Take ownership of the file so that permissions can be set
takeown /F $certificateFilePath

# Give the NETWORK SERVICE read permissions
$acl = (Get-Item $certificateFilePath).GetAccessControl('Access')
$rule = new-object System.Security.AccessControl.FileSystemAccessRule "NETWORK SERVICE","Read","Allow"
$acl.SetAccessRule($rule)
Set-Acl -Path $certificateFilePath -AclObject $acl
Run Code Online (Sandbox Code Playgroud)