Я делаю веб-приложение, которое использует внешний веб-сервис. Этот внешний веб-сервис требует от меня подписи каждого из моих запросов. Поэтому я использую класс WebServicesClientProtocol
и .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) Я уже прочитал сертификат должным образом в LocalMachine / MyStore с помощью MMC, а затем я изменил разрешения на закрытый ключ с помощью WSE 2.0 SP3, чтобы у всех был полный доступ к нему. Вы можете увидеть это здесь:
альтернативный текст http://www1.ruedenet.is/files/CertError1.png
2) Я также установил свойство так, чтобы при отладке приложения использовался сервер разработки Visual Studio:
альтернативный текст 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
Если бы вы могли помочь мне с этим, я, безусловно, был бы признателен. Я уже потратил на это часы и не хочу тратить больше времени, если я делаю фундаментальную ошибку, которую вы, ребята, видите. Кстати, я разрабатываю с использованием Visual Studio 2008 на Windows Server 2008 с отключенным UAC: -)
Очень жду ответа от вас, ребята. Спасибо.