Why is the TLS client certificate not being included in preflight request on most browsers? Why is the TLS client certificate not being included in preflight request on most browsers? angularjs angularjs

Why is the TLS client certificate not being included in preflight request on most browsers?


See https://bugzilla.mozilla.org/show_bug.cgi?id=1019603 and my comment in the answer at CORS with client https certificates (I had forgotten I’d seen this same problem reported before…).

The gist of all that is, the cause of the difference you’re seeing is a bug in Chrome. I’ve filed a bug for it at https://bugs.chromium.org/p/chromium/issues/detail?id=775438.

The problem is that Chrome doesn’t follow the spec requirements on this, which mandate that the browser not send TLS client certificates in preflight requests; so Chrome instead does send your TLS client certificate in the preflight.

Firefox/Edge/Safari follow the spec requirements and don’t send the TLS client cert in the preflight.


Update: The Chrome screen capture added in an edit to the question shows an OPTIONS request for a GET request, and a subsequent GET request — not the POST request from your code. So perhaps the problem is that the server forbids POST requests.


The request shown in https://i.stack.imgur.com/GD8iG.png is a CORS preflight OPTIONS request the browser automatically sends on its own before trying the POST request in your code.

The Content-Type: application/json request header your code adds is what triggers the browser to make that preflight OPTIONS request.

It’s important to understand the browser never includes any credentials in that preflight OPTIONS request — so the server the request is being sent to must be configured to not require any credentials/authentication for OPTIONS requests to /api/transactions/own-transactions/.

However, from https://i.stack.imgur.com/GD8iG.png it appears that server is forbidding OPTIONS requests to that /api/transactions/own-transactions/. Maybe that’s because the request lacks the credentials the server expects or maybe it’s instead because the server is configured to forbid all OPTIONS requests, regardless.

So the result of that is, the browser concludes the preflight was unsuccessful, and so it stops right there and never moves on to trying the POST request from your code.

Given what’s shown in https://i.stack.imgur.com/GD8iG.png it’s hard to understand how this could actually be working as expected in Chrome — especially given that no browsers ever send credentials of any kind in the preflight requests, so any possible browsers differences in handling of credentials would make no difference as far as the preflight goes.