C# 为本地群集安装证书
我有一些代码要通过Azure密钥库进行身份验证,以便检索一些机密。我正在使用客户端id和证书进行身份验证,而不是使用客户端id和密码。此代码在普通控制台应用程序中非常有效:C# 为本地群集安装证书,c#,azure-service-fabric,C#,Azure Service Fabric,我有一些代码要通过Azure密钥库进行身份验证,以便检索一些机密。我正在使用客户端id和证书进行身份验证,而不是使用客户端id和密码。此代码在普通控制台应用程序中非常有效: var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); try { store.Open(OpenFlags.ReadOnly); var matchingCertificates = store.Certificates.Fi
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();
}
一旦我尝试在有状态服务应用程序中使用此代码,它就无法再找到证书
如何安装证书以使其可供本地群集使用?服务结构应用程序在网络服务帐户下运行,因此您需要确保该帐户具有证书的访问/权限 编辑: 对于在本地机箱上运行的群集,您可以使用certmgr.msc或相关mmc管理单元查找证书,然后右键单击>所有任务>管理私钥,然后授予网络服务读取权限 对于Azure中的远程群集,您可以在规模集的虚拟机上使用一个可运行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
这不能按原样工作的原因是服务结构在网络服务帐户下运行,没有配置,网络服务帐户无权访问证书 至少对我们来说,当使用Microsoft.Azure.KeyVault提供的
KeyVault客户端
使用证书连接到密钥库时,此场景导致“密钥集不存在”异常
解决方案是将证书包含在ApplicationManifest.xml
中,它指示服务结构向网络服务帐户授予对证书的访问权
<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>
所以只要本地计算机有权访问,它仍然可以看到安装在本地计算机上的所有证书?是的,没错。通过在ApplicationManifest.xml中定义用户、组和访问策略,您可以让Service Fabric自动授予对特定证书的访问权,而不是手动授予访问权。有关设置的更多信息,请参阅此文档:能否提供有关如何在Service Fabric中授予证书访问权限的更多详细信息?该文档讨论了SSL端点证书,但这不是我的用例。我正在使用证书私钥对KeyVault资源进行身份验证。我已经在缩放集的VM定义上使用自定义脚本扩展完成了此操作,该扩展将运行脚本来设置这些权限。然而,@VaclavTurecek可能能够使用RunAs提供更优雅的解决方案。请注意,在德国,“网络服务”是“Netzwerkdienst”-即使您将Windows语言切换为英语。这就是为什么最好使用新对象System.Security.Principal.SecurityIdentifier(“S-1-5-20”)
等。这是更好的答案,更简洁、更容易。完美无瑕!此解决方案似乎不支持证书滚动。Azure Service Fabric不会使用类似“netsh http ssl remove..”的内容注销端口,并且使用新指纹升级应用程序失败…一个让我感到困惑的澄清:确保将证书安装到LOCALMACHINE(而不是CurrentUser)位置。如果您只是dbl单击了*.pfx/cer文件,那么它将转到CurrentUser。这将在codepackage部署步骤中为您提供结构\u E\u证书\u NOTFOUND错误。@Satthru如果您通过VM Scale Set资源添加证书(请参阅以获取信息),则该证书将自动安装在本地计算机存储中。