You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 6与RabbitMQ SSL/TLS通信IIS部署异常求助

排查ASP.NET Core 6与RabbitMQ SSL/TLS通信部署问题

问题现象

  • 相同代码在控制台应用中可正常通信
  • VS2022本地F5运行ASP.NET Core项目正常
  • 部署到IIS服务器后出现SSL认证失败报错

相关环境信息

  • 证书存放于wwwroot文件夹
  • 文件夹已设置Everyone权限
  • 证书为自签名私有证书

核心代码

ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "129001-01";
factory.RequestedHeartbeat = heartbeat;
factory.AutomaticRecoveryEnabled = true;
factory.UserName = "";
factory.Password = "";
factory.VirtualHost = "/";
factory.AuthMechanisms = new IAuthMechanismFactory[] { new ExternalMechanismFactory() };

// SSL Certification
X509Certificate2Collection certCollection = new X509Certificate2Collection();
string certificateName = "CART1290213.A000.pfx";
           
X509Certificate2 certificate = new X509Certificate2(certificatePath + certificateName, certificatePassword);
certCollection.Add(certificate);

factory.Ssl.Certs = certCollection;
factory.Ssl.Enabled = true;
factory.Ssl.ServerName = "129001-01";
factory.Ssl.Version = SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
factory.Ssl.AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors;

IConnection connection = factory.CreateConnection();
IModel channel = connection.CreateModel();

抛出异常

'RabbitMQ.Client.Exceptions.BrokerUnreachableException' in RabbitMQ.Client.dll
EXCEPTIONRabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable

System.AggregateException: One or more errors occurred. (Authentication failed, see inner exception.)

System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.

System.ComponentModel.Win32Exception (0x8009030D): The credentials supplied to the package were not recognized

at System.Net.SSPIWrapper.AcquireCredentialsHandle(ISSPIInterface secModule, String package, CredentialUse intent, SCH_CREDENTIALS* scc)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCH_CREDENTIALS* secureCredential)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandleSchCredentials(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
--- End of inner exception stack trace ---
at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
at System.Net.Security.SecureChannel.GenerateToken(ReadOnlySpan1 inputBuffer, Byte[]& output) at System.Net.Security.SecureChannel.NextMessage(ReadOnlySpan1 incomingBuffer)
at System.Net.Security.SslStream.ProcessBlob(Int32 frameSize)
at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at RabbitMQ.Client.Impl.SslHelper.<>c__DisplayClass2_0.b__0(SslOption opts)
at RabbitMQ.Client.Impl.SslHelper.TcpUpgrade(Stream tcpStream, SslOption options)
at RabbitMQ.Client.Impl.SocketFrameHandler..ctor(AmqpTcpEndpoint endpoint, Func2 socketFactory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout) at RabbitMQ.Client.Framing.Impl.IProtocolExtensions.CreateFrameHandler(IProtocol protocol, AmqpTcpEndpoint endpoint, ArrayPool1 pool, Func2 socketFactory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout) at RabbitMQ.Client.ConnectionFactory.CreateFrameHandler(AmqpTcpEndpoint endpoint) at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func2 selector)
--- End of inner exception stack trace ---
at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector)
at RabbitMQ.Client.Framing.Impl.AutorecoveringConnection.Init(IEndpointResolver endpoints)
at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
--- End of inner exception stack trace ---
at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
at RabbitMQ.Client.ConnectionFactory.CreateConnection(String clientProvidedName)
at RabbitMQ.Client.ConnectionFactory.CreateConnection()
at AdvancedConnector.MVC.Models.AdvancedConnector.ConnectRabbitMQ() in C:\Bordel\AdvancedConnector.NET\AdvancedConnector.MVC\Models\AdvancedConnector.cs:line 62

Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor: Error: The view 'StartRabbitMq' was not found.
Searched locations: /Views/Home/StartRabbitMq.cshtml, /Views/Shared/StartRabbitMq.cshtml

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware: Error: An unhandled exception has occurred while executing the request.

System.InvalidOperationException: The view 'StartRabbitMq' was not found.
The following locations were searched:
/Views/Home/StartRabbitMq.cshtml
/Views/Shared/StartRabbitMq.cshtml

at Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult.EnsureSuccessful(IEnumerable`1 originalLocations)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
at Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)

已尝试操作

  • 修改文件夹权限
  • 更换证书存储路径
  • 调整认证凭据
  • 换用不同IIS服务器

解决建议

1. 修复证书加载权限与存储方式

IIS应用池身份可能无法读取PFX证书的私钥,即使文件夹有Everyone权限,私钥权限需单独配置:

  • 加载证书时添加X509KeyStorageFlags参数,将私钥存储在机器级别:
    X509Certificate2 certificate = new X509Certificate2(
        Path.Combine(certificatePath, certificateName), 
        certificatePassword,
        X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable
    );
    
  • 或者将证书导入到本地计算机-个人存储区,然后给应用池身份(如IIS AppPool\你的应用池名称)授予私钥读取权限:
    1. 打开certlm.msc,找到导入的证书
    2. 右键→所有任务→管理私钥
    3. 添加应用池身份,授予读取权限

2. 验证外部认证机制配置

你使用了ExternalMechanismFactory进行证书认证,需确保RabbitMQ服务器端:

  • 启用了rabbitmq_auth_mechanism_ssl插件(执行rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl)
  • 配置文件中auth_mechanisms包含EXTERNAL
  • ssl_options中指定了信任的CA证书(与客户端自签名证书的CA一致)

3. 调整SSL协议与服务器名称匹配

  • 尝试缩小SSL协议范围,保留主流版本:
    factory.Ssl.Version = SslProtocols.Tls12 | SslProtocols.Tls13;
    
  • 确认factory.Ssl.ServerName与RabbitMQ服务器证书的CN或SAN字段完全匹配,即使设置了忽略名称不匹配的策略,某些环境下仍可能导致认证失败

4. 排查应用池身份权限

临时将应用池身份改为LocalSystem测试,如果能正常连接,说明是身份权限问题,再换回专用身份并配置证书和文件的相应权限

内容的提问来源于stack exchange,提问作者saman5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:20:41