我们的应用程序有错误,希望有人能提供帮助。以下是正在发生的事情的摘要:
1) 我们的应用程序具有 3 层架构——Silverlight 应用程序、Web 层和后端业务逻辑层。
- 业务逻辑层(主要是遗留代码)作为 Windows 服务运行。
- 我们为每个客户提供一项服务。
- 系统中有多个业务逻辑服务器,每个都为我们的客户运行多个 Windows 服务
- Silverlight 浏览器应用程序将通过一组 WCF Web 服务与 Web 层通信,而 Web 层将通过 .NET Remoting 与业务逻辑通信。
- 每个客户端的 Windows 服务在启动时都会为远程端点建立一个 TCP 端口。
- Web 层的作用是获取传入请求并将其路由到正确的服务。
2) 我们的 SilverLight 应用程序中存在零星问题。用户将在界面中看到一条消息,显示“无法为源 'ExceptionManagerInternalException' 打开日志。您可能没有写访问权限”或“对 SSPI 的调用失败,请参阅内部异常。” 这两个错误都是由同一个问题引起的,在系统上具有管理员权限的用户将看到第二条消息,“普通”客户端用户将看到第一条消息。
3) 可以在 Web 服务器上的任一事件日志中看到有关错误的更多详细信息。在系统事件日志中,我们看到:
Kerberos 客户端收到来自 aaa$ 的 KRB_AP_ERR_MODIFIED 错误。使用的目标名称是 HOST/bbb.cab.local。这表明目标服务器未能解密客户端提供的票证。当目标服务器主体名称 (SPN) 在目标服务使用的帐户以外的帐户上注册时,可能会发生这种情况。请确保目标 SPN 已在服务器使用的帐户上注册,并且仅在该帐户上注册。当目标服务使用的目标服务帐户密码与 Kerberos 密钥分发中心 (KDC) 用于目标服务帐户的密码不同时,也会发生此错误。请确保服务器上的服务和 KDC 都更新为使用当前密码。如果服务器名称不是完全限定的,则目标域 (domain.
4) 我们已经捕获了跟踪文件,这些文件允许我们看到在我们得到这个错误时发生的事件:
- SOAP 调用进入 Web API (WCF)
- 客户端 ID 从 http 标头中恢复。客户端 ID 允许我们唯一标识在浏览器实例上工作的用户,并在客户端首次登录系统时被放入标题中。当他们登录时,我们还在 Web 服务器上缓存了客户端 ID 以及他们连接的服务。这是在我们端点上的 WCF 行为中实现的。
- 使用此查找,系统的地址(即服务器的名称和 tcp 端口)和服务的 SPN (HOST\) 被放入线程存储中。
- 我们已使用日志记录 (NLOG) 来确认此过程是否正常进行
- 然后,Web 层上的代码将对服务器进行 .NET Remoting 调用。
- 然后,Web 层中的代码对业务逻辑层进行 .NET Remoting 调用。在 ClientChannelSink 中,我们从线程存储中获取服务器的地址和 SPN,并配置远程调用以到达正确的目的地。NLOG 跟踪已确认从线程存储中检索到正确的详细信息并用于配置调用。我们看到了一条跟踪,其中 UserA@domain.local 使用 HOST\aaa 的 SPN 请求访问 aaa)。
- 从网络监视器跟踪中,我们可以看到 DNS 包并为服务器名称返回正确的 IP 地址。
- 从网络监视器跟踪中,我们可以看到向 DC 发出了 Kerberos 票证请求。
- 此请求将包含与预期不同的服务器的 SPN(在我们的跟踪中,请求要求 HOST\bbb)
- Kerberos 票证服务为请求的服务 (HOST\bbb) 的用户 (UserA@domain.local) 返回一个有效的 Kerberos 票证
- 使用错误服务的有效 Kerberos 票证将请求发送到预期服务(服务器 aaa)。
- 服务(在服务器 aaa 上)拒绝该请求。这是合法的,因为 Kerberos 票证不是用于 HOST\aaa 而是 HOST\bbb
我认为事件日志中的任何“建议”都不是导致此问题的原因: - 我们的系统上没有任何重复的 SPN - 两台计算机在同一个域中 - 问题是零星的;消息中列出的问题看起来总是会导致完全失败。
我已经阅读了有关 asp.net 线程敏捷性的信息,但我认为这不会导致此问题,因为我们总是将请求发送到正确的服务器,但使用了错误的 Kerberos 票证。如果我们使用线程存储中的“错误”设置,那么我们会将请求发送到错误的服务器,并为该服务器提供匹配的 Kerberos 票证。对原因或如何进一步调查此问题的任何帮助将不胜感激。