我正在使用凭据和预检请求实现CORS,我有点不知道为什么预检请求在Firefox 30中始终失败但在Safari(7.0.2)和Chrome 35中有效.我认为这个问题与" 为什么会这样做有所不同" 经过身份验证的CORS请求的预检OPTIONS请求在Chrome中运行但不在Firefox中运行? "因为我没有收到401,而是来自浏览器客户端的特定于CORS的消息:
"跨源请求被阻止:同源策略不允许在http://myurl.dev.com上读取远程资源.这可以通过将资源移动到同一域或启用CORS来解决."
没有显示源代码,这就是我正在做的事情:
在服务器上:
OPTIONS响应的标题:
POST响应的标题:
在浏览器客户端中:
jQuery.ajax({
url: requestUrl,
type: 'POST',
data: getData(),
xhrFields: {
withCredentials: true
}
});
Run Code Online (Sandbox Code Playgroud)
根据规范,这将触发OPTIONS预检请求,该请求需要在其响应中具有CORS头.我已经多次阅读过W3C规范了,在预检响应中我无法确定我做错了什么,如果有的话.
我正在构建一个我正在构建的Web应用程序的问题.Web应用程序由一个有角度的4前端和一个dotnet核心RESTful api后端组成.其中一个要求是需要使用SSL相互身份验证对后端的请求进行身份验证; 即客户证书.
目前我将前端和后端托管为Azure应用服务,它们位于不同的子域中.
后端设置为需要客户端证书,遵循本指南,我认为这是为Azure应用程序服务执行此操作的唯一方法:https: //docs.microsoft.com/en-us/azure/app-service/app-服务网络的配置-TLS-互AUTH
当前端向后端发出请求时,我设置withCredentials为true- [根据文档] [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);
Run Code Online (Sandbox Code Playgroud)
在Chrome上,这是有效的,当发出请求时,浏览器会提示用户输入证书,并且它会包含在预检请求中,一切正常.
然而,对于所有其他主要浏览器,情况并非如此.Firefox,Edge和Safari都会使预检请求失败,因为服务器在请求中不包含客户端证书时会关闭连接.
直接浏览到api端点会使每个浏览器都提示用户输入证书,因此我非常确定这与大多数浏览器如何使用客户端证书处理预检请求明确相关.
我做错了什么?或者其他浏览器是否通过在发出请求时不提示输入证书而做错了?
我需要支持除Chrome以外的其他浏览器,所以我需要以某种方式解决这个问题.
我已经看到类似的问题通过后端允许而不是需要证书来解决.唯一的问题是我还没有找到一种方法来实际使用Azure应用服务.它要么需要要么不要求.
有没有人对我如何继续前进有任何建议?