在Windows和Linux上使用Kerberos的SSO

时间:2018-12-21 13:53:07

标签: single-sign-on kerberos gssapi sspi

我们有一个内部开发的基于客户端/服务器的应用程序。客户端和服务器通过TCP / IP连接使用特定于应用程序的协议进行通信。客户端在Windows上运行,服务器在Linux上运行。所有计算机都在同一Active Directory / Kerberos域/领域中。

当前,用户在启动应用程序时输入用户名和密码。服务器检查用户名和密码(身份验证)。服务器还根据用户名确定对资源的访问(授权)。

我们想向应用程序添加单点登录(SSO)功能。也就是说,我们不希望用户输入用户名和密码,而是希望自动以当前Windows用户身份登录。

当然,确定当前的Windows用户必须安全完成。

我想出了以下设置:

  1. 我在Windows上使用SSPI(协商),在Linux上使用GSSAPI。
  2. 客户端连接到服务器时,它使用AcquireCredentialsHandle (Negotiate)获取当前Windows用户的凭据。
  3. 客户端使用InitializeSecurityContext (Negotiate)根据这些凭据生成令牌。
  4. 客户端将令牌发送到服务器。
  5. 服务器使用gss_acquire_cred()获取服务的凭据。这些都存储在.keytab文件中。
  6. 服务器从客户端接收令牌。
  7. 服务器使用gss_accept_sec_context()处理令牌。此调用还返回“源名称”,即客户端的当前Windows用户。
  8. 服务器使用“源名称”作为用户名:服务器不执行其他身份验证。服务器仍然执行授权。

这可行,但我确实有一些疑问:

  1. 这安全吗?客户端不应指定客户端进程的Windows用户以外的任何其他用户名。如果一个用户具有(作为合法或非法的)另一个用户身份创建流程的凭据,则不允许这样做。
  2. 我应该执行其他检查以验证用户名吗?
  3. 在此设置中是否有其他方法可以实现SSO?他们的利弊是什么?

1 个答案:

答案 0 :(得分:1)

您在此处描述的是验证用户身份的正确方法。您不必担心用户指定其他名称。 Kerberos就是为您服务的。

如果客户端能够获得服务票证,则他们必须已经能够针对KDC(Active Directory)进行身份验证。 KDC创建一个包含用户名的服务票证,并使用服务的秘密密钥对其进行加密。

客户端无法使用假名为服务器创建票证,因为它没有必要的密钥来加密票证。

当然,所有这些都假设您已经正确设置了所有内容;例如,客户端不应有权访问该服务的密钥表文件,并且该服务的密钥选项卡中除其自身外不应具有任何主体。

here有一个非常详细的解释。