我们有一个使用基本身份验证和 SSL 的自托管(在控制台应用程序中)SignalR 集线器。
中心类是:
[HubName("TestingHub")]
[Authorize(Mode=AuthorizeMode.Both)]
public class TestingHub : Hub
{
public void TestMethod(int arg)
{
Console.WriteLine("Arg: {0}", arg);
}
public string TestWebClientCall(string message)
{
Clients.Caller.clientFunction(string.Format("From the server : {0}", message));
return "Call Worked";
}
}
自托管按如下方式完成:
var url = "https://localhost:3232/";
var server = new Server(url);
server.Configuration.DisconnectTimeout = TimeSpan.Zero;
var authoriser = new Authoriser();
server.HubPipeline.AddModule(new AuthorizeModule(authoriser, authoriser));
server.AuthenticationSchemes = AuthenticationSchemes.Basic;
server.MapHubs();
server.Start();
Authoriser 类是:
public class Authoriser : IAuthorizeHubConnection, IAuthorizeHubMethodInvocation
{
bool isAuthorised(HttpListenerBasicIdentity identity)
{
var authorised = Membership.Provider.ValidateUser(identity.Name, identity.Password);
return authorised;
}
public bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
{
var identity = (HttpListenerBasicIdentity)request.User.Identity;
return isAuthorised(identity);
}
public bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext)
{
var identity = (HttpListenerBasicIdentity)hubIncomingInvokerContext.Hub.Context.User.Identity;
return isAuthorised(identity);
}
}
然后MVC Razor页面javascript如下:
$(document).ready(function () {
var hubUrl = "https://localhost:3232/";
$.connection.hub.url = hubUrl;
var hub = $.connection.TestingHub;
if (hub == undefined) {
alert("hub not found at " + hubUrl);
}
else {
$.extend(hub, {
clientFunction: function (textMessage) {
alert("clientFunction called : " + textMessage);
}
});
$.connection.hub.start()
.done(function() {
hub.server.testWebClientCall('Hello from the client')
.done(function (message) {
alert(message);
});
})
.fail(function() {
alert("could not connect!");
});
}
});
这是发生的事情:
- 页面加载并弹出Basic Auth登录框-输入用户名/密码
- 再次弹出基本身份验证登录框 - 我猜是 SignalR/集线器的脚本包含
- 'hub' 对象是有效的 - 即可以看到 'TestingHub'
- $.connection.hub.start() 调用总是转到 .fail 并且 hub.server.testWebClientCall 甚至从未尝试过。
因为我们可以从 .NET 控制台应用程序客户端访问,所以 SSL 证书对于自托管来说都是很好的设置。
所以问题是,对于这个涉及基本身份验证和 SSL 的自托管集线器,应该如何处理?如何将用户名/密码组合传递到 SignalR 集线器/调用以通过身份验证?
作为参考,我们正在测试这种方法,因为我们目前有一个 MVC3 站点,该站点通过 HTTPS/SSL 上的表单身份验证进行保护,并且根据我的另一个问题,访问不安全的自托管 SignalR 集线器(即非 HTTPS /SSL) 来自 HTTP/SSL 下的 MVC 站点似乎不起作用。
在 SignalR 示例中,我找到了有关“托管”(即 AuthHub 类)授权的详细信息,但我找不到有关如何从 Web 客户端连接的任何信息 - 似乎缺少“现实世界”示例 - 即具有完整身份验证和 SSL 加密。