2

外部 Web サービスを利用する Web アプリケーションを実行しています。この外部 Web サービスでは、要求ごとに署名する必要があります。WebServicesClientProtocolそのため、最初に外部 Web サービスを使用してクラスと .NET 2.0 を使用し、次にReference.csファイルを手動で編集して、拡張クラスを からSystem.Web.Services.Protocols.SoapHttpClientProtocolに変更しますMicrosoft.Web.Services2.WebServicesClientProtocol。次に、Page_Loadメソッドには次のコードがあります。

try
{
    // Create the ws endpoint
    var uriServiceAddress = new Uri("urn:something-wse:something_NNNN");
    var uribuilderViaRouter = new UriBuilder("http://xx.xxx.xx/SrvXXX_NNNN/Test.asmx");
    var endpointReference = new EndpointReference(uriServiceAddress, uribuilderViaRouter.Uri);

    // Create the ws client
    var client = (WebServicesClientProtocol) new Test.Something();
    client.Destination = endpointReference;

    // Read the certificate from MyStore on LocalMachine
    X509CertificateStore localStore = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
    X509SecurityToken securityToken = null;
    if (!localStore.OpenRead()) throw new Exception("Unable to open localstore for read");
    X509CertificateCollection certificateCollection = localStore.FindCertificateBySubjectString("email@subject.test");
    if (certificateCollection.Count == 0) throw new Exception("Unable to obtain security token.");
    securityToken = new X509SecurityToken(certificateCollection[0]);
    localStore.Close();

    // Attach the security toekn to the client request
    client.RequestSoapContext.Security.Tokens.Add(securityToken);
    client.RequestSoapContext.Security.Elements.Add(new MessageSignature(securityToken));

    // Set the timeouts
    client.RequestSoapContext.Security.Timestamp.TtlInSeconds = 2 * 60;
    client.Timeout = 60 * 10 * 1000;    // 10 mínútur ættu að duga í flest.

    // Call the test function
    DataSet set = ((Test.Something)client).searchMethod("Parameter 1", "Parameter 2");
    Label1.Text = User.Identity.Name+ " worked! " + set.Tables.Count + " tables!";
}
catch (Exception exc)
{
    Label1.Text = User.Identity.Name + " exception: " + exc.ToString();
}

Visual Studio Development Server を使用してこれを実行すると問題なく動作しますが、IIS に変更すると動作が停止し、醜いCryptography_CSP_NoPrivateKey例外が発生します。

1) MMC を使用して証明書を LocalMachine/MyStore に適切に読み込んでから、WSE 2.0 SP3 を使用して秘密鍵のアクセス許可を変更し、全員がアクセスできるようにします。これはここから見ることができます:

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

2)アプリケーションのデバッグ時に Visual Studio Development Server が使用されるように、プロパティも設定します。

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

3)次に、それを実行すると、素晴らしい結果が得られます。

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

4)ただし、IIS を使用するようにプロパティを変更すると (VS に仮想ディレクトリを作成させると)、次のようになります。

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

5)また、IIS の認証方法を変更して、ログオンできるようにします (実際には理由はありません)。

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

6) Windows へのログオンを求められます。

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

7)そして、私のページが実行され、エラーが発生します:

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

あなたがこれで私を助けることができれば、私はきっとそれを感謝します. 私はすでに何時間も費やしてきましたが、皆さんが見ることができる根本的なエラーを犯している場合、これ以上時間を費やしたくありません. ところで:UACをオフにして、Windows Server 2008でVisual Studio 2008を使用して開発しています:-)

皆さんからの連絡を本当に楽しみにしています。ありがとう。

4

1 に答える 1

2

:-)

いくつかの手順でこの問題を解決しました。

1)のユーザーを自分のユーザー名に変更しましたDefault Application Pool...

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

...そしてそれはうまくいきました。アプリケーション プールのユーザーを に戻しましたがNETWORK SERVICE、再び機能しませんでした。これにより、問題はNETWORK SERVICEユーザーに関係していることがわかりました。そこで、このユーザーの権限に問題がある可能性があるものを探すことに戻りました。

2) Web をブラウジングして読んでいると、Tim Jacobs のブログ投稿App-V 4.5 Certificate Galorehttp://timjacobs.blogspot.com/2008/11/app-v-45-certificate-galore.htmlで見つかりました。ええと、最後に彼がディスク上の秘密鍵の保管場所について話すまで、新しいことは何もありませんでした。そこで、FindPrivateKey.exeツールを実行しました...

C:\MyTools>FindPrivateKey.exe My LocalMachine -t "8c 1a e6 1b 6d f2 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
秘密キー ディレクトリ:
C:\Users\alfred\AppData\Roaming\Microsoft \Crypto\RSA\S-1-5-21-3612370315-2559787 071-3412320394-1135
秘密鍵ファイル名:
b3765d4123902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acb123b8b3bf

...これは、秘密鍵の場所がC:\Users\alfred\...ディレクトリにあり、NETWORK SERVICEユーザーがおそらくこのディレクトリにアクセスできないことを示しています!!!

3)したがって、MMC を使用して から証明書と秘密鍵をエクスポートし、Local Computer/Personal/Certificatesそれを にインポートするというティムの提案に従いましたLocal Computer/Trusted Root Certificate Authorities/Certificates。エクスポートした後、FindPrivateKey.exeは次のように報告しました。

C:\MyTools>FindPrivateKey.exe My LocalMachine -t "8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
FindPrivateKey は次の理由で失敗しました: キー '8c 1a e6 1b の証明書がありません7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58' ストアで見つかりました。

...これは、エクスポートが機能したことを示しています。インポートしてコピーして貼り付けた後、Local Computer/Personal/Certificates...

C:\MyTools>FindPrivateKey.exe My LocalMachine -t "8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
秘密鍵ディレクトリ:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
秘密鍵ファイル名:
b3765d4d5a902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acbaccb8b3bf

...そして今、秘密鍵は公開された場所、C:\ProgramData\...ディレクトリにあります。次に、以前に行ったように、 X509 証明書ツールを使用して、NETWORK SERVICEユーザーの秘密キーのアクセス許可をフル アクセスに変更しました。

そして今、それは動作します!!!

ティムのブログ投稿に感謝してもしきれません。ありがとうございました。

于 2009-03-25T16:46:13.747 に答える