具有自定义身份验证和授权的 SignalR

问题描述 投票:0回答:3

我有三个应用程序。

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 集成我如何确保登录用户发送消息并且没有人可以进行模拟?

任何人都可以帮助我得到正确的想法和计划吗?

谢谢

c# asp.net asp.net-core signalr signalr-hub
3个回答
1
投票

您可以实现自定义授权属性,您可以在其中进行必要的检查并拒绝未经授权的用户/接受授权用户。然后,您可以使用自定义授权属性装饰所需的集线器类/方法。

您应该会发现类似问题的答案很有帮助:https://stackoverflow.com/a/14343581/19214431.


1
投票

您有不同类型的客户端应用程序。所以我建议使用 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。

ASP.NET Core SignalR 中的身份验证和授权

使用 IdentityServer

在 C# .NET 中创建和验证 JWT 令牌


0
投票

不知道你用的是哪个版本的.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
            }


        }

    }
© www.soinside.com 2019 - 2024. All rights reserved.