【Azure 服务总线】使用Azure Service Bus 时,出现证书错误: 所使用的证书具有无法验证的信任链 - LuBu0505/My-Code GitHub Wiki

问题描述

在Azure中连接 Service Bus 服务发送消息时发生证书错误,抛出证书异常消息: image

The X.509 certificate CN=servicebus.chinacloudapi.cn, OU=Azure, O=Shanghai Blue Cloud Technology Co Ltd, L=Shanghai, S=Shanghai, C=CN is not in the trusted people store.  

The X.509 certificate CN=servicebus.chinacloudapi.cn, OU=Azure, O=Shanghai Blue Cloud Technology Co Ltd, L=Shanghai, S=Shanghai, C=CN chain building failed. 

The certificate that was used has a trust chain that cannot be verified. 

Replace the certificate or change the certificateValidationMode. 

A certificate chain could not be built to a trusted root authority.

问题解答

如果在连接Service Bus的代码中不对 ConnectivityMode 做预先设置,Service Bus SDK默认使用了 AutoDetect 模式 连接 Service Bus 服务。 

AutoDetect 会优先使用 TCP 连接模式,由于 TCP 连接模式也是加密的,所以客户端需要首先验证 service bus 服务器证书 CN = servicebus.chinacloudapi.cn 的有效性,证书链信息在 SSL 协议的 server hello 消息中返回。

如果证书链中的某些中间证书没有安装在 web 应用实例上,web 应用需要发起额外的请求到 CA 服务器上下载中间证书并安装。当下面任何一种情况发生时,web 应用无法对 service bus 服务器证书建立信任的证书链,随后会报告上述的证书错误:

  1. 运行Service Bus客户端代码的实例和 CA 服务器之间存在网络问题,导致无法下载证书.
  2. 运行Service Bus客户端代码的实例无法成功安装证书,如权限问题等。

推荐在代码中强制使用 HTTPS 模式连接 Service Bus 服务,HTTPS 模式有不同的设计,因此会很大程度上避免上述错误发生。

示例代码如下:

string connectionString = "servicebus connection string";

ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Https var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); if (!namespaceManager.TopicExists("TestTopic"))
{
    namespaceManager.CreateTopic("TestTopic");
}

TopicClient client = TopicClient.CreateFromConnectionString(connectionString, "TestTopic");

BrokeredMessage testMessage = new BrokeredMessage("test message");
testMessage.MessageId = "message id";

client.Send(testMessage);

另外,以上代码代码使用很旧的Service Bus SDK,强烈建议升级SDK代码,使用新的AMQP协议连接Service Bus

using Azure.Messaging.ServiceBus;

// the client that owns the connection and can be used to create senders and receivers
ServiceBusClient client;
// The Service Bus client types are safe to cache and use as a singleton for the lifetime
// of the application, which is best practice when messages are being published or read
// regularly.
//
// set the transport type to AmqpWebSockets so that the ServiceBusClient uses the port 443. 
// If you use the default AmqpTcp, you will need to make sure that the ports 5671 and 5672 are open

// TODO: Replace the <NAMESPACE-CONNECTION-STRING> and <QUEUE-NAME> placeholders
var clientOptions = new ServiceBusClientOptions()
{ 
    TransportType = ServiceBusTransportType.AmqpWebSockets
};
client = new ServiceBusClient("<NAMESPACE-CONNECTION-STRING>", clientOptions); 

参考文档

**添加将消息发送到队列的代码 ** : https://learn.microsoft.com/zh-cn/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues?tabs=passwordless#add-code-to-send-messages-to-the-queue 

当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

分类: 【Azure 服务总线】

标签: Azure Service Bus所使用的证书具有无法验证的信任链

⚠️ **GitHub.com Fallback** ⚠️