首先項目中使用IdentityServer負責項目的登錄認證服務。
在客戶端SignalR配置如下
@inject IHttpContextAccessor httpContextAccessor
@code{
private HubConnection connection;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
if (httpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
{
connection = new HubConnectionBuilder()
.WithUrl("http://localhost:4200/chat", options =>
{
if (httpContextAccessor.HttpContext != null)
{
foreach (var cookie in httpContextAccessor.HttpContext.Request.Cookies)
{
options.Cookies.Add(new Cookie(cookie.Key, cookie.Value, null, "localhost"));
}
}
})
.Build();
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0, 5) * 1000);
await connection.StartAsync();
};
try
{
await connection.StartAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
在這里說明一下,對連接到中心 SignalR 的用戶進行身份驗證有多種方式,具體可以看官方文檔 https://docs.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.1
這里我們使用的是Cookies方式,因為在Blazor應用中,我們使用的是SignalR .Net客戶端,請求並非來自瀏覽器。如果使用的是js的客戶端,使用持有者令牌身份驗證應該是沒問題的。
之前一直試圖使用令牌驗證,但是始終獲取不到身份信息,這里文檔里並沒有交代,感覺是個小坑希望大家可以避免遇到
Cookie身份驗證
在基於瀏覽器的應用中 cookie ,身份驗證允許現有用戶憑據自動流向 SignalR 連接。 使用瀏覽器客戶端時,無需其他配置。 如果用戶登錄到應用,則連接 SignalR 會自動繼承此身份驗證。
Cookie是一種特定於瀏覽器的發送訪問令牌的方法,但非瀏覽器客戶端可以發送這些令牌。 使用 .NET 客戶端時,可以在調用中配置 屬性 Cookies .WithUrl 以提供 cookie 。 但是, cookie 從 .NET 客戶端使用身份驗證需要應用提供 API 來交換 的身份驗證數據 cookie 。
持有者令牌身份驗證
客戶端可以提供訪問令牌,而不是使用 cookie 。 服務器驗證令牌並使用它來標識用戶。 此驗證僅在建立連接時完成。 在連接期間,服務器不會自動重新驗證以檢查令牌吊銷。