Próbuję nowej funkcji systemu Windows 8.1 i Windows Phone 8.1, a mianowicie magazynów certyfikatów i możliwości korzystania z certyfikatów klienta do uwierzytelniania klienta po stronie serwera. Jednak mam problemy z tą funkcjonalnością.Korzystanie z certyfikatów klienta dla systemu Windows RT (Windows 8.1/Windows Phone 8.1)
Mam podstawową przetestowaną usługę WCF, która działa na ekspresie IIS. Ekspres IIS jest skonfigurowany do obsługi SSL
i certyfikatów klienta. W pliku konfiguracyjnym IIS (configurationhost.config) Mam ustawione tak:
<access sslFlags="SslRequireCert" /> (tried also SslNegotiateCert)
<clientCertificateMappingAuthentication enabled="true" />
Dodałem certyfikatu klienta w aplikacji Windows RT, jak poniżej:
//Install the self signed client cert to the user certificate store
string CACertificate = null;
try
{
Uri uri = new Uri("ms-appx:///Assets/AdventureWorksTestClient1.pfx");
var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
IBuffer buffer = await FileIO.ReadBufferAsync(file);
using (DataReader dataReader = DataReader.FromBuffer(buffer))
{
byte[] bytes = new byte[buffer.Length];
dataReader.ReadBytes(bytes);
// convert to Base64 for using with ImportPfx
CACertificate = System.Convert.ToBase64String(bytes);
}
await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
CACertificate,
"",
ExportOption.Exportable,
KeyProtectionLevel.NoConsent,
InstallOptions.None,
"ClientCert1");
}
catch (Exception ex)
{...
Następnie używam HttpBaseProtocolFilter do której dodaję Certyfikat klienta w ten sposób:
IReadOnlyCollection<Certificate> certs = await CertificateStores.FindAllAsync(query);
HttpBaseProtocolFilter bpf = new HttpBaseProtocolFilter();
if (certs.Count > 0)
{
cert = certs.ElementAt(0);
bpf.ClientCertificate = cert;
}
HttpClient httpClient = new HttpClient(bpf);
....
a następnie wniosek:
var resp = await httpClient.GetAsync(new Uri(serviceURL));
Ta linia kodu generuje ten wyjątek:
{System.Exception: Exception from HRESULT: 0x80072F7D
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at JumpStartCertificateDemo.MainPage.<btnCallService_Click>d__0.MoveNext()}
Jestem w 100% pewien, że mam odpowiednie certyfikaty importowane również na localhost (komputer lokalny), a także na stronie aplikacji. Wywołanie usługi za pośrednictwem przeglądarki działa poprawnie. (Zostałem poproszony o dostarczenie certyfikatu klienta), więc musi wystąpić problem z dostarczeniem certyfikatu klienta w aplikacji.
Czy ktoś może mi pomóc w tej sprawie? Dziękuję Ci.
chyba to, co widzisz, to dlatego, że wniosek o cert jest WebException w C#, które trzeba obsłużyć złapanie go. ponieważ nie możesz spróbować złapać, musisz usunąć oczekujące i użyć zadania do sprawdzenia wyniku w t.IsFaulted i sprawdź t.Exception; –
Pedro dziękuję za komentarz, ale łapię wyjątek (wiem, jak z nimi pracować), jest problem, że nie powinno być wyjątku, ponieważ wywołanie żądania pobrania powinno działać, ponieważ dołączam certyfikat klienta i żądanie działa z przeglądarki, a także z Androida. –
Nie, w .Net, w zależności od opcji żądania, gdy żądanie certyfikatu zgłasza wyjątek, to jak to działa, zrobiłem to wiele razy. Wyjątek WebException jest zgłaszany, gdy otrzymasz coś w odpowiedzi 4XX. Użyj skrzypka, aby zobaczyć, co otrzymujesz. –