22
33The WebView2 team has been asked for an API to intercept client certificates when WebView2 is
44making a request to an Http server that needs a client certificate for Http authentication.
5- This event allows you to show ui if desired, replace default client certificate dialog prompt,
5+ This event allows you to show ui if desired, replace default client certificate dialog prompt,
66programmatically query the certificates and select a certificate from the list to respond to the server.
77
88In this document we describe the API. We'd appreciate your feedback.
@@ -32,10 +32,10 @@ wil::com_ptr<ICoreWebView2> m_webView;
3232wil::com_ptr<ICoreWebView2_3> m_webView2_3;
3333EventRegistrationToken m_ClientCertificateRequestedToken = {};
3434
35- // ! [ClientCertificateRequested1]
3635// Turn off client certificate selection dialog using ClientCertificateRequested event handler
3736// that disables the dialog. This example hides the default client certificate dialog and
3837// always chooses the last certificate without prompting the user.
38+ // ! [ClientCertificateRequested1]
3939void SettingsComponent::EnableCustomClientCertificateSelection ()
4040{
4141 m_webView2_3 = m_webView.try_query<ICoreWebView2_3>();
@@ -90,13 +90,13 @@ void SettingsComponent::EnableCustomClientCertificateSelection()
9090wil::com_ptr<ICoreWebView2> m_webView;
9191wil::com_ptr<ICoreWebView2_3> m_webView2_3;
9292EventRegistrationToken m_ClientCertificateRequestedToken = {};
93- std::vector<ClientCertificate> client_certificates_ ;
93+ std::vector<ClientCertificate> clientCertificates_ ;
9494
9595struct ClientCertificate
9696{
97- PWSTR Subject;
98- PWSTR DisplayName;
99- PWSTR Issuer;
97+ wil::unique_cotaskmem_string Subject;
98+ wil::unique_cotaskmem_string DisplayName;
99+ wil::unique_cotaskmem_string Issuer;
100100 double ValidFrom;
101101 double ValidTo;
102102 PCWSTR CertificateKind;
@@ -105,12 +105,12 @@ struct ClientCertificate
105105ScenarioClientCertificateRequested::ScenarioClientCertificateRequested (SampleWindow* sampleWindow)
106106 : m_sampleWindow(sampleWindow), m_webView(sampleWindow->GetWebView())
107107{
108- //! [ ClientCertificateRequested2]
109108 // Register a handler for the ` ClientCertificateRequested ` event.
110109 // This example hides the default client certificate dialog and shows a custom dialog instead.
111110 // The dialog box displays mutually trusted certificates list and allows the user to select a certificate.
112111 // Selecting ` OK ` will continue the request with a certificate.
113112 // Selecting ` CANCEL ` will continue the request without a certificate.
113+ //! [ ClientCertificateRequested2]
114114 m_webView2_3 = m_webView.try_query<ICoreWebView2_3>();
115115 if (m_webView2_3)
116116 {
@@ -136,32 +136,32 @@ ScenarioClientCertificateRequested::ScenarioClientCertificateRequested(SampleWin
136136
137137 if (certificateCollectionCount > 0)
138138 {
139- ClientCertificate client_certificate ;
139+ ClientCertificate clientCertificate ;
140140 for (UINT i = 0; i < certificateCollectionCount; i++)
141141 {
142142 CHECK_FAILURE(certificateCollection->GetValueAtIndex(i, &certificate));
143143
144- CHECK_FAILURE(certificate->get_Subject(&client_certificate .Subject));
144+ CHECK_FAILURE(certificate->get_Subject(&clientCertificate .Subject));
145145
146- CHECK_FAILURE(certificate->get_DisplayName(&client_certificate .DisplayName));
146+ CHECK_FAILURE(certificate->get_DisplayName(&clientCertificate .DisplayName));
147147
148- CHECK_FAILURE(certificate->get_Issuer(&client_certificate .Issuer));
148+ CHECK_FAILURE(certificate->get_Issuer(&clientCertificate .Issuer));
149149
150150 COREWEBVIEW2_CLIENT_CERTIFICATE_KIND Kind;
151151 CHECK_FAILURE(certificate->get_Kind(&Kind));
152- client_certificate .CertificateKind = NameOfCertificateKind(Kind);
152+ clientCertificate .CertificateKind = NameOfCertificateKind(Kind);
153153
154- CHECK_FAILURE(certificate->get_ValidFrom(&client_certificate .ValidFrom));
154+ CHECK_FAILURE(certificate->get_ValidFrom(&clientCertificate .ValidFrom));
155155
156- CHECK_FAILURE(certificate->get_ValidTo(&client_certificate .ValidTo));
156+ CHECK_FAILURE(certificate->get_ValidTo(&clientCertificate .ValidTo));
157157
158- client_certificates_ .push_back(client_certificate );
158+ clientCertificates_ .push_back(clientCertificate );
159159 }
160160
161161 // Display custom dialog box for the client certificate selection.
162162 ClientCertificateSelectionDialog dialog(
163163 m_sampleWindow->GetMainWindow(), L"Select a Certificate for authentication",
164- host.get(), port, client_certificates_ );
164+ host.get(), port, clientCertificates_ );
165165
166166 if (dialog.confirmed)
167167 {
@@ -214,7 +214,7 @@ ScenarioClientCertificateRequested::ScenarioClientCertificateRequested(SampleWin
214214// Turn off client certificate selection dialog using ClientCertificateRequested event handler
215215// that disables the dialog. This example hides the default client certificate dialog and
216216// always chooses the last certificate without prompting the user.
217- private bool _isCustomClientCertificateSelection = false;
217+ private bool _isCustomClientCertificateSelection = false;
218218void EnableCustomClientCertificateSelection()
219219{
220220 // Safeguarding the handler when unsupported runtime is used.
@@ -246,7 +246,7 @@ void EnableCustomClientCertificateSelection()
246246
247247void WebView_ClientCertificateRequested(object sender, CoreWebView2ClientCertificateRequestedEventArgs e)
248248{
249- IReadOnlyList<CoreWebView2ClientCertificate> certificateList = e. MutuallyTrustedCertificates;
249+ IReadOnlyList<CoreWebView2ClientCertificate> certificateList = e.MutuallyTrustedCertificates;
250250 if (certificateList. Count() > 0)
251251 {
252252
@@ -265,7 +265,7 @@ void WebView_ClientCertificateRequested(object sender, CoreWebView2ClientCertifi
265265 }
266266}
267267
268- ```
268+ ```
269269
270270## .NET/ WinRT: Custom certificate selection dialog
271271
@@ -314,7 +314,7 @@ void DeferredCustomClientCertificateSelectionDialog()
314314 else
315315 {
316316 // Continue without a certificate to respond to the server if certificate list is empty.
317- args .Handled = false ;
317+ args .Handled = true ;
318318 }
319319 }
320320
@@ -370,17 +370,18 @@ interface ICoreWebView2_3 : ICoreWebView2_2 {
370370 ///
371371 /// With this event you have several options for responding to client certificate requests:
372372 ///
373- /// * You can query the mutually trusted CA certificates, and select a certificate
374- /// from the list to respond to the server.
375- /// * You can choose to respond to the server without a certificate.
376- /// * You can choose to display default client certificate selection dialog prompt
377- /// to let user to respond to the server.
378- /// * You can cancel the request.
373+ /// Scenario | Handled | Cancel | SelectedCertificate
374+ /// ---------------------------------------------------------- | ------- | ------ | -------------------
375+ /// Respond to server with a certificate | True | False | MutuallyTrustedCertificate value
376+ /// Respond to server without certificate | True | False | null
377+ /// Display default client certificate selection dialog prompt | False | False | n/a
378+ /// Cancel the request | n/a | True | n/a
379379 ///
380380 /// If you don't handle the event, WebView2 will
381381 /// show the default client certificate selection dialog prompt to user.
382382 ///
383383 /// \snippet SettingsComponent.cpp ClientCertificateRequested1
384+ /// \snippet ScenarioClientCertificateRequested.cpp ClientCertificateRequested2
384385 HRESULT add_ClientCertificateRequested(
385386 [ in] ICoreWebView2ClientCertificateRequestedEventHandler* eventHandler,
386387 [ out] EventRegistrationToken* token);
@@ -517,7 +518,7 @@ interface ICoreWebView2ClientCertificateRequestedEventArgs : IUnknown {
517518## . NET/ WinRT
518519
519520``` c#
520- namespace Microsoft . Web . WebView2 . Core
521+ namespace Microsoft .Web .WebView2 .Core
521522{
522523
523524 runtimeclass CoreWebView2ClientCertificateRequestedEventArgs;
@@ -558,11 +559,18 @@ namespace Microsoft. Web. WebView2. Core
558559 CoreWebView2ClientCertificateKind Kind { get ; };
559560
560561 String ToPemEncoding ();
562+ /// Converts this to a System.Security.Cryptography.X509Certificates.X509Certificate2.
563+ // This is only for the .NET API, not the WinRT API.
564+ System .Security .Cryptography .X509Certificates .X509Certificate2 ToX509Certificate2 (CoreWebView2ClientCertificate coreWebView2ClientCertificate );
565+
566+ /// Converts this to a Windows.Security.Cryptography.Certificates.Certificate.
567+ // This is only for the WinRT API, not the .NET API.
568+ Windows .Security .Cryptography .Certificates .Certificate ToCertificate (CoreWebView2ClientCertificate coreWebView2ClientCertificate );
561569 }
562570
563571 runtimeclass CoreWebView2
564572 {
565- event Windows . Foundation . TypedEventHandler < CoreWebView2 , CoreWebView2ClientCertificateRequestedEventArgs > ClientCertificateRequested ;
573+ event Windows .Foundation .TypedEventHandler < CoreWebView2 , CoreWebView2ClientCertificateRequestedEventArgs > ClientCertificateRequested ;
566574 }
567575
568576}
0 commit comments