我有一个简单的客户端套接字应用程序,我想通过它访问网站。为了访问 Internet,我的客户端必须通过 HTTP 代理服务器(我使用的是 Microsoft Forefront 威胁管理网关)。代理服务器需要身份验证,并且被配置为通过 GSSAPI 接受 Kerberos。
在我的客户端中,我使用 Microsoft 的 SSPI:
首先,我调用AcquireCredentialsHandle成功并返回SEC_E_OK
接下来,我调用InitializeSecurityContext也成功并返回SEC_E_OK
到目前为止,一切都很好。但是现在,我需要将令牌提交给代理服务器进行授权,这是给我带来问题的部分。
如果我使用 Internet Explorer 连接到我的代理服务器,我可以通过 Wireshark 观看数据包交换。IE 与 Kerberos 协商票证,并似乎通过 Proxy-Authorization 标头提交票证。标头内容似乎是 base64 编码的。
如果我只是获取从返回的令牌InitializeSecurityContext
,base64 对其进行编码并通过类似的标头将结果发送到代理服务器Proxy-Authorization: Negotiate <base64Data>
,则身份验证失败。
我觉得我很接近,但仍然缺少一些东西。一个站点讨论了在发送之前在令牌上使用 EncryptMessage。另一个讨论了使用相互身份验证(我不认为 IE 正在使用相互身份验证,因为客户端似乎只发送一次授权,并且没有来自服务器的反馈数据(InitializeSecurityContext
第二次调用)另一个站点概述了将令牌与不同的SEC_BUFFER
类型(填充、数据等)和加密。我怀疑这是我需要做的,因为我没有找到太多关于如何做的文档。
您可能有任何见解或建议将不胜感激。
2014 年 7 月 19 日更新:为了清楚起见,我在问如何使用 SSPI 来计算“base64Data”字段(如上所述)。虽然计算 SECBUFFER_TOKEN 缓冲区中包含的内容的 base64 编码是我最初的猜测,但服务器不接受结果,因此它显然是无效的。
进一步的研究表明,令牌必须“包装”(又名“EncryptMessage”通过 SSPI)并以与 GSSAPI 兼容的方式加密,必须使用三个缓冲区(按顺序:SECBUFFER_TOKEN、SECBUFFER_DATA 和 SECBUFFER_PADDING)我试过这个昨天,但没有找到成功。