当前位置: 首页 > 面试题库 >

为什么大多数浏览器的预检请求中不包括TLS客户端证书?

傅奕
2023-03-14
问题内容

我正在构建的Web应用程序有问题。该Web应用程序由一个angular 4前端和一个dotnet核心RESTful
API后端组成。要求之一是,需要使用SSL双向身份验证来验证对后端的请求。即客户证书。

目前,我同时将前端和后端托管为Azure应用服务,它们位于单独的子域中。

遵循本指南将后端设置为要求客户端证书,我认为这是针对Azure应用程序服务的唯一方法:https :
//docs.microsoft.com/zh-cn/azure/app-service/app-
服务网络配置TLS相互认证

当前端向后端发出请求时,我设置withCredentialstrue- [根据文档] [1]也应与客户端证书一起使用。

XMLHttpRequest.withCredentials属性是一个布尔值,指示是否应使用cookie,授权标头或TLS客户端证书之类的凭据发出跨站点访问控制请求。设置withCredentials不会影响同一站点的请求。

前端的相关代码:

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);

在Chrome上,此方法有效,当发出请求时,浏览器会提示用户输入证书,该证书将包含在预检请求中,并且一切正常。

但是,对于所有其他主要浏览器,情况并非如此。Firefox,Edge和Safari均会失败预检请求,因为服务器在请求中未包含客户端证书时会关闭连接。

直接浏览到api端点会使每个浏览器提示用户输入证书,因此,我很确定这与大多数浏览器如何处理带有客户端证书的预检请求有关。

做错什么了吗?还是其他浏览器通过发出请求时不提示输入证书来做错事?

我需要支持Chrome浏览器以外的其他浏览器,因此需要以某种方式解决此问题。

我看到通过让后端允许而不是要求证书可以解决类似的问题。唯一的问题是,我还没有找到使用Azure应用程序服务实际执行此操作的方法。它是必需的还是不需要的。

有人对我的前进方式有任何建议吗?


问题答案:

请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=1019603和我在CORS中使用客户端https证书的答案中的评论(我忘记了以前见过同样的问题……)。

要点是,您发现与众不同的原因是Chrome中的错误。我已经在https://bugs.chromium.org/p/chromium/issues/detail?id=775438上提交了一个错误。

问题在于Chrome浏览器未遵循此规范要求,该规范要求浏览器不要在预检请求中发送TLS客户端证书;因此Chrome
在飞行前发送您的TLS客户端证书。

Firefox / Edge / Safari遵循规范要求,并且 不要 在飞行前发送TLS客户端证书。

更新
:在对问题的修改中添加的Chrome屏幕截图显示了对 OPTIONS请求的 GET请求以及随后的请求,而 GET不是 POST代码中的请求。因此,问题可能出在服务器禁止 POST请求。

https://i.stack.imgur.com/GD8iG.png中显示的请求是CORS的预检OPTIONS请求,浏览器会在尝试POST在您的代码中尝试该请求之前自动自动发送该请求。

Content-Type: application/json您的代码添加的请求标头是触发浏览器发出该预检OPTIONS请求的原因。

了解浏览器就不会包括任何这一点很重要凭据在预检OPTIONS所以服务器的请求被发送到必须被配置为不需要任何凭证/认证-
请求OPTIONS请求/api/transactions/own-transactions/

但是,从https://i.stack.imgur.com/GD8iG.png看来,服务器正在禁止对此OPTIONS请求/api/transactions/own- transactions/。可能是因为请求缺少服务器期望的凭据,或者是因为服务器配置为禁止所有OPTIONS请求,无论如何。

因此,结果是,浏览器认为预检不成功,因此它就在那里停止了,并且从不尝试POST从您的代码中尝试请求。

鉴于https://i.stack.imgur.com/GD8iG.png中显示的内容,很难理解它在Chrome中的实际效果如何-
尤其是考虑到没有浏览器在预检请求中曾经发送过任何形式的凭证,因此就预检而言,任何可能的浏览器在处理凭据方面的差异都不会造成任何影响。



 类似资料:
  • 我有一个在生产中工作的密钥斗篷,我需要我的用户登录到一个使用react native开发的移动应用程序,使用该密钥斗篷。到目前为止,我使用的正常登录流程通过应用内浏览器作为AppAtuh,但现在我收到了一个用户的请求,说在应用程序,同时登录。 > 我使移动登录的Keycloak主题对移动应用程序UI进行了如此多的加密,以至于可以将其作为普通屏幕使用react WebView打开。 其次,这种思想适

  • 我知道这是不好的做法和特征识别应该是建设网站的方式。然而,这不是我的用例。 我有我的浏览器扩展的不同发行版,我想根据他们当前的浏览器更改下载按钮。 我试过使用,事实证明这是非常没用的,因为大多数浏览器都设置了所有流行的用户代理。例如chrome就有这个。 我见过很多网站的下载按钮上都有这个功能。如何做到这一点呢? 编辑:我现在了解了为什么“mozzila/x.x”位于userAgent字符串开头的

  • 看到一个项目:https://github.com/lencx/ChatGPT 是把网页版的 chatGPT 封装成桌面客户端 用的是 tauri 我记得 python 也有类似的,叫什么的?

  • 一面-2023年5月6日 ios客户端,大前端、object-c 自我介绍。有点背稿的感觉。 聊一个项目。说了OSG的项目。提到内存管理。 开始八股。内存:只能指针。 多态,静态、动态。模板、虚函数。静态的除了模板还有啥。析构函数为什么要添加虚函数。 空类size的大小。 struct/class的区别。 堆/栈/BSS几个内存类别 TCP四次挥手。 ipv4地址空间这么小怎么够用,NAT。用同一

  • 二面-2023年5月8日 第一次迟到了面试.. 自我介绍。刚开始没准备各种结巴,语言不顺。整体还是讲完了。 项目。疯狂问项目、但是又不是挖,就是让自己讲。讲了好几个项目。看起来不是特别满意。一个是我自己准备项目拿普通横向项目准备的亮点肯定不够不到位,另外岗位是客户端,没有什么相关的。 岗位匹配度上,问了好几遍和原技术栈不匹配,自己的个人想法。(一开始也是你捞的我,我有啥想法 手撕算法。快排。这两面