基于事件驱动架构构建微服务第19部分:使用 SignalR 和 Azure Active Directory 构建和保护实时通信...

本文主要是介绍基于事件驱动架构构建微服务第19部分:使用 SignalR 和 Azure Active Directory 构建和保护实时通信...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:https://logcorner.com/building-micro-services-through-event-driven-architecture-part19-building-and-securing-real-time-communications-using-signalr-and-azure-active-directory/

命令 HTTP API 将事件存储到事件存储,但不直接将它们发布到 Kafka 服务总线。可以考虑这种情况,但我不希望命令 API 也充当生产者。

另一个原因是前端SPA应该收到推送通知。应该通知它发布的命令已成功。

所以我需要一个像SignalR这样的通知系统。

使用场景如下:

  • 前端 SPA 启动并订阅 SignalR 组(主题)

  • 前端 SPA 将数据发布到命令 HTTP API

  • 命令 HTTP API 将从post/put/delete请求中接收的数据转换为事件,并将这些事件存储到事件存储中

  • 命令 HTTP API 将通知推送到 SignalR 组(主题)

  • 订阅 SignalR 组的生产者服务接收通知,然后将事件发布到 Kafka 服务总线

  • 订阅 Kafka 服务总线的使用者从 Kafka 服务总线接收事件,然后构建一个读取模型并将其存储到非 SQL 数据库(Elasticsearch)并向 SignalR 组发送通知

  • 前端 SPA 会收到 Elasticsearch 索引已更新的通知,然后刷新视图。

因此,推送通知系统在此体系结构中起着至关重要的作用。

如果架构的某个部分出现故障(SignalR Hub、Kafka、database、API)会发生什么?我们将在以后的教程中看到它。

在本教程中,我将演示如何构建 SignalR Hub 通知系统,并使用标识提供者通过使用 Azure AD B2C 启用 Oauth2 和 OpenID Connect 来保护 SignalR Hub 通知系统。

Azure Active Directory B2C 提供企业到客户的标识即服务。客户使用其首选的社交、企业或本地帐户标识来获取对应用程序和 API 的单一登录访问权限。

有关 Azure AD B2C 的更多信息,请参阅什么是 Azure Active Directory B2C?

Azure Active Directory B2C

若要将 Azure AD B2C 设置为标识提供者,我需要创建一个与 Azure AD 租户不同的 B2C 租户。

Azure AD B2C 是独立于 Azure Active Directory (Azure AD) 的服务。它基于与 Azure AD 相同的技术构建,但用途不同 - 允许企业构建面向客户的应用程序,然后允许任何人注册这些应用程序,而对用户帐户没有限制。

有关 Azure AD 的更多信息,请参阅什么是 Azure Active Directory?

构建 SignalR Hub 通知

ASP.NET Core SignalR 是一个开源库,可简化向应用程序添加实时Web功能的过程。实时 Web 功能使服务器端代码能够立即将内容推送到客户端。

https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?WT.mc_id=DOP-MVP-5003013

要构建 SignalR Hub ,您应该定义一个从 Hub 继承的类,如下所示:

using Microsoft.AspNetCore.SignalR;namespace SignalRChat.Hubs
{public class ChatHub : Hub{public async Task SendMessage(string user, string message){await Clients.All.SendAsync(“ReceiveMessage”, user, message);}}
}

要向所有连接的客户端发送消息,您应该使用SendMessage功能并接收消息,连接的客户端应侦听接收消息

您可以使用以下链接开始使用 SignalR:https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio

SendMessage和ReisterMessage作为字符串使用和调用,所以我不会以相同的方式继续,而是使用强类型的方式

所以我创建了一个IHubInvoker接口来调用Hub:

  • 发布 :将 T 类型的消息发布到中心

  • 发布到主题 :将特定主题的 T 类型消息发布到中心

  • 订阅 :订阅主题

  • 取消订阅 :取消订阅主题

d1761e47dc347b07a871e85b37740984.png

我创建了一个 IHubNotifier 接口来侦听来自集线器的消息。

52f568fe7d0e6d669cf004c73425a553.png

SignalR Hub 应该继承自 Hub<IHubNotifier>、IHubInvoker

f1da1df36335d148d2c2e4460398e465.png

在 startup.cs ( configure 方法) 类将 endpoints 与连接相关联。

852b476770313c9d73196edb941d1563.png

