java - SPNEGO:成功协商和身份验证后的后续调用

标签 java web-services kerberos spnego gssapi

在过去的几天里,我使用 GSS-APISPNEGO 构建了一个概念验证演示。目的是让用户通过 Http RESTful 网络服务单点登录访问我们的自定义应用程序服务器提供的服务。

持有有效 Kerberos 票证授予票证 (TGT) 的用户可以调用支持 SPNEGO 的 Web 服务,客户端和服务器将协商, 用户将通过 Kerberos 和应用程序级别的身份验证,并且(在身份验证成功后)将在他的票证缓存中拥有我的服务委托(delegate)人的服务票证。

使用带有 --negotiate 标志的 CURL 作为测试客户端效果很好。

在第一次通过时,CURL 发出没有特殊 header 的普通 HTTP 请求。该请求被服务器拒绝, 它将“WWW-Authenticate:Negotiate”添加到响应 header ,建议协商。 然后 CURL 从 KDC 获取服务票证,并发出第二个请求,这次是在请求 header (NegTokenInit) 中使用协商 + 包装的服务票证 然后,服务器打开票证,对用户进行身份验证,并且(如果身份验证成功)执行请求的服务(例如登录)。

问题是,从客户端到服务器的后续服务调用应该发生什么?客户端现在有一个有效的 Kerberos 服务票证,但通过 CURL 进行额外的调用使用 SPNEGO 进行上述相同的两次传递。

在我看来,我有很多选择:

1) 每个服务调用重复完整的 2 遍 SPNEGO 协商(就像 CURL 所做的那样)。 虽然这可能是最简单的选择,但至少在理论上会有一些开销:客户端和服务器都在创建和拆除 GSS 上下文,并且请求在网络上发送了两次,对于 GET 可能没问题,对于 POST 则不然,如以下问题所述:

Why does the Authorization line change for every firefox request?

Why Firefox keeps negotiating kerberos service tickets?

但是开销*在现实生活中是否明显?我想只有性能测试才能说明问题。

2) 第一次调用使用 SPNEGO 协商。一旦成功通过身份验证,后续调用将使用应用程序级别的身份验证。 这似乎是 Websphere Application Server 采用的方法,它使用轻量级第三方身份验证 (LTPA) 安全 token 进行后续调用。

https://www.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.express.doc/ae/csec_SPNEGO_explain.html

起初这似乎有点奇怪。在成功协商可以使用 Kerberos 之后,为什么要退回到其他东西呢?另一方面,如果可以证明 GSS-API/SPNEGO 会导致明显的开销/性能损失,则此方法可能有效。

3) 第一次调用使用 SPNEGO 协商。一旦成功通过身份验证和信任,后续调用将使用 GSS-API Kerberos。 在这种情况下,我不妨执行下面的选项 4)。

4) 转储 SPNEGO,使用“纯”GSS-API Kerberos。 我可以通过自定义 Http header 或 cookie 交换 Kerberos 票证。

有最佳实践吗?

作为背景:客户端和服务器应用程序都在我的控制之下,都是用 java 实现的,而且我都知道“会说”Kerberos。 我选择 SPNEGO 作为概念验证的“起点”,也是为了让我进入 Kerberos 和单点登录的世界,但这并不是一个硬性要求。

概念验证在带有 FreeIPA 的 OEL Linux 服务器上运行(因为这是我在地牢中拥有的),但可能的应用程序将是 Windows/Active Directory。

* 或与其他性能因素(例如数据库、消息正文使用 XML 与 JSON 等)相比具有重要意义

** 如果将来我们希望允许基于浏览器访问 Web 服务,那么 SPNEGO 将是可行的方法。

最佳答案

  1. 为了回答您的第一个问题,GSS-SPNEGO 可能包括多次往返。它不仅限于两个。您应该实现 session 处理,并在身份验证成功后发出一个 session cookie,客户端应在每个请求中显示该 cookie。当此 cookie 无效时,服务器将强制您重新进行身份验证。这样,您只会在真正需要时才会产生谈判成本。

  2. 根据您的应用程序设计,您可以选择不同的身份验证方法。在 FreeIPA 中,我们一直建议进行前端身份验证,并允许应用程序重新使用前端确实对用户进行身份验证的事实。参见 http://www.freeipa.org/page/Web_App_Authentication了解不同方法的详细说明。

我建议您阅读上面引用的链接并查看我的同事完成的 Material :https://www.adelton.com/他是许多 Apache(和 nginx)模块的作者,这些模块有助于在与 FreeIPA 一起使用时将身份验证与实际 Web 应用程序分离。

关于java - SPNEGO:成功协商和身份验证后的后续调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43456734/

相关文章:

java - Java中静态变量的使用

java - 将货币转换为 Double 时 String 类错误

java - 在没有 krb5.conf 的情况下配置 kerberos

elasticsearch - 在 Elasticsearch 试用版中尝试 Kerberos 身份验证

Java servlet 过滤器 - 阻止来自客户端的所有请求

Java - 确定事件顺序 - AB 或 BA

web-services - 所有子域的单一 SSL 证书

web-services - 如何使用HATEOAS和查询参数进行RESTful搜索?

java - 使用 OTP(一次性密码)连接的 Web 服务

java - 跨域/领域身份验证