Signalr 信号机连接

Signalr 信号机连接,signalr,signalr-hub,Signalr,Signalr Hub,我想在用户连接到signalr服务器时对其进行身份验证。客户端是javascript,并且是跨域的。我尝试使用此方法,调用了AuthorizeHubMethodInvocation,但从未调用过AuthorizeHubConnection 我创建了一个新类AuthTicketAttribute,在这里我重写了这两个方法 public class AuthTicketAttribute : AuthorizeAttribute { public override bool Authoriz

我想在用户连接到signalr服务器时对其进行身份验证。客户端是javascript,并且是跨域的。我尝试使用此方法,调用了
AuthorizeHubMethodInvocation
,但从未调用过
AuthorizeHubConnection

我创建了一个新类
AuthTicketAttribute
,在这里我重写了这两个方法

public class AuthTicketAttribute : AuthorizeAttribute
{
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
    {
        return base.AuthorizeHubConnection(hubDescriptor, request);
    }

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        return base.AuthorizeHubMethodInvocation(hubIncomingInvokerContext, appliesToMethod);
    }
}
然后我把它添加到信号器映射函数中

var authorizer = new AuthTicketAttribute();
var module = new AuthorizeModule(authorizer, authorizer);
然后我试着调试代码,当我调用一个方法时,只有
AuthorizeHubMethodInvocation
被调用,当我连接时,
AuthorizeHubConnection
没有被调用。有什么想法吗

然后我想也许我可以将环境中设置
server.User
的代码从
AuthorizeHubConnection
移动到
AuthorizeHubMethodInvocation

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        IList<Claim> claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, "The users username")
        };
        ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, "Basic", ClaimTypes.NameIdentifier, ClaimTypes.Role);

        var environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
        environment["server.User"] = new ClaimsPrincipal(claimsIdentity);

        hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(environment), hubIncomingInvokerContext.Hub.Context.ConnectionId);

        return true;
    }

我弄明白了为什么没有调用连接

在开始连接之前,我没有从中心订阅任何内容

$.connection.myHub.client.something = function() {

};

$.connection.hub.start().done(function() {
    alert('I'm connected!');
});

一旦我这样做了,它就会被调用。

上面的答案对我来说不合适

问题在于
hubinominginvokerContext.Hub.Context.Request.Environment
的行为类似于
IDictionary
,但实际上是一个
Microsoft.Owin.Host.SystemWeb.CallenEnvironment.AspNetDictionary
,它在分配键值对时执行一些额外的检查(并在这样做时抛出)

我的解决方案是将内容添加到真正的
词典

var environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
var copy = new Dictionary<string, object>(environment)
{
    ["server.User"] = new ClaimsPrincipal(claimsIdentity)
};

var serverRequest = new ServerRequest(copy);
hubIncomingInvokerContext.Hub.Context = new HubCallerContext(serverRequest, hubIncomingInvokerContext.Hub.Context.ConnectionId);
var-environment=hubinominginvokercontext.Hub.Context.Request.environment;
var copy=新字典(环境)
{
[“server.User”]=新的ClaimsPrincipal(ClaimsEntity)
};
var serverRequest=新的serverRequest(副本);
HubinomingInvokerContext.Hub.Context=新的HubCallerContext(serverRequest,HubinomingInvokerContext.Hub.Context.ConnectionId);
var environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
var copy = new Dictionary<string, object>(environment)
{
    ["server.User"] = new ClaimsPrincipal(claimsIdentity)
};

var serverRequest = new ServerRequest(copy);
hubIncomingInvokerContext.Hub.Context = new HubCallerContext(serverRequest, hubIncomingInvokerContext.Hub.Context.ConnectionId);