我有一个 Web 服务器,它返回一个
WWW-Authenticate: Negotiate
HTTP 标头(无 <value>
),这表明客户端应使用 Kerberos 进行身份验证。
然后客户端生成 Kerberos 令牌如下(输入令牌为空):
gss_init_sec_context(
&minor_status, GSS_C_NO_CREDENTIAL, (gss_ctx_id_t*)context, (gss_name_t)name, GSS_KRB5_MECHANISM,
request_flags, 0, GSS_C_NO_CHANNEL_BINDINGS, (gss_buffer_desc*)input_token_x, nullptr,
(gss_buffer_desc*)output_token, &return_flags, nullptr);
此令牌只能用于单个请求(为什么?),服务器会使用
WWW-Authenticate: Negotiate <value>
HTTP 标头进行响应,例如:
WWW-Authenticate: Negotiate YIGZBgkqhkiG9xIBAgICAG+BiTCBhqADAgEFoQMCAQ+iejB4oAMCARKicQRv3w2k6UrZ+MQ2wnUaWFxGjiWXi/QHrcdcjlklMW7uCgYUsaLqwO6ihBIxjfSSSHxmMm6JMwbf/0xrN8gMq5D9By9/5YKIOzQWKjwm73CfkrvMAq+Ns0StFfXxkx3rFm2u0OBpuaB77TubvLsMap45
现在这个
<value>
应该用来做什么?
我是否应该在每个 Web 请求之前使用空输入令牌运行
gss_init_sec_context()
,类似于 requests-kerberos 中的操作方式?
这似乎是错误的......我想获得一个长期存在的令牌。
<value>
通常如何使用?
您可以通过在不输入令牌的情况下调用
Authorization: Negotiate
来生成 gss_init_sec_context()
请求的初始令牌。
如果服务器返回
WWW-Authenticate: Negotiate <value>
,则表示协商尚未完成。您再次调用 gss_init_sec_context()
,这次将值作为输入令牌参数传递(解码后)。您通过另一个 Authorization: Negotiate
请求发送生成的令牌。您执行此操作,直到获得没有附加数据的 WWW-Authenticate: Negotiate
(表示协商失败),或其他响应,通常为 200,但也可能是 301 等其他任何内容(表示授权已成功)。
某些服务器可能配置为要求每次请求或每次连接都进行身份验证。如果是后者,服务器将不会在后续请求中发送
WWW-Authenticate
,并且您不需要发送任何 Authorization
。如果是,服务器将发送 Persistent-Auth: true
。无论如何,您不能重复使用协商令牌。您可以为每个请求发出一个新令牌,或者如果 Persistent-Auth 设置为 true,则在第一个请求之后不发送任何令牌。
您无需等待
WWW-Authenticate: Negotiate
即可生成令牌。如果您知道服务器使用此协议,请立即发送Authorization: Negotiate <token>
。
现在您可能会得到另一个
WWW-Authenticate: Negotiate
,其中带有带有 200 响应的令牌(或者我认为其他响应表明成功)。该令牌是服务器的相互身份验证令牌。如果你拿到了,你应该再次打电话给 gss_init_sec_context()
。如果 gss_init_sec_context()
返回成功,则一切就绪。否则,这意味着客户端无法验证服务器(可能服务器设置不正确,或者有人试图冒充它)。
参考资料: