基本身份验证重定向到登录页面,而不是返回身份验证质询

时间:2015-01-08 01:53:09

标签: c# signalr owin katana

除了标准的现成cookie /表单身份验证之外,我还需要支持SignalR上的HTTPS基本身份验证。 SignalR在混合MVC / WebApi站点的上下文中运行。

在将各个部分放在一起后如何实现这一点,我在服务器上使用了ThinkTecture.IdentityModel.Owin.BasicAuthentication库,如下所示:

app.Map("/basicauth", map =>
{
    map.UseBasicAuthentication("realm", ValidateUser);
    map.MapSignalR<AuthenticatedEchoConnection>("/echo");
    map.MapSignalR();
});

但是我总是得到一个HTTP 302响应,重定向到MVC站点的Login页面,而不是返回一个挑战。为了更好地调试这个,我快速推出了自己的简单OWIN中间件进行基本身份验证,并得到了相同的结果。使用这样的简单映射进行进一步测试:

app.Map("/test", map =>
    {
        map.Use((context, next) =>
            {
                // context.Response.StatusCode = 401;
                context.Response.Write("Hello World!");
                return Task.FromResult(0);
            });

揭示了一个简单的&#34; Hello World&#34;响应正常返回。但是当我注释掉将响应代码设置为401的行时,我再次重定向到“登录”页面。我不明白这种行为......为什么我的MVC网站在这里涉及而不是401响应被返回?我该如何防止这种情况?

对于OWIN,除了上面的特殊/basicauth映射之外,我在定义的启动方法中只有顶级SignalR映射,它应该继续适用于所有经过cookie验证的调用:

app.MapSignalR();

我没有为OWIN配置任何其他内容。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

好的,我找到了解决此问题的方法。第一部分是从第一个样本中删除map.MapSignalR<AuthenticatedEchoConnection>("/echo"); - 这是没有必要的,由于某种原因我没有发现它阻止SignalR正常工作。

第二部分以及实际问题的解决方法是,在客户端中,我还使用第一个请求发送凭据,而不是等待挑战。因此,401永远不会发生,因此没有重定向到登录页面。这对我来说已经足够了。

因此,在客户端中,解决方法是不要像这样使用NetworkCredential:

connection.Credentials = new NetworkCredential(username, password);

相反,请自行添加Authorization标头,以便它已包含在第一个请求中:

string creds = string.format("{0}:{1}", username, password);
string encodedCreds = Convert.ToBase64String(Encoding.Utf8.GetBytes(creds));
connection.Headers.Add("Authorization", "Basic " + encodedCreds);

此外,我发现,对于OWIN,这个问题似乎是一个更普遍的问题,不仅与SignalR甚至Basic Auth一起使用时相关:

http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

因此,通过对基本认证模块的一些修改,还应该可以防止这种重定向。我可能会对此进行调查,并在完成后更新此帖。