部署ASP.NET Core 7 API到Azure App Service时的MongoDB认证问题
我使用ASP.NET Core 7和MongoDB开发API,已在MongoDB Atlas上配置数据库并通过连接字符串访问。本地环境下一切正常,也能通过MongoDB Compass连接数据库,但将API部署到Azure App Service后,发起请求时遇到以下错误:
Erro ao ler usuários: A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode : Primary } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "ReplicaSet", Type : "ReplicaSet", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/ac-qh7znw4-shard-00-00.v0kzanp.mongodb.net:27017" }", EndPoint: "Unspecified/ac-qh7znw4-shard-00-00.v0kzanp.mongodb.net:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
--- End of inner exception stack trace ---
at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, ReadOnlySpan1 input, Byte[]& sendBuf, Int32& sendCount) at System.Net.Security.SslStreamPal.HandshakeInternal(SafeDeleteSslContext& context, ReadOnlySpan1 inputBuffer, Byte[]& outputBuffer, SslAuthenticationOptions sslAuthenticationOptions, SelectClientCertificate clientCertificateSelectionCallback)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
at MongoDB.Driver.Core.Connections.SslStreamFactory.CreateStream(EndPoint endPoint, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.Open(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.ServerMonitor.InitializeConnection(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.ServerMonitor.Heartbeat(CancellationToken cancellationToken)", LastHeartbeatTimestamp: "2023-11-09T19:10:01.1718870Z", LastUpdateTimestamp: "2023-11-09T19:10:01.1718873Z" }, { ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/ac-qh7znw4-shard-00-01.v0kzanp.mongodb.net:27017" }", EndPoint: "Unspecified/ac-qh7znw4-shard-00-01.v0kzanp.mongodb.net:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
--- End of inner exception stack trace ---
at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, ReadOnlySpan1 input, Byte[]& sendBuf, Int32& sendCount) at System.Net.Security.SslStreamPal.HandshakeInternal(SafeDeleteSslContext& context, ReadOnlySpan1 inputBuffer, Byte[]& outputBuffer, SslAuthenticationOptions sslAuthenticationOptions, SelectClientCertificate clientCertificateSelectionCallback)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
at MongoDB.Driver.Core.Connections.SslStreamFactory.CreateStream(EndPoint endPoint, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.Open(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.ServerMonitor.InitializeConnection(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.ServerMonitor.Heartbeat(CancellationToken cancellationToken)", LastHeartbeatTimestamp: "2023-11-09T19:10:01.1794022Z", LastUpdateTimestamp: "2023-11-09T19:10:01.1794023Z" }, { ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/ac-qh7znw4-shard-00-02.v0kzanp.mongodb.net:27017" }", EndPoint: "Unspecified/ac-qh7znw4-shard-00-02.v0kzanp.mongodb.net:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
--- End of inner exception stack trace ---
at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, ReadOnlySpan1 input, Byte[]& sendBuf, Int32& sendCount) at System.Net.Security.SslStreamPal.HandshakeInternal(SafeDeleteSslContext& context, ReadOnlySpan1 inputBuffer, Byte[]& outputBuffer, SslAuthenticationOptions sslAuthenticationOptions, SelectClientCertificate clientCertificateSelectionCallback)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
at MongoDB.Driver.Core.Connections.SslStreamFactory.CreateStream(EndPoint endPoint, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.Open(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.ServerMonitor.InitializeConnection(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.ServerMonitor.Heartbeat(CancellationToken cancellationToken)", LastHeartbeatTimestamp: "2023-11-09T19:10:01.1893947Z", LastUpdateTimestamp: "2023-11-09T19:10:01.1893949Z" }] }.
我的连接字符串及实现代码如下:
"DatabaseSettings": { "ConnectionString": "mongodb+srv://myuser:password@host/database?authSource=admin", "DatabaseName": "Database", "Collections": { "Usuarios": "Usuarios", "Imoveis": "Imoveis", "Imagens": "Imagens", "Avatares": "Avatares" } },
namespace IMobi.Cofigurations; public class MongoDbSettings : IMongoDbSettings { public string ConnectionString { get; set; } = string.Empty; public string DatabaseName { get; set; } = string.Empty; public string CollectionName { get; set; } = string.Empty; }
builder.Services.Configure<MongoDbSettings>( builder.Configuration.GetSection("DatabaseSettings"));
这似乎是数据库认证问题,但我无法理解错误的根本原因,恳请提供解决该问题的思路或建议。
解决思路与建议
- 检查MongoDB Atlas的IP白名单:确认Azure App Service的出站IP地址已添加到MongoDB Atlas的IP访问列表中。本地能连接但Azure不能,大概率是Azure的服务器IP未被授权,导致连接被拒绝进而触发SSL握手错误。
- 确认连接字符串配置:在Azure App Service的「配置-应用设置」中直接配置
DatabaseSettings__ConnectionString,避免部署时配置文件可能出现的遗漏或格式问题,确保连接字符串和本地完全一致。 - 强制指定TLS版本:MongoDB Atlas要求使用TLS 1.2及以上版本,可在连接字符串末尾添加
&tls=TLS1_2参数,强制客户端使用兼容的TLS版本。同时可在Azure App Service的「配置-TLS/SSL设置」中启用TLS 1.2+。 - 更新MongoDB驱动版本:检查项目中
MongoDB.Driver包的版本,更新到最新稳定版,解决可能存在的TLS协议兼容性问题。 - 排查SSL证书验证:临时在连接字符串中添加
&sslValidateCertificates=false(仅用于测试,生产环境禁用),若能连接则说明是证书信任问题,需确认Azure App Service是否信任MongoDB Atlas的SSL证书。 - 查看Azure应用日志:启用Azure App Service的应用日志记录,获取更详细的连接过程日志,定位是否存在网络层面的限制或其他未捕获的异常。
内容的提问来源于stack exchange,提问作者Rafael Jordão

