microsoft / react-native-windows

A framework for building native Windows apps with React.
https://microsoft.github.io/react-native-windows/
Other
16.41k stars 1.14k forks source link

Add delegate property to configure React's HttpClient to use a client certificate #12744

Open rbergerjr opened 9 months ago

rbergerjr commented 9 months ago

Summary

In order for XHRRequests from javascript layer to request to certificate protected endpoints, a client certificate must be added to the underlying WinRT HttpClient.

Certificate configuration is performed through the HttpBaseProtocolFilter object via the HttpBaseProtocolFilter::ClientCertificate property. The HttpBaseProtocolFilter, or more generally an IHttpFilter, is passed into HttpClient at construction.

Applications need to configure the http stack's HttpBaseProtocolFilter before HttpClient construction. New API is a novel property set on the ReactInstanceSettings::Properties() property bag. The property value is a delegate of type void(winrt::Windows::Web::Http::Filters::IHttpBaseProtocolFilter& filter). If the property is set, the delegate is called during HttpClient configuration in IHttpResource::Make to allow application code to modify HttpBaseProtocolFilter. Modified HttpBaseProtocolFilter is then passed to HttpClient during HttpModule init.

Alternatives designs considered were:

Motivation

Enterprise applications often have to access protected endpoints which can be guarded by a certificate. In order for javascript layer to access certificate protected endpoints, the React Native Windows http stack needs to be configured to include the certificate.

React Native Windows uses WinRT's HttpClient to facilitate network requests from javascript layer. HttpClient needs to be configured with certificate in order to facilitate javascript requests to certificate protected endpoints.

Basic Example

In ReactNativeHost setup, add property to ReactInstanceSettings::Properties via setter in Networking/HttpBaseProtocolFilterModifierSettings.h

  Microsoft::React::Networking::SetHttpBaseProtocolFilterModifierDelegate(
      properties, [](winrt::Windows::Web::Http::Filters::IHttpBaseProtocolFilter& filter) {
        auto certFind =
            winrt::Windows::Security::Cryptography::Certificates::CertificateStores::FindAllAsync();
        auto certs = certFind.get();
        for (auto const& cert : certs) {
          auto issuer = cert.Issuer();

          if (winrt::to_string(issuer) == kMyIssuer) {
            filter.ClientCertificate(cert);
            return;
          }
        }
      });

Open Questions

No response

jonthysell commented 9 months ago

@JunielKatarn Can you look at this? Does this seem like the right approach to adding this functionality? (See linked PR).

JunielKatarn commented 9 months ago

@jonthysell I have followed up with @rbergerjr and suggested a simplified approach (using a filter factory function instead of a filter "editor").

More details on the PR's thread.

Currently awaiting the next commits to approve.