MassTransit 8升级:消息加密与System.Text.Json序列化适配疑问
MassTransit 8升级:System.Text.Json序列化下的消息加密方案
关于MassTransit.Newtonsoft加密的适配性
MassTransit.Newtonsoft包中的消息加密逻辑仅适配Newtonsoft.Json序列化器,它是针对Newtonsoft的序列化流程设计的,和System.Text.Json的序列化机制不兼容,无法直接用于默认的System.Text.Json序列化场景。
System.Text.Json序列化下的消息加密实现方案
如果想在MassTransit 8默认的System.Text.Json序列化下实现消息加密,可以通过以下两种方式实现:
1. 自定义System.Text.Json转换器
针对需要加密的消息类型或敏感字段,实现JsonConverter,在序列化/反序列化过程中完成加解密:
- 创建自定义转换器,在
Write方法中加密内容,Read方法中解密内容 - 配置MassTransit使用System.Text.Json时添加该转换器
示例代码:
// 自定义加密转换器 public class EncryptedMessageConverter : JsonConverter<YourMessageType> { private readonly ISecureKeyProvider _keyProvider; public EncryptedMessageConverter(ISecureKeyProvider keyProvider) { _keyProvider = keyProvider; } public override YourMessageType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var encryptedJson = reader.GetString(); var decryptedJson = _keyProvider.Decrypt(encryptedJson); return JsonSerializer.Deserialize<YourMessageType>(decryptedJson, options); } public override void Write(Utf8JsonWriter writer, YourMessageType value, JsonSerializerOptions options) { var json = JsonSerializer.Serialize(value, options); var encryptedJson = _keyProvider.Encrypt(json); writer.WriteStringValue(encryptedJson); } } // MassTransit配置中添加转换器 configurator.UseSystemTextJson(options => { options.JsonSerializerOptions.Converters.Add(new EncryptedMessageConverter(keyProvider)); });
2. 自定义MassTransit消息中间件
利用MassTransit的发送/接收中间件,在消息序列化前后对字节流进行加解密,这种方式不依赖具体序列化器,通用性更强:
发送端加密中间件
public class EncryptionSendFilter : IFilter<SendContext> { private readonly ISecureKeyProvider _keyProvider; public EncryptionSendFilter(ISecureKeyProvider keyProvider) { _keyProvider = keyProvider; } public async Task Send(SendContext context, IPipe<SendContext> next) { // 读取原始序列化后的字节并加密 var originalBody = await context.Body.ReadToEndAsync(); var encryptedBody = _keyProvider.Encrypt(originalBody); // 替换为加密后的字节流 context.Body = new MemoryStream(encryptedBody); await next.Send(context); } public void Probe(ProbeContext context) { } }
接收端解密中间件
public class EncryptionReceiveFilter : IFilter<ReceiveContext> { private readonly ISecureKeyProvider _keyProvider; public EncryptionReceiveFilter(ISecureKeyProvider keyProvider) { _keyProvider = keyProvider; } public async Task Send(ReceiveContext context, IPipe<ReceiveContext> next) { // 读取加密的字节流并解密 var encryptedBody = await context.Body.ReadToEndAsync(); var decryptedBody = _keyProvider.Decrypt(encryptedBody); // 替换为解密后的字节流 context.Body = new MemoryStream(decryptedBody); await next.Send(context); } public void Probe(ProbeContext context) { } }
注册中间件
// 注册发送端中间件 configurator.AddSendFilter(() => new EncryptionSendFilter(keyProvider)); // 注册接收端中间件 configurator.AddReceiveFilter(() => new EncryptionReceiveFilter(keyProvider));
注意事项
- 确保发送端和接收端使用完全一致的加密算法、密钥管理策略,避免无法解密
- 使用Azure Service Bus作为代理时,无需修改服务端配置,所有加解密逻辑在客户端完成
- 若仅需加密敏感字段,优先选择自定义转换器方案,减少性能开销;若需加密整个消息体,中间件方案更合适
内容的提问来源于stack exchange,提问作者dotnetdeveloper
相关产品推荐
相关产品推荐

