我有三个应用程序。
1)Windows 应用程序
2)Asp.net网页表格
3)ASP.NET MVC
我有一个使用网络服务实现的身份验证和授权系统。以简单的形式,基础表是这样的:
User Table:
Id UserName Password
---------------------------------
Role Table;
Id RoleName
---------------------------------
UserRole
UserId RoleId
---------------------------------
现在我想为这些应用程序实现聊天功能。我的问题是我不知道如何将
SignalR
与我的自定义身份验证集成。考虑一个用户想要向另一个用户发送消息的场景:
public async Task SendMessage(string user1, string user2, string message)
这个方法一眼就能找到。但是我怎样才能防止这种情况:
如果
知道user3
用户名并创建请求并从user1
发送消息到user1
?user2
因为我无法将我的身份验证服务更改为用户 Asp.net Identity 并将其与 SignalR 集成我如何确保登录用户发送消息并且没有人可以进行模拟?
任何人都可以帮助我得到正确的想法和计划吗?
谢谢
您可以实现自定义授权属性,您可以在其中进行必要的检查并拒绝未经授权的用户/接受授权用户。然后,您可以使用自定义授权属性装饰所需的集线器类/方法。
您应该会发现类似问题的答案很有帮助:https://stackoverflow.com/a/14343581/19214431.
您有不同类型的客户端应用程序。所以我建议使用 Bearer token 进行身份验证。客户端应用程序应向发送到服务器的请求添加不记名令牌。我不知道你使用哪个版本的 .net,但使用 .net 核心很容易配置。
在网络应用程序中:
this.connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/chat", { accessTokenFactory: () => this.loginToken })
.build();
在 Windows 应用中
var connection = new HubConnectionBuilder()
.WithUrl("https://example.com/chathub", options =>
{
options.AccessTokenProvider = () => Task.FromResult(_myAccessToken);
})
.Build();
问题是身份服务器应该向客户端提供令牌。我看到你实现了你的身份服务器。在这种情况下,使用 Microsoft.AspNetCore.Identity 和 Entityframework Core 等内置库会让生活变得更轻松。也可以选择使用 IdentityServer。否则,您需要实施和开发为客户端提供访问令牌的自定义 IdentityServer。
不知道你用的是哪个版本的.net 但我试了四天.net core 6.
你可以试试是Context对象
因为获取连接的唯一 ID,由 SignalR 分配。每个连接都有一个连接 ID。
https://learn.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-6.0
我尝试保存 ID 和消息,然后判断 Items 是否有密钥。
您可以尝试使用唯一 ID 确保登录用户发送消息并且没有人可以进行模拟。
ChatHub.cs
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
string getID = Context.ConnectionId;
var getName = Context.User;
await Clients.All.SendAsync("ReceiveMessage", user, message);
checkItems(getID, message);
}
public void checkItems(string key, string value)
{
var data = Context.Items.Where(o => o.Key == key).ToList();
if (data == null)
{
Context.Items.Add(key, value);
int i = Context.Items.Count();
}else{
//you code
}
}
}