我有三个 ASP.NET WebAPI 端点:
三台服务器都使用 OAuth2 中间件作为 Auth 机制。 Microsoft.Owin.Cors 也已配置。
服务器仅使用 HTTPS 请求。
SignalR v2.2.0 安装在 serverB.com 上。
我可以成功地从 serverC.com 向 serverA.com 发出跨域请求以获取承载 token ,但实际上,我不知道如何在连接到 serverB.com 时传递身份验证 token
到目前为止,我发现了两种方法:
$.ajaxSetup({
发送前:函数(xhr){
xhr.setRequestHeader('tokenKey', 'tokenValue');
}});
但它强制 SignalR 仅使用长轮询。
是否有任何其他方式发送身份验证 token (不在查询字符串中),以便 OAauth BearerAuthorizationProvider 可以使用和验证它?也许,cookie,标题或任何其他方式?
更新
为两种环境设置的 CORS 中间件允许所有数据并接受凭据。
这是我的 OWIN 中间件:
var requestUri = context.Request.Uri.AbsolutePath;
if (string.Equals(requestUri, authRoute, StringComparison.OrdinalIgnoreCase))
{
if (!context.Request.Headers.ContainsKey("Authorization") || string.IsNullOrEmpty(context.Request.Headers["Authorization"]))
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
else
{
context.Response.Cookies.Append("BearerToken", context.Request.Headers["Authorization"]);
}
}
else
{
await Next.Invoke(context);
}
然后我做第一个 Ajax 请求:
$.ajax({
url: self.communicationHubUrl + '/authenticate',
type: 'post',
cache: false,
crossDomain: true,
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', self.accessToken);
});
中间件将身份验证 token 从 header 设置为响应 cookie。
然后我调用 hub.Start 以便 SignalR 开始发送 ajax 请求。
但是由于某些我不太明白的原因,只有当我通过 $.ajaxSetup 为所有 ajax 请求启用 xhr.withCredentials = true 时,cookie 才会出现在请求中
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
没有此设置的请求不包括 cookie。另一方面,我认为强制所有 ajax 请求启用此类设置并不是一个好的决定。
此外,我在 Oauth 中间件中遇到了奇怪的行为:当来自 signalR 的请求到来时,不会调用 ValidateIdentity 方法,所以我得到了默认的主体,而不是 401 Unauthorized。
最佳答案
我认为将身份验证 token 放入 cookie 将是您最好的选择。与 ajaxSetup 选项不同,cookie 与 EventSource 和 WebSocket 请求一起发送。
您可能需要向 SignalR 服务器 (serverB.com) 添加一些中间件,以便在启动 SignalR 连接之前 POST auth token 时设置适当的 cookie。
关于oauth-2.0 - 连接 Auth token 并将其传递到启用了 CORS 的 SignalR 集线器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25120766/