2

我正在使用 SPNEGO 来实施 SSO 解决方案。在配置过程中,我需要分两步使用域用户凭据:

  1. web.xml我的应用程序中:

     <init-param>
          <param-name>spnego.preauth.username</param-name>
          <param-value>myuser</param-value>
     </init-param>
     <init-param>
          <param-name>spnego.preauth.password</param-name>
          <param-value>mypassword</param-value>
     </init-param>
    
  2. setspn命令中:setspn -A <mySPN> myuser

当我使用此配置时,Java 应用程序使用 getRemoteUser() 检索了用户“myuser”的用户名。所以 SSO 工作正常。但是当我尝试以其他用户(在同一 Windows 服务器上)的身份打开会话时,它也可以正常工作,所以我有点困惑。这让我想到了这些问题:

为什么 SSO 对域的所有其他用户都有效?我必须在 web.xml 和 setspn 命令中使用相同的用户吗?以及选择哪个用户?SPN 在 Kerberos 方案中的确切用途是什么?我必须在每台 Windows 计算机上执行命令 setspn 还是有办法只执行一次?

4

1 回答 1

2

此帐户是在 Kerberos中定义服务器身份的一部分。

Kerberos 是一种对称密钥协议。每个用户都有一个在用户和 KDC 之间共享的对称密钥,同样,每个服务(接受者)都有一个在服务和 KDC 之间共享的对称密钥。

当用户请求特定“服务主体”的票证时,KDC 将使用该服务的密钥加密返回票证。因此,为了让服务解密这些 Kerberos 票证,它还需要某种方式来了解与其自己的服务主体关联的密钥。

通常,服务密钥是随机生成的,并通过“keytab”文件提供。但是,在 Active Directory 系统中,大多数服务帐户都是具有密码的常规用户帐户,因此它们的密钥可以从服务的密码中派生。

看来您的 SPNEGO 模块支持这两种方法(参见第 150-160 行)——可以给它一个密钥表密码。

无论如何,该设置与将连接到您的服务的客户端完全无关。它只建立服务器自己的身份。

SPN 在 Kerberos 方案中的确切用途是什么?

类似于 HTTPS 证书中的域名字段。例如,当浏览器对 执行 Kerberos 身份验证时,它总是会从 KDChttps://example.com请求 SPN 的 Kerberos 票证。HTTP/example.com

如果您熟悉 OAuth2 或 SAML 或 JWT,我相信 Kerberos SPN 大致相当于 SAML 断言中的“audience”字段或 JWT 中的“aud”字段。

(请注意,浏览器通过其 SPN 了解您的服务,并不关心在幕后使用的实际服务帐户——例如,在这种情况下,Active Directory 恰好将 SPN 映射到真正的“用户”帐户,但其他 Kerberos实现方式不同)

我必须在 web.xml 和 setspn 命令中使用相同的用户吗?

是的,它必须是同一个用户,因为服务必须能够解密为其 SPN 签发的票证,因此它需要知道相同的对称密钥。

以及选择哪个用户?

仅为该服务创建一个新的专用帐户。不要使用真实的“人”帐户。

使用长且高度随机的密码,并将其标记为不过期。此外,请确保在帐户选项中启用“帐户支持 Kerberos AES xxx 位”功能(假设您的 Java SPNEGO 支持 AES,它确实应该支持)。

我必须在每台 Windows 计算机上执行命令 setspn 还是有办法只执行一次?

不,在哪里执行它并不重要,因为它只编辑域控制器上的实际帐户——它不会在本地机器上留下任何痕迹。(具体来说,它servicePrincipalName为提供的帐户设置 LDAP 属性。)

客户仅通过 SPN 识别您的服务,无需了解 KDC 在幕后完成的帐户映射。

于 2021-04-09T11:58:15.363 回答