我们有一个自托管(在控制台应用程序中)SignalR集线器,它同时使用基本身份验证和SSL。
集线器类是:
[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!");
});
}
});
以下是发生的事情:
SSL证书可以自行托管,因为我们可以从.NET控制台应用客户端访问。
所以问题是,如何在这个自我托管的集线器上实现这一点,同时涉及Basic Auth和SSL?如何将用户名/密码组合传递到SignalR集线器/呼叫以通过身份验证?
作为参考,我们正在测试这种方法,因为我们目前有一个MVC3站点,通过HTTPS / SSL上的表单身份验证保护,并根据我的另一个问题,访问非安全的自托管SignalR集线器(来自HTTP / SSL下的MVC站点的非HTTPS / SSL似乎不起作用。
在SignalR示例中,我发现了有关'托管'(即AuthHub类)授权的详细信息,但我找不到任何关于如何从Web客户端连接的内容 - 似乎缺乏'现实世界的样本 - 即使用完全身份验证和SSL加密。
答案 0 :(得分:1)
我认为这与Self主机或SSL无关。我想你问的是如何将用户名和密码传递给期望从javascript(“web客户端”)获得基本身份验证的服务。使用SignalR JS API无法更改标头,因此您可以在那里运气。
做这样的事情可能会有所帮助:
http://coderseye.com/2007/how-to-do-http-basic-auth-in-ajax.html
您可以尝试使用$ .ajaxSetup来影响所有传出的ajax请求,但我不确定这是否适用于websockets。
似乎websockets不支持Auhtorization标头:
basic authentication for websockets
所以你不得不求助于使用查询字符串。
答案 1 :(得分:0)
在建立SignalR连接之前,请使用以下代码:
$.ajaxSetup({
headers: {
'Authorization': "your auth token"
}
});
好消息是:SignalR与auth一起使用!
坏消息是:SignalR从websocket退回长时间的投票。
我更喜欢这样做,因为我根本无法接受url或方法调用中的任何丑陋参数!