c# – 如何使用SignalR(单独的域)进行表单身份验证?

好的,所以我一直在玩SignalR一段时间.我有一个包含以下项目的VS2013解决方案:

>业务项目(包含自定义成员资格提供者的类库)
> Mvc网站(本地IIS – subdomain1.domain.ext)
> SignalR(本地IIS – subdomain2.domain.ext)

这些在本地运行时,使用hosts文件转发域.它们运行在不同的域上,因为我希望SignalR与任何其他项目完全分开运行(因为它也可以通过某些桌面软件,也可能是iOS应用程序访问).

在Mvc网站上,正在运行一个小留言板.包括留言板在内的整个网站都是表格身份验证的背后.我通过SignalR检索电路板的所有消息,使用Javascript在自定义MessageHub上调用GetMessages函数:

 $(function () {
        // Declare a proxy to reference the hub.
        var signalrUrl = SignalrBaseUrl + '/signalr';
        var messageList = $('#messageList');
        var messenger = $.connection.messengerHub;

        messenger.client.addMessage = function (message) {
            addMessageToList(message);
        };

        function init() {
            messenger.server.getAllMessages().done(function (messages) {
                messageList.empty();
                addMessagesToList(messages);
        })
    }

    [...]

    // Start the connection.
    $.connection.hub.url = signalrUrl;
    $.connection.hub.logging = SignalrLogging;
    $.connection.hub.start().done(init);
 })

我希望只有经过身份验证的用户才能访问集线器以及所有集线器.我知道设置Authorize属性(或通过配置强制对所有集线器进行身份验证),我的问题是关于身份验证部分.

那么认证如何正确完成?我相信只要我们在不同的域上(有人可以确认吗?),共享cookie就无法运行.为此,我需要以某种方式使用Mvc网站中创建的Cookie(我猜?)来使用,但我不知道如何将它发送到SignalR以及将它与之比较?或者将用户名和密码发送到SignalR并在那里对businesslayer中的Membership provider进行身份验证?实现这一目标的最佳模式是什么?任何想法将不胜感激.

解决方法:

最后,我通过查看表单身份验证的单点登录技术的一些示例找到了解决方案.基本上我做的是:

将以下内容添加到MVC和SignalR web.config中:

<authentication mode="Forms">
    <forms name="MyCookieName" domain=".domain.nl" cookieless="AutoDetect" loginUrl="My/Login/Url" timeout="525600" />
</authentication>
<machineKey validationKey="12345etc" decryptionKey="cte54321" validation="SHA1" decryption="AES" />

两个项目在主域名domain.nl下运行非常重要(例如subdomain1.domain.com和subdomain2.domain.com).机器密钥用于cookie和票证加密,应在web.configs中设置. (更多信息:http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms)

在mvc项目中,cookie像往常一样在登录后设置:

FormsAuthentication.SetAuthCookie(loginName, true);

我使用chrome开发人员工具检查cookie是否设置正确.出于测试目的,我将以下内容放在我的信号器集线器中,在if语句中放置一个断点:

if (Context.User.Identity.IsAuthenticated)
{                
}

然后用户不为null,并且IsAuthenticated是真的.

最后我补充道

GlobalHost.HubPipeline.RequireAuthentication();

在我的SignalR Startup类中,确保只有经过身份验证的用户才能访问任何集线器.在登录之前,我现在在尝试访问集线器时收到401未授权.登录后,cookie由mvc网站创建,该网站与SignalR共享,可以到达集线器.像魅力一样工作,比我想象的要简单得多!

上一篇:c# – 是否可以将更新“注入”Knockout ViewModel?


下一篇:c# – SignalR“启动请求期间出错.停止连接.“