【问题标题】:Authenticate a .NET Core 2.1 SignalR console client to a web app that uses "Identity as UI"向使用“身份作为 UI”的 Web 应用程序验证 .NET Core 2.1 SignalR 控制台客户端
【发布时间】:2018-06-08 03:02:09
【问题描述】:

使用 .NET Core 2.1 和 VS2017 预览版 2,我创建了一个简单的 Web 服务器,具有“作为 UI 的身份”,如 here 所述,然后在 this 之后添加了一个 SignalR 聊天。

特别是我有:

app.UseAuthentication();
app.UseSignalR((options) => {
    options.MapHub<MyHub>("/hubs/myhub");
});

..

[Authorize]
public class MyHub : Hub

..

"iisSettings": {
  "windowsAuthentication": false,
  "anonymousAuthentication": true,
     "iisExpress": {
     "applicationUrl": "http://localhost:5000",
     "sslPort": 0

我启动带浏览器的调试器,注册用户并登录,然后转到http://localhost:5000/SignalRtest(我的剃须刀页面使用signalr.js)并验证聊天是否正常。

我现在尝试创建一个 .NET Core 控制台应用聊天客户端:

class Program
{
    public static async Task SetupSignalRHubAsync()
    {
        var hubConnection = new HubConnectionBuilder()
                    .WithUrl("http://localhost:5000/hubs/myhub")
                    .Build();

        await hubConnection.StartAsync();
        await hubConnection.SendAsync("Send", "consoleapp");
    }

    public static void Main(string[] args)
    {
        SetupSignalRHubAsync().Wait();
    }
}

我的问题是我不知道如何验证这个客户端?

编辑:

(来自https://github.com/aspnet/SignalR/issues/2455

"之所以能在浏览器中工作,是因为浏览器有一个 Cookie 从您登录时开始,因此它会在您登录时自动发送 SignalR 发出它的请求。在 .NET 中做类似的事情 客户端,您必须在服务器上调用可以设置 cookie,从 HttpClient 中舀出 cookie,然后在 调用 .WithUrl,如下所示:

var loginCookie = /* get the cookie */
var hubConnection = new HubConnectionBuilder()
    .WithUrl("http://localhost:5000/hubs/myhub", options => {
        options.Cookies.Add(loginCookie);
    })
    .Build();

我现在悬赏这个问题,希望得到一个解决方案,展示如何使用“身份作为 UI”的 .NET Core 2.1 Web 应用 SignalR 服务器对 .NET Core 2.1 SignalR 控制台客户端进行身份验证。我需要从服务器获取 cookie,然后将其添加到 SignalR HubConnectionBuilder(现在有一个 WithCookie 方法)。

请注意,我不是在寻找像 IdentityServer 这样的第三方解决方案 谢谢!

【问题讨论】:

    标签: asp.net-core signalr signalr-hub signalr.client asp.net-core-2.1


    【解决方案1】:

    我确实最终让它像这样工作:

    在服务器上我搭建了 Login 脚手架,然后在 Login.cshtml.cs 中添加了

    [AllowAnonymous]
    [IgnoreAntiforgeryToken(Order = 1001)]
    public class LoginModel : PageModel
    

    也就是说我在登录时不需要防伪令牌(无论如何这都没有意义)

    然后客户端代码是这样的:

    HttpClientHandler handler = new HttpClientHandler();
    CookieContainer cookies = new CookieContainer();
    handler.CookieContainer = cookies;
    HttpClient client = new HttpClient(handler);
    
    var uri = new Uri("http://localhost:5000/Identity/Account/Login");
    string jsonInString = "Input.Email=myemail&Input.Password=mypassword&Input.RememberMe=false";
    HttpResponseMessage response = await client.PostAsync(uri, new StringContent(jsonInString, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded"));
    var responseCookies = cookies.GetCookies(uri);
    var authCookie = responseCookies[".AspNetCore.Identity.Application"];
    
    var hubConnection = new HubConnectionBuilder()
            .WithUrl("http://localhost:5000/hubs/myhub", options =>
            {
                options.Cookies.Add(authCookie);
            })
            .Build();
    
    await hubConnection.StartAsync();
    await hubConnection.SendAsync("Send", "hello!");
    

    (当然密码会在部署的其他地方)

    【讨论】:

    • 对于任何研究此问题的人,虽然@kofifus 提供的答案足以标记为正确,但您可能应该避免使用 Cookie。 Cookie 对 API 请求很有用,但如果您使用 SignalR,尤其是使用 .NET SignalR 客户端(或者实际上,任何其他非 JS/浏览器客户端),您应该查看 Bearer token authentication - MS Docs here
    • @eja:问题在于,与简单的登录相比,Bearer 令牌身份验证是一个庞大的基础架构设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多