AX 2012调用HTTPS API时无法创建SSL/TLS安全通道问题求助
Dynamics AX 2012调用HTTPS API报SSL/TLS安全通道创建失败问题解决
问题背景
在Dynamics AX 2012中通过HTTPS URL调用外部API时,抛出错误:
The request was aborted: Could not create SSL/TLS secure channel
相同代码在Dynamics 365环境中可正常运行,已在代码中添加以下设置:
System.Net.ServicePointManager::set_Expect100Continue(true); System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12);
完整报错代码
str destinationUrl,requestJson, responseJson; System.Net.HttpWebRequest request; System.Net.HttpWebResponse response = new System.Net.HttpWebResponse(); CLRObject clrObj; System.Byte[] bytes; System.Text.Encoding utf8; System.IO.Stream requestStream, responseStream; System.IO.StreamReader streamReader; System.Exception ex; System.Net.WebHeaderCollection httpHeader; System.Net.ServicePoint servicePt; System.Net.ServicePointManager ServicePointManager; str byteStr; System.Byte[] byteArray; System.IO.Stream stream; System.IO.Stream dataStream; int secProtocol; boolean ssl3,tls,tls11,tls12,tls13; destinationUrl = 'https://...'; requestJson = @'MyJsonData'; try { new InteropPermission(InteropKind::ClrInterop).assert(); httpHeader = new System.Net.WebHeaderCollection(); clrObj = System.Net.WebRequest::Create(destinationUrl); request = clrObj; utf8 = System.Text.Encoding::get_UTF8(); bytes = utf8.GetBytes(requestJson); request.set_Method("POST"); httpHeader.Add("Client-Id","5..."); httpHeader.Add("Secret-Key","..."); httpHeader.Add("Cookie", "..."); request.set_Headers(httpHeader); request.set_ContentType('application/json'); request.set_ContentLength(bytes.get_Length()); System.Net.ServicePointManager::set_Expect100Continue(true); System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12); secProtocol = System.Net.ServicePointManager::get_SecurityProtocol(); ssl3 = secProtocol == enum2int(System.Net.SecurityProtocolType::Ssl3); tls = secProtocol == enum2int(System.Net.SecurityProtocolType::Tls); tls11 = secProtocol == enum2int(System.Net.SecurityProtocolType::Tls11); tls12 = secProtocol == enum2int(System.Net.SecurityProtocolType::Tls12); tls13 = secProtocol == 12288; info(strFmt("SSL3 enabled: '%1' | TLS enabled: '%2' | TLS1.1 enabled: '%3' | TLS1.2 enabled: '%4' | TLS1.3 enabled: '%5'", ssl3, tls, tls11, tls12, tls13)); requestStream = request.GetRequestStream(); requestStream.Write(bytes, 0, bytes.get_Length()); response = request.GetResponse(); responseStream = response.GetResponseStream(); streamReader = new System.IO.StreamReader(responseStream); responseJson = streamReader.ReadToEnd(); info(responseJson); } catch (Exception::CLRError) { ex = CLRInterop::getLastException().GetBaseException(); error(ex.get_Message()); }
解决方案
1. 调整ServicePointManager设置顺序
AX2012中System.Net.WebRequest::Create(destinationUrl)会提前初始化ServicePoint,导致后续设置的SecurityProtocol不生效。需将ServicePointManager的配置代码移到创建WebRequest之前:
try { new InteropPermission(InteropKind::ClrInterop).assert(); // 先配置ServicePointManager参数 System.Net.ServicePointManager::set_Expect100Continue(true); System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12); httpHeader = new System.Net.WebHeaderCollection(); clrObj = System.Net.WebRequest::Create(destinationUrl); // 移到配置之后 request = clrObj; // 后续代码保持不变 }
2. 确保服务器.NET Framework版本支持TLS 1.2
Dynamics AX2012默认依赖.NET Framework 4.0,而TLS 1.2在.NET 4.5及以上才原生支持:
- 安装.NET Framework 4.5或更高版本到AX服务器
- 通过注册表强制启用强加密:
- 打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 - 添加DWORD值
SchUseStrongCrypto,设置值为1 - 64位系统需同时在
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319下添加相同键值
- 打开注册表编辑器,定位到
3. 处理证书信任问题
若目标API的证书未被服务器信任根CA认可,会导致SSL握手失败:
- 测试环境:添加证书验证回调跳过验证(生产环境不推荐):
// 在ServicePointManager设置后添加 System.Net.ServicePointManager::set_ServerCertificateValidationCallback( new System.Net.Security.RemoteCertificateValidationCallback( delegate(System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; // 跳过证书验证 } ) ); - 生产环境:将目标API的证书导入AX服务器的「受信任根证书颁发机构」存储
4. 修正TLS协议检测逻辑
原代码中协议检测使用==判断,而SecurityProtocol是位掩码(可同时启用多个协议),需改为按位与判断:
secProtocol = System.Net.ServicePointManager::get_SecurityProtocol(); ssl3 = (secProtocol & enum2int(System.Net.SecurityProtocolType::Ssl3)) != 0; tls = (secProtocol & enum2int(System.Net.SecurityProtocolType::Tls)) != 0; tls11 = (secProtocol & enum2int(System.Net.SecurityProtocolType::Tls11)) != 0; tls12 = (secProtocol & enum2int(System.Net.SecurityProtocolType::Tls12)) != 0; tls13 = (secProtocol & 12288) != 0;
5. 检查AX服务账户权限
确保运行AX服务的账户:
- 有权限访问目标HTTPS URL(无防火墙/代理拦截)
- 有权限读取本地证书存储
内容的提问来源于stack exchange,提问作者Saleem Alayyan
相关产品推荐
相关产品推荐

