安全 WebSocket 验证:连接 .NET 8 和 Flutter 以实现实时通信

在本文中,我们将探讨如何在 .NET 8 后端和 Flutter 跨平台客户端之间实现安全的 WebSocket 身份验证。我们将深入探讨配置 .NET 后端、设置 Flutter 客户端的具体细节,并确保它们之间的通信既安全又高效。

了解 .NET 中的中间件

在深入了解 WebSocket 设置之前,有必要先了解一下什么是 .NET 中的中间件。中间件是组装到应用程序管道中用于处理请求和响应的软件。管道中的每个组件都可以将请求传递给下一个组件或直接处理请求。

在我们的方案中,我们将创建一个自定义的中间件来处理访问令牌,确保我们的 WebSocket 连接得到正确的验证。

在 .NET 8 中实现访问令牌中间件

为了安全地验证 WebSocket 连接,我们需要拦截对 WebSocket 端点(/changesHub)的请求,并将访问令牌附加到请求标头。这可以通过创建自定义中间件来实现:

public class AccessTokenMiddleware
{
    private readonly RequestDelegate _next;
  public AccessTokenMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/changesHub", StringComparison.OrdinalIgnoreCase))
        {
            string accessToken = context.Request.Query["access_token"];
            
            if (!string.IsNullOrEmpty(accessToken))
            {
                context.Request.Headers["Authorization"] = $"Bearer {accessToken}";
            }
        }
        await _next(context);
    }
}
// Extension method to make it easier to add the middleware
public static class AccessTokenMiddlewareExtensions
{
    public static IApplicationBuilder UseAccessTokenMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<AccessTokenMiddleware>();
    }
}

该中间件会检查请求是否以 /changesHub 端点为目标。如果查询字符串中存在 access_token,它就会将其作为 Bearer 令牌添加到授权头中。这对于确保 WebSocket 连接通过身份验证至关重要。

配置 .NET 8 应用程序

对于我们的 .NET 应用程序,我们将使用身份验证附带的 app.MapIdentityApi 模板。按照特定顺序添加中间件对确保身份验证的正常运行非常重要:

app.UseAccessTokenMiddleware();
app.UseAuthentication();
app.UseAuthorization();
  1. app.UseAccessTokenMiddleware():此中间件首先运行,以确保在尝试任何身份验证之前将访问令牌添加到标头中。
  2. app.UseAuthentication():然后,该中间件处理身份验证,检查提供的凭证。
  3. app.UseAuthorization():最后,这个中间件强制执行授权策略,确保经过身份验证的用户具有必要的权限。

有了这些二设置,就可以直接使用hubContext.Clients.User(userId).SendAsync向经过身份验证的用户发送消息。

注册 Hub

要在 WebSocket hub 中使用验证连接,需要映射 hub 并要求授权:

app.MapHub<ChangesHub>( “/changesHub” ).RequireAuthorization();

这将确保只有通过身份验证的用户才能连接到 /changesHub 端点,从而增强应用程序的安全性。

设置 Flutter 客户端

在 Flutter 端,我们需要设置客户端以正确处理 WebSocket 连接。首先,我们将声明一个同时支持 Web 和移动平台的客户端存根:

export 'browser_client.dart' if (dart.library.io) 'io_client.dart';

根据平台的不同,我们将使用 browser_clientio_client。对于 Web 客户端,useCredentials 选项应设置为 true,以确保使用 cookie:

final client = BrowserClient()..withCredentials = true;

对于移动平台,使用io_client

使用 SignalR 处理 WebSocket 身份验证

对于 WebSocket 连接,我们将使用 Flutter 中的 signalr_core 包:

final auth = _httpClientCall.headers['Authorization'];
_hubConnection = HubConnectionBuilder()
    .withUrl(
        '$baseUrl/changesHub',
        HttpConnectionOptions(
          accessTokenFactory: auth == null
              ? null
              : () {
                  return _httpClientCall.handleJsonToken.getJsonToken;
                },
          withCredentials: true,
          client: client,
          logging: (level, message) => log(message),
          customHeaders: auth == null ? null : {'Authorization': auth},
        ))
    .build();

在此设置中

  • accessTokenFactory 为 WebSocket 连接提供令牌(如果有的话)。
  • withCredentials 选项确保随请求发送 cookie。
  • customHeaders 用于在有令牌的情况下添加授权头信息。

如果 _httpClientCall.headers['Authorization']null ,则表明我们是在 Web 上,依靠 cookie 进行身份验证。

监听服务器消息

为了处理来自服务器的消息,我们向 WebSocket 连接添加一个监听器:

_hubConnection.on('ReceiveMessage', (arguments) {
    final user = arguments?[0] as String;
    final message = arguments?[1] as String;
    log('Message from $user: $message');
});

该监听器将记录从服务器收到的消息,证明 WebSocket 连接已成功建立。

正确实施后,此设置允许在 .NET 8 后端和 Flutter 客户端之间建立安全、经过身份验证的 WebSocket 连接。您将能够使用以下方式向特定用户发送实时更新:

hubContext.Clients.User(userId).SendAsync("ReceiveMessage", parameters);

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/im/51794.html

(0)

相关推荐

发表回复

登录后才能评论