C#开发OPC UA客户端连接Zenon SCADA报BadIdentityTokenInvalid错误求助
解决C# OPC UA客户端连接Zenon SCADA服务器时的BadIdentityTokenInvalid错误
问题描述
我用C#开发的OPC UA客户端对接Zenon SCADA OPC UA服务器,服务器要求用SCADA用户ID认证,确认用户名密码正确,但始终返回BadIdentityTokenInvalid错误。用Matrikon OPC客户端可以正常连接,且我的客户端用证书认证方式也能正常连接。
错误信息
/ Opc.Ua.ClientBase.ValidateResponse(ResponseHeader header)\r\n<br /> / Opc.Ua.SessionClient.ActivateSession(RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, Byte[]& serverNonce, StatusCodeCollection& results, DiagnosticInfoCollection& diagnosticInfos)\r\n<br /> / Opc.Ua.Client.Session.Open(String sessionName, UInt32 sessionTimeout, IUserIdentity identity, IList`1 preferredLocales, Boolean checkDomain)\r\n / Opc.Ua.Client.Session.Create(ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, Boolean updateBeforeConnect, Boolean checkDomain, String sessionName, UInt32 sessionTimeout, IUserIdentity identity, IList`1 preferredLocales)\r\n /
相关代码
private ApplicationConfiguration CreateOpcUaAppConfigurationbyNone() { var config = new ApplicationConfiguration() { ApplicationName = "OPC UA Client", ApplicationType = ApplicationType.ClientAndServer, SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier(), AutoAcceptUntrustedCertificates = true, }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }, }; config.Validate(ApplicationType.Client); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); }; } return config; } // 连接逻辑 endpointUrl = _tagGroup.HostIp.Replace(" ", string.Empty); userId = _tagGroup.SysUser.Replace(" ", string.Empty); passWord = _tagGroup.SysPassword.Replace(" ", string.Empty); if(userId == "") { userIdentity = new UserIdentity(new AnonymousIdentityToken()); } else { userIdentity = new UserIdentity(userId, passWord); } if (_tagGroup.OpcCertType == "N") { config = CreateOpcUaAppConfigurationbyNone(); var endconf = new ConfiguredEndpoint(null, new EndpointDescription(endpointUrl)); session = Session.Create(config, endconf, true, "abc", 60000, userIdentity, null); }
解决方案
1. 明确指定用户名密码令牌类型
Zenon SCADA可能需要客户端显式指定身份令牌类型,默认构造的UserIdentity可能未正确适配服务器要求。手动创建UserNameIdentityToken并设置安全策略:
else { var userToken = new UserNameIdentityToken(userId, passWord); // 根据Zenon服务器配置调整安全策略,常用SecurityPolicies.None或SecurityPolicies.Basic256Sha256 userToken.SecurityPolicyUri = SecurityPolicies.None; userIdentity = new UserIdentity(userToken); }
2. 确保端点安全配置与服务器匹配
手动构造EndpointDescription时,需对齐服务器的安全模式和策略:
var endpointDescription = new EndpointDescription(endpointUrl); // 按Zenon服务器实际配置设置,比如MessageSecurityMode.None或MessageSecurityMode.SignAndEncrypt endpointDescription.SecurityMode = MessageSecurityMode.None; endpointDescription.SecurityPolicyUri = SecurityPolicies.None; var endconf = new ConfiguredEndpoint(null, endpointDescription);
3. 禁用域检查
当用IP地址访问服务器时,关闭域检查避免身份令牌验证失败:
// 将最后一个参数设为false session = Session.Create(config, endconf, true, "abc", 60000, userIdentity, null, false);
4. 验证Zenon用户权限配置
确认Zenon SCADA中该用户ID已被授予OPC UA客户端的访问权限,部分系统会单独配置OPC UA认证权限,即使用户能登录SCADA也可能无此权限。
5. 通过服务发现获取正确端点
避免手动构造端点,通过服务器发现机制获取标准端点配置:
// 自动发现并选择合适的端点 var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointUrl, false, 15000); var endconf = new ConfiguredEndpoint(null, selectedEndpoint);
内容的提问来源于stack exchange,提问作者TKTK
相关产品推荐
相关产品推荐

