我正在使用带有安全性令牌的WebServicesClientProtocol类,并使用以下代码查找要使用的安全性令牌:
private static X509SecurityToken GetSecurityCertificate(string subject)
{
X509CertificateStore localStore = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
X509SecurityToken securityToken = null;
if (localStore.OpenRead())
{
X509CertificateCollection certificateCollection = localStore.FindCertificateBySubjectString(subject);
if (certificateCollection.Count == 0) throw new Exception("Skilríki finnst ekki í skilríkjageymslu");
securityToken = new X509SecurityToken((X509Certificate)certificateCollection[0]);
}
localStore.Close();
return securityToken;
}
时不时(但并非总是如此,我一直无法弄明白)究竟是什么时候我得到以下异常:
答案 0 :(得分:1)
我今天遇到了这个问题,我相信我已经弄明白是什么导致了这个问题。静态方法需要同步。
如果您在异常时将鼠标悬停在localStore变量上并检查Certificates属性,您很可能会看到“InvalidOperationException”的影响 - 要访问证书,您必须使用Open()或OpenRead()。 ......等等等等。“
正在发生的事情是某个线程在另一个线程完成访问之前关闭了商店。
我首先创建了一个用于锁定商店的静态类成员来解决这个问题:
private static object m_storeLock = new object();
当您访问商店时,您必须执行以下操作:
public static X509Certificate FindCertificate(string certName) {
X509CertificateStore store = null;
X509Certificate cert = null;
lock (m_storeLock) {
try {
store = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
store.OpenRead();
X509CertificateCollection col =
(X509CertificateCollection)store.FindCertificateBySubjectString(certName);
if (col.Count > 0) {
cert = col[0];
}
}
catch {
}
finally {
if (store != null) {
store.Close();
}
}
}
if (cert == null) {
throw new ArgumentException("Certificate not found!");
}
return cert;
}
为了更安全,你应该锁定局部变量“cert”,但这不是生产代码人......:D~