我创建了一个 ISignalRPublisher 接口来订阅主题或将消息发布到中心。

5c166c5e275c42fdcdafc56c490cba39.png

所以要订阅一个主题,我应该调用 nameof(IHubInvoker.Subscribe) ,要发布一个主题,我应该调用nameof(IHubInvoker.PublishToTopic)

cce9dc2d6a3877487c5fe45dc62d8305.png

我创建了一个 ISignalRNotifier 接口来开始客户端连接,停止连接并收听消息

7055d4fdc12e110b6438344df1c9b90e.png

因此,为了侦听和处理发送到中心的消息,我注册了一个处理程序,当调用具有指定方法名称的中心方法时,将调用该处理程序:nameof(IHubNotifier.OnPublish)

2007cf1d816f200cb902c6716805d1fd.png

ISignalRNotifier 应按如下方式使用

public interface ISignalRNotifier
{event Action<string, object> ReceivedOnPublishToTopic;Task StartAsync();Task OnPublish();Task OnPublish(string topic);Task StopAsync();
}

0c9f802ee54bcaf9edd4372e6437f287.png

要将消息发布到 hub,我应该使用 ISignalRPublisher 接口。如果断开连接的客户端尝试向中心发送消息,在发送消息之前会自动连接它

a3973eb6daf1f0b04061e1aeb33bf2c8.png

保护 SignalR HUB

若要保护SignalR HUB,需要在 Azure AD B2C 租户中注册应用程序,公开终结点

Azure AD B2C 应用程序注册

转到租户并单击"应用注册"并相应地填写表单:提供应用程序名称、支持的帐户类型。在这里,我不需要重定向URI,因为它是一个Web api。

a3467a9dbd55dbd1cdd93348fd94d22b.png

单击"公开 API"并设置应用程序 ID URI(在本例中为,https://workshopb2clogcorner.onmicrosoft.com/signalr/hub)

a779f00a908dd6207a225fb99734d52d.png

配置 SignalR HUB

打开 startup.cs 类并添加以下内容以注册身份验证服务所需的服务,并使用 Microsoft 标识平台保护hub

3ab19066819c879a79a65d36cfcaf077.png

打开appsettings.Development.json 并添加如下内容

将 [ClientID] 替换为您注册的应用程序的标识符,将 [TenantName] 替换为您的租户名称(在我的案例 workshopb2clogcorner 中)。

用户流B2C_1_SignUpIn、B2C_1_PasswordReset和B2C_1_ProfileEdit已在第16部分中配置:https://logcorner.com/building-micro-services-through-event-driven-architecture-part16-azure-active-directory-b2c/

3d32728b70c5dca9333b081acf1587ca.png

要启用身份验证,请使用标志"isAuthenticationEnabled":在 appSettings.json 文件中为 true。

要禁用身份验证,请使用标志"isAuthenticationEnabled":在 appSettings.json 文件中为 false。

在 startup.cs 类中,它的管理方式如下:

bool.TryParse(Configuration[“isAuthenticationEnabled”], out var isAuthenticationEnabled);
if (!isAuthenticationEnabled)
{endpoints.MapHub<LogCornerHub<object>>(“/logcornerhub”);
}
else
{endpoints.MapHub<LogCornerHub<object>>(“/logcornerhub”).RequireAuthorization();
}

测试

运行应用程序并导航到 http://localhost:5000/logcornerhub 或者 https://localhost:5001/logcornerhub

6f9d94e899d5f2b5934534c66d026422.png

http://localhost:5000/logcornerhub

e6937c48463a129d9bcd5143b0cea036.png

https://localhost:5001/logcornerhub

fe5992193a7142969db6e617f3394da0.png

可以看到,hub 已准备好进行客户端连接

代码源可在此处获得:

https://github.com/logcorner/LogCorner.EduSync.Notification.Server/tree/develop

这篇关于基于事件驱动架构构建微服务第19部分:使用 SignalR 和 Azure Active Directory 构建和保护实时通信...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/352026

相关文章

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Python基础语法中defaultdict的使用小结

《Python基础语法中defaultdict的使用小结》Python的defaultdict是collections模块中提供的一种特殊的字典类型,它与普通的字典(dict)有着相似的功能,本文主要... 目录示例1示例2python的defaultdict是collections模块中提供的一种特殊的字

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro