У меня есть приложение, развернутое в IIS, которое должно вызвать службу SOAP.Он использует WCF из .NET Framework.Эта служба SOAP требует, чтобы сделанные запросы были аутентифицированы с помощью сертификата на стороне клиента, который выдается во время выполнения.Администратор приложения может обновить использованный сертификат в бэк-офисе.Цель состоит в том, чтобы автономия и управление жизненным циклом сертификата были независимыми от IIS или базовой системы, поэтому использование хранилища сертификатов компьютера не является вариантом.Вот исходный код:
var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
var client = new ServiceReference1.myClient(binding, new EndpointAddress(serviceUrl));
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var certificate = new X509Certificate2(certificateBinary, certificatePassword);
client.ClientCredentials.ClientCertificate.Certificate = certificate;
//use the client
var result = client.myMethod(new ServiceReference1.MethodRequest());
certificateBinary
является результатом загрузки файла PFX, содержащего полную цепочку сертификатов (клиентский сертификат, промежуточный и корневой CA) и certificatePassword
пароль, используемый для создания этого файла,Но запрос отклонен сервером.При взгляде на Wireshark кажется, что отправляется только клиентский сертификат.Это отличается от того, что происходит, если мы устанавливаем PFX в хранилище компьютеров, которое работает нормально.
Поэтому следующим шагом, который я попытался, была установка сертификатов во время выполнения.Сначала загрузите их:
X509Certificate2Collection collection = new X509Certificate2Collection();
try {
collection.Import(ssCertificateFile, ssPassword, X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet);
}
Затем определите, какие это сертификаты, и, наконец, установите их в текущем хранилище пользователей:
private static void InstallCertificates(X509Certificate2Collection clientCerts, X509Certificate2Collection intermediateCAs, X509Certificate2Collection RootCAs) {
using (X509Store personalStore = new X509Store(StoreName.My, StoreLocation.CurrentUser)) {
personalStore.Open(OpenFlags.ReadWrite);
personalStore.AddRange(clientCerts);
}
using (X509Store intermediateStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) {
intermediateStore.Open(OpenFlags.ReadWrite);
intermediateStore.AddRange(intermediateCAs);
}
using (X509Store trustedCAsStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser)) {
trustedCAsStore.Open(OpenFlags.ReadWrite);
trustedCAsStore.AddRange(rootCAs);
}
}
Сбой при установке корневых ЦС в доверенный кореньцентры сертификации (StoreName.Root
) с:
System.Security.Cryptography.CryptographicException: The request is not supported.
at System.Security.Cryptography.X509Certificates.X509Store.Add(X509Certificate2 certificate)
at System.Security.Cryptography.X509Certificates.X509Store.AddRange(X509Certificate2Collection certificates)
at OutSystems.NssCertificationExtremeXP.CssCertificationExtremeXP.InstallCertificates(CertificatesClassifier certificates)
, поэтому устанавливаются только сертификат клиента и промежуточные центры сертификации, и, по-видимому, во время выполнения этого недостаточно.
Но если я возьму точноетот же самый код и запустить его в отдельном проекте C #, при установке корневых CA появляется диалоговое окно подтверждения , и если я нажимаю OK, сертификат устанавливается.
From здесь и здесь похоже, что каждый раз, когда мы хотим установить что-либо в пользовательских доверенных корневых центрах сертификации, возникает такая подсказка, и , вероятно, не поддерживается в контекстеиспользование не-GUI.
Проблема в том, что даже если я не установлю корневой ЦС в хранилище, я смогу успешно вызвать службу SOAP при запускеg это автономное приложение, только при запуске под IIS это не получается.
Кто-нибудь знает, почему это происходит и как его решить?