Why is the TLS client certificate not included in the pre-validation request in most browsers?

I have a problem with the web application that I am creating. The web application consists of the angular 4 framework and the RESTful api mesh core. One of the requirements is that backend requests must be authenticated using mutual SSL authentication; i.e. client certificates.

I currently host both the interface and the backend as Azure application services, and they are on separate subdomains.

The backend is configured to require client certificates, following this guide, which I believe is the only way to do this for Azure application services: https://docs.microsoft.com/en-us/azure/app-service/app- service-web-configure-tls-mutual-auth

When the external interface makes requests to the server, I set withCredentials to true - which [according to the documentation] [1] should also work with client certificates.

The XMLHttpRequest.withCredentials property is a boolean property that indicates whether Access Control firewall requests should be executed using credentials such as cookies, authority headers, or TLS client certificates. The setting withCredentials does not affect requests on a single site.

Corresponding code from the interface:

 const headers = new Headers({ 'Content-Type': 'application/json' }); const options = new RequestOptions({ headers, withCredentials: true }); let apiEndpoint = environment.secureApiEndpoint + '/api/transactions/stored-transactions/'; return this.authHttp.get(apiEndpoint, JSON.stringify(transactionSearchModel), options) .map((response: Response) => { return response.json(); }) .catch(this.handleErrorObservable); 

In Chrome, this works when the request is made, the browser requests a certificate from the user, and it is included in the preliminary verification request, and everything works.

For all other major browsers, however, this is not the case. Firefox, Edge, and Safari do not perform a pre-flight request because the server disconnects if it does not contain a client certificate in the request.

Viewing directly at the api endpoint makes each browser request a certificate from the user, so I’m sure this clearly relates to how most browsers handle pre-validation requests with client certificates.

Something is wrong? Or do other browsers do the wrong thing without requesting a certificate when making requests?

I need to support browsers other than Chrome, so I need to solve this somehow.

I saw that similar problems are solved with the backend, and not for obtaining certificates. The only problem is that I did not find a way to do this using Azure applications. It requires or does not require.

Does anyone have any suggestions on how I can move on?

+5
source share
1 answer

See https://bugzilla.mozilla.org/show_bug.cgi?id=1019603 and my comment in the CORS answer with https client certificates (I forgot that Id saw the same issue that was reported earlier ...).

The essence of all that is, the reason for the difference that you see is a bug in Chrome. Ive filed an error for him at https://bugs.chromium.org/p/chromium/issues/detail?id=775438 .

The problem is that Chrome does not comply with the specification requirements for this, which require the browser not to send TLS client certificates in pre-flight requests; therefore, Chrome instead sends your TLS client certificate in the pre-flight period.

Firefox / Edge / Safari adheres to specifications and does not send a TLS client certificate in the pre-flight period.


<y> Refresh . The Chrome screen storage added to edit the question shows the OPTIONS request for the GET request and the subsequent GET request is not a POST request from your code, so the problem may be that the server denies POST requests.


The request shown at https://i.stack.imgur.com/GD8iG.png is a CORS pre-flight OPTIONS request browser automatically sends its messages before trying to execute a POST request in your code.

The Content-Type: application/json request header that your code adds is what causes the browser to execute the pre-flight OPTIONS request.

It is important to understand that the browser never includes credentials in the OPTIONS preview request - therefore, the server on which the request is sent must be configured so as not to require credentials / authentication for OPTIONS requests /api/transactions/own-transactions/ .

However, from https://i.stack.imgur.com/GD8iG.png it seems that the server forbids OPTIONS requests to this /api/transactions/own-transactions/ . Perhaps this is due to the fact that the request does not have enough credentials expected by the server or, possibly, instead, because the server is configured to prohibit all OPTIONS requests, regardless.

Thus, as a result, the browser fails the preflight check, and therefore it stops right there and never goes on trying to POST from your code.

Given what is shown at https://i.stack.imgur.com/GD8iG.png , it's hard to see how this can actually work as expected in Chrome - especially considering that no browsers ever send credentials of any type in requests pre-flight verification, so any possible differences in browsers when processing credentials will not matter as much as possible pre-flight. C>

+3
source

Source: https://habr.com/ru/post/1012430/


All Articles