1

セキュリティ トークンで 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;
}

ときどき(ただし、常にではなく、いつ正確に把握することができませんでした)、次の例外が発生します。

代替テキスト http://www1.ruedenet.is/files/exception.png

4

1 に答える 1

1

今日、この問題が発生しました。何が原因であるかを把握したと思います。静的メソッドには同期が必要です。

例外時に localStore 変数にカーソルを合わせて Certificates プロパティを調べると、「InvalidOperationException - To access the certificates you must use Open() or OpenRead()... blah何とか何とか」。

何が起こっているのかというと、別のスレッドがストアへのアクセスを完了する前に、一部のスレッドがストアを閉じているということです。

最初にストアをロックするための静的クラス メンバーを作成して、問題を解決しました。

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~

于 2009-08-18T21:33:43.340 に答える