问题
Using .NET Core 2.1 & VS2017 preview 2 I created a simple web server with "Identity as UI" as explained here and then added a SignalR chat following this.
In particular I have:
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
I start the debugger which brings the browser, register a user and log in, then go to http://localhost:5000/SignalRtest (my razor page that uses signalr.js) and verify the chat works fine.
I now try to create a .NET Core console app chat client:
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();
}
}
My issue is I don't know how to authenticate this client ?
EDIT:
(from https://github.com/aspnet/SignalR/issues/2455)
"The reason it works in the browser is because the browser has a Cookie from when you logged in, so it sends it automatically when SignalR makes it's requests. To do something similar in the .NET client you'll have to call a REST API on your server that can set the cookie, scoop the cookie up from HttpClient and then provide it in the call to .WithUrl, like so:
var loginCookie = /* get the cookie */ var hubConnection = new HubConnectionBuilder() .WithUrl("http://localhost:5000/hubs/myhub", options => { options.Cookies.Add(loginCookie); }) .Build();
I now put a bounty on this question, hoping to get a solution showing how to authenticate the .NET Core 2.1 SignalR console client with a .NET Core 2.1 web app SignalR server that uses "Identity as UI". I need to get the cookie from the server and then add it to SignalR HubConnectionBuilder (which now have a WithCookie method).
Note that I am not looking for a third-party solutions like IdentityServer Thanks!
回答1:
I did ended up getting this to work like this:
On the server I scaffolded Login and then in Login.cshtml.cs added
[AllowAnonymous]
[IgnoreAntiforgeryToken(Order = 1001)]
public class LoginModel : PageModel
That is I do not require the anti forgery token on login (which doesn't make sense anyway)
The client code is then like this:
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!");
(of course password will be elsewhere in deployment)
来源:https://stackoverflow.com/questions/50752724/authenticate-a-net-core-2-1-signalr-console-client-to-a-web-app-that-uses-iden