QuickFix/n接受端无法获取Logon消息Password字段及鉴权问题
问题分析与解决方案
问题1:无法获取Logon消息中的Password字段
你在强类型QuickFix.FIXT11.Logon对象中无法获取Password字段,核心原因是QuickFix/n的默认强类型Admin消息类未绑定Password字段(即便数据字典里有定义)。直接从FromAdmin方法的原始Message对象提取字段即可解决:
public void FromAdmin(Message message, SessionID sessionID) { if (message.Header.GetString(MsgType.FIELD) == MsgType.LOGON) { string clientPassword = string.Empty; // 直接从原始Message对象判断并提取Password字段(tag=554) if (message.IsSetField(554)) { clientPassword = message.GetString(554); } // 后续可在此处添加验证逻辑 } }
另外确认TransportDataDictionary=FIXT11.xml的文件路径正确,确保QuickFix/n能加载到包含Password字段定义的字典文件。
问题2:密码不匹配仍能登录
QuickFix/n的Acceptor不会自动验证Password,需手动实现验证逻辑,不匹配时抛出RejectLogonException拒绝登录:
步骤1:存储会话与密码的映射
动态添加会话时,把对应密码存入字典,方便后续验证:
private Dictionary<SessionID, string> _sessionPasswordMap = new Dictionary<SessionID, string>(); public void AddSession(string targetCompId, string password) { var dictionarySettings = new Dictionary(); dictionarySettings.SetString("Password", password); // 注意SessionID格式:BeginString, Acceptor的SenderCompID, 客户端的SenderCompID var sessionId = new SessionID("FIXT.1.1", "MyAcceptor", targetCompId); _soketAcceptor.AddSession(sessionId, dictionarySettings); // 存储会话与密码的对应关系 _sessionPasswordMap[sessionId] = password; }
步骤2:在FromAdmin中验证密码
public void FromAdmin(Message message, SessionID sessionID) { if (message.Header.GetString(MsgType.FIELD) == MsgType.LOGON) { string clientPassword = string.Empty; if (message.IsSetField(554)) { clientPassword = message.GetString(554); } // 匹配预设密码 if (_sessionPasswordMap.TryGetValue(sessionID, out string expectedPassword)) { if (!string.Equals(clientPassword, expectedPassword, StringComparison.Ordinal)) { throw new RejectLogonException("密码验证失败"); } } else { throw new RejectLogonException("未找到对应会话配置"); } } }
关键注意点
你之前动态创建的SessionID格式错误:客户端的SessionID是FIXT.1.1:MyInitiator->MyAcceptor,所以Acceptor侧的会话ID必须是new SessionID("FIXT.1.1", "MyAcceptor", "MyInitiator")(格式为BeginString, Acceptor发送方ID, 客户端发送方ID),否则会出现会话不匹配,导致密码验证逻辑无法触发。
内容的提问来源于stack exchange,提问作者rapetum228
相关产品推荐
相关产品推荐

