如何基于HTTP头创建自定义身份验证机制?

时间:2016-07-29 16:55:27

标签: c# asp.net .net signalr

我将旧版本的问题留在底部。

我想为SignalR客户端实现自定义身份验证。在我的例子中,这是Java客户端(Android)。不是网络浏览器。没有表单身份验证,没有Windows身份验证。这些是使用java库的纯粹的vanilla http客户端。

所以,让我们说连接到HUB的客户端传递自定义标头。我需要以某种方式根据此标头验证用户。文档here提到它是可能的,但没有提供有关如何实现它的任何细节。

以下是Android方面的代码:

expr = xPath.compile("//doc/str[@name='"+attribute+"']");

P.S。下面的原始问题是我“简化”问题的愿望。因为我可以访问int main(){ system("gnome-terminal 'gdb test'"); system("break main"); return 0; } 回调中的标头。我认为有简单的方法可以放下连接..

将Signal R与自定义身份验证机制配合使用。我只是检查连接客户端是否通过连接请求传入了某个标头。

问题是 - 如何拒绝或不连接未通过支票的用户?文档here并没有真正解释这种情况。提到使用证书/标题 - 但没有关于如何在服务器上处理它的示例。我不使用Forms或Windows身份验证。我的用户 - 安卓java设备。

以下是我的Hub中我想拒绝连接的代码..

hubConnection = new HubConnection("http://192.168.1.116/dbg", "", true, new NullLogger());
        hubConnection.getHeaders().put("SRUserId", userId);
        hubConnection.getHeaders().put("Authorization", userId);

        final HubProxy hubProxy = hubConnection.createHubProxy("SignalRHub");
        hubProxy.subscribe(this);


        // Work with long polling connections only. Don't deal with server sockets and we
        // don't have WebSockets installed
        SignalRFuture<Void> awaitConnection = hubConnection.start(new LongPollingTransport(new NullLogger()));
        try
        {
            awaitConnection.get();

            Log.d(LOG_TAG, "------ CONNECTED to SignalR -- " + hubConnection.getConnectionId());
        }
        catch (Exception e)
        {
            LogData.e(LOG_TAG, e, LogData.Priority.High);
        }

2 个答案:

答案 0 :(得分:7)

所以我刚创建了一个自定义授权属性并覆盖AuthorizeHubConnection方法以获取对请求的访问权限,并实现了您尝试使用Header进行的逻辑,它似乎正在工作。

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace SignalR.Web.Authorization
{
    public class HeadersAuthAttribute : AuthorizeAttribute
    {
        private const string UserIdHeader = "SRUserId";

        public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
        {
            if (string.IsNullOrEmpty(request.Headers[UserIdHeader]))
            {
                return false;
            }

            return true;
        }
    }
}

集线器

 [HeadersAuth]
    [HubName("messagingHub")]
    public class MessagingHub : Hub
    {

    }

在控制台中产生这个效果(如果图片没有出现,那就是[Failed to load resource: the server responded with a status of 401 (Unauthorized)]):

enter image description here

答案 1 :(得分:3)

实际上,公认的答案是错误的。令人惊讶的是,授权属性应该用于授权(也就是说,您应该使用它来检查请求经过身份验证的用户是否被授权执行所需的操作)。

此外,由于使用了错误的机制,因此您没有设置HttpContext.Current.User.Identity。因此,您没有明确的方法将用户信息传递给您的业务/授权逻辑。

第三,由于SignalR无法在用户和连接之间进行映射,因此您将无法使用Clients.User()方法向特定用户发送消息。

正确的方法是插入OWIN身份验证管道。 Here is an excellent article详细解释和演示如何实现要在OWIN中使用的自定义身份验证。

我不会在这里复制粘贴它,只需遵循它并确保您实现了所有必需的部分:

  • 选项
  • 处理程序
  • 中间件

拥有这些文件后,将它们注册到OWIN:

app.Map("/signalr", map =>
{
   map.UseYourCustomAuthentication();

   var hubConfiguration = new HubConfiguration
   {
       Resolver = GlobalHost.DependencyResolver,
   };

   map.RunSignalR(hubConfiguration);
});