мы хотим подключить наше приложение к нашему веб-сервису IIS. Мы используем самозаверяющие сертификаты, а также клиентский сертификат для аутентификации.
Когда веб-сервис не требует проверки подлинности клиентского сертификата, все работает нормально, вызывается NSURLAuthenticationMethodServerTrust, и запрос продолжается. Но когда я активирую аутентификацию клиентского сертификата на нашем сервере, после DidReceiveChallenge с NSURLAuthenticationMethodServerTrust в качестве вызова вызывается DidCompleteWithError. Сообщение об ошибке: «Сертификат для этого сервера недействителен. Возможно, вы подключаетесь к серверу, выдающему себя за «192.168.221.118», что может подвергнуть риску вашу конфиденциальную информацию.
Примечание. «NSURLAuthenticationMethodClientCertificate» никогда не вызывается, перед этим происходит сбой приложения. Сертификат клиента подписан промежуточным сертификатом, поэтому я не понимаю, почему не удается выполнить вызов ServerTrust.
Кроме того: на мой взгляд, в этом нет необходимости, но я также попытался добавить сертификат клиента в коллекцию AnchorCertificates Sectrust.
Заранее спасибо за вашу помощь.
Вот мой код:
private class SessionDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
{
private Action<bool, string> completed_callback;
private string antwortCache;
private int status_code;
public SessionDelegate(Action<bool, string> completed)
{
completed_callback = completed;
antwortCache = "";
}
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
if (challenge.PreviousFailureCount == 0)
{
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodServerTrust"))
{
// GetParent is correct, because I'm too lazy to copy the certs into to the correct folders...
var path = Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var caPath = Path.Combine(path.FullName, "ca.cert.der");
var caByteArray = File.ReadAllBytes(caPath);
var caCert = new X509Certificate2(caByteArray);
var interPath = Path.Combine(path.FullName, "intermediate.cert.der");
var interByteArray = File.ReadAllBytes(interPath);
var interCert = new X509Certificate2(interByteArray);
var secTrust = challenge.ProtectionSpace.ServerSecTrust;
var certCollection = new X509CertificateCollection();
certCollection.Add(caCert);
certCollection.Add(interCert);
secTrust.SetAnchorCertificates(certCollection);
var credential = new NSUrlCredential(secTrust);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodClientCertificate"))
{
var path = Directory.GetParent(GlobaleObjekte.SSLZertifikatePath);
var certPath = Path.Combine(path.FullName, "client.pfx");
var certByteArray = File.ReadAllBytes(certPath);
var cert = new X509Certificate2(certByteArray, Settings.WSClientCertPasswort);
var ident = SecIdentity.Import(certByteArray, Settings.WSClientCertPasswort);
var credential = new NSUrlCredential(ident, new SecCertificate[] { new SecCertificate(cert) }, NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodHTTPBasic"))
{
var credential = new NSUrlCredential(Settings.WebserviceBenutzer, Settings.WebservicePasswort, NSUrlCredentialPersistence.ForSession);
completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
return;
}
completed_callback(false, "Unbekannte Authentifizierungsanfrage: " + challenge?.ProtectionSpace?.AuthenticationMethod);
}
else
{
completed_callback(false, "Authentifizierung fehlgeschlagen: " + challenge?.ProtectionSpace?.AuthenticationMethod);
}
}
}