SignalR:调用者无权调用该方法

时间:2016-08-29 11:12:38

标签: asp.net-web-api ionic-framework signalr authorize

在调用" SignalR时出错:调用者无权调用LoadPvtChatHistory_Hub方法" IsAuthenticated也总是假的。

public class QueryStringBearerAuthorizeAttribute : AuthorizeAttribute
{
    public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, IRequest request)
    {
        var dataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider();
        var secureDataFormat = new Microsoft.Owin.Security.DataHandler.TicketDataFormat(dataProtectionProvider.Create());

        //var secureDataFormat = new Microsoft.Owin.Security.DataHandler.TicketDataFormat(new MachineKeyProtector());
        var token = request.QueryString.Get("Bearer");

        if (string.IsNullOrEmpty(token))
            return false;
     //   var token = request.QueryString.Get(WebApiConfig.AuthenticationType);
        var authenticationTicket = secureDataFormat.Unprotect(token);

        if (authenticationTicket == null || authenticationTicket.Identity == null || !authenticationTicket.Identity.IsAuthenticated)
        {
            return false;
        }

        request.Environment["server.User"] = new ClaimsPrincipal(authenticationTicket.Identity);
        request.Environment["server.Username"] = authenticationTicket.Identity.Name;
        request.GetHttpContext().User = new ClaimsPrincipal(authenticationTicket.Identity);
        return true;
    }

    public override bool AuthorizeHubMethodInvocation(Microsoft.AspNet.SignalR.Hubs.IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
        // check the authenticated user principal from environment
        var environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
        var principal = environment["server.User"] as System.Security.Claims.ClaimsPrincipal;
        if (principal != null && principal.Identity != null && principal.Identity.IsAuthenticated) // IsAuthenticated always gets false
        {
            // create a new HubCallerContext instance with the principal generated from token
            // and replace the current context so that in hubs we can retrieve current user identity
            hubIncomingInvokerContext.Hub.Context = new Microsoft.AspNet.SignalR.Hubs.HubCallerContext(new Microsoft.AspNet.SignalR.Owin.ServerRequest(environment), connectionId);
            return true;
        }
        else
        {
            return false;
        }
    }

}

当点击发送按钮时,我正在调用AppHub的这个Invoke方法,但是在调用它时会给我一个像未授权的错误。

AppHub.invoke('LoadPvtChatHistory_Hub', curVM, GENERAL_CONFIG.APP_messageExpiryTimeLimit);

AppHub.cs

[QueryStringBearerAuthorize]
    public class AppHub : Hub
    {
public void LoadPvtChatHistory_Hub(string xiSelectedUserID, int xiMessageExpiryTimeLimit)
        {
        ///code....
        }
    }
[16:36:33 GMT+0530 (India Standard Time)] SignalR: Caller is not authorized to invoke the LoadPvtChatHistory_Hub method on AppHub.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.SignalR.Hubs.HubPipelineModule.<>c__DisplayClass0_0.<<BuildIncoming>b__0>d.MoveNext().
jquery.signalR.js:82 [16:36:33 GMT+0530 (India Standard Time)] SignalR: apphub.loadPvtChatHistory_Hub failed to execute. Error: Caller is not authorized to invoke the LoadPvtChatHistory_Hub method on AppHub.
jquery.signalR.js:82 [16:37:00 GMT+0530 (India Standard Time)] SignalR: Invoking apphub.sendPrivateMessage_Hub
jquery.signalR.js:82 [16:37:04 GMT+0530 (India Standard Time)] SignalR: Caller is not authorized to invoke the SendPrivateMessage_Hub method on AppHub.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.SignalR.Hubs.HubPipelineModule.<>c__DisplayClass0_0.<<BuildIncoming>b__0>d.MoveNext().
jquery.signalR.js:82 [16:37:04 GMT+0530 (India Standard Time)] SignalR: apphub.sendPrivateMessage_Hub failed to execute. Error: Caller is not authorized to invoke the SendPrivateMessage_Hub method on AppHub.

1 个答案:

答案 0 :(得分:0)

这是我的解决方案,在Azure和本地工作。 AngularJS,Web API和SignalR request.Environment [“server.User”]此代码在Azure上不起作用。首先,我创建自定义过滤器类。

 public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
        var request=hubIncomingInvokerContext.Hub.Context.Request;
        var _Authorization = request.QueryString.Get("Bearer");
        if (!string.IsNullOrEmpty(_Authorization))
        {
            //var token = _Authorization.Replace("Bearer ", "");
            var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(_Authorization);

            if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
            {
                Dictionary<string, object> _DCI = new Dictionary<string, object>();
                _DCI.Add("server.User", new ClaimsPrincipal(ticket.Identity));
                hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(_DCI), connectionId);
                return true;
            }
        }
        return false;
    }

Refer this article.