从 IIS 到 SQL 服务器的 Kerberos 双跃点委派(使用 django)

Kerberos Double Hop Delegation from IIS to SQL server (using django)

我需要将凭据(集成 Windows 身份验证)从 IIS 上的 django 网站传递到后端 SQL 服务器,以便它在正确的用户上下文中运行。

到目前为止我的设置是这样的:

  1. 运行 SQL sql_sever.domain.com 上的服务器在服务帐户 domain\svc_sqlserver
  2. 运行 app_server.domain.com 上的 Django 网站使用服务帐户 domain\svc_appserver 下的 IIS,具有 Windows 身份验证和 ASP.Net 模拟(提供程序设置为 Negotiate:Kerberos -> Negotiate -> NTLM ) 与 useAppPoolCredentials=True
  3. 通过在连接
  4. 中设置Trusted_Connection=yes,使用Windows身份验证从django连接到SQL服务器
  5. domain\svc_sqlserverdomain\svc_appserver 配置的用于 Kerberos 身份验证的 SPN 如下:

    setspn -a HTTP/app_server                          domain\svc_appserver
    setspn -a HTTP/app_server.domain.com               domain\svc_appserver
    setspn -a MSSQLSvc/sql_server.domain.com:PORT      domain\svc_sqlserver
    setspn -a MSSQLSvc/sql_server.domain.com:INSTANCE  domain\svc_sqlserver
    setspn -a MSSQLSvc/sql_server.domain.com           domain\svc_sqlserver
    
  6. 信任 svc_sqlserversvc_appserver 委托给 MSSQLSvc 服务,另外 domain\svc_appserver 我也添加了 HTTP 服务(来自上面的列表)

结果:

  1. Kerberos 身份验证适用于 SQL 服务器。通过查看 auth scheme of connected users
  2. 确认
  3. Kerberos 身份验证适用于 Django 网站。通过检查 WWW-Authenticate 响应头和 Authorization 请求头确认(Negotiate 被正确使用)
  4. Sql 服务器仅在 domain\svc_appserver 的上下文中运行,而它应该在 domain\remote_user
  5. 的 运行 中运行

我已经为此工作了一个多星期,但对于我来说,我无法弄清楚如何将经过身份验证的用户的上下文从 IIS 传递到 SQL 服务器。我查看了在网上找到的数百个链接,但此时我不确定该怎么做。

还有什么我想念的吗?在建立与数据库的连接之前,Django 中是否有任何方法可以设置用户的上下文?如果有人可以提供帮助,我将不胜感激。谢谢!

我正在使用:

我认为在 FastCGI 或 Kestrel 工作进程中运行的任何东西都没有实施模拟。参见例如 ASP.NET 核心:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-2.1&tabs=aspnetcore2x#impersonation

如果您使用 HTTP Basic 身份验证,这需要用户输入密码,您可以使用 Win32 执行 Logon 并自己进行模拟。但是对于 NTLM 和 Kerberos,没有简单的方法可以从您的 python 进程中模拟调用用户。

或者,如果这是自定义应用程序,您可以在服务器端代码可以看到的地方使用 SQL Impersonation, or pass the end user's identity to SESSION_CONTEXT。也可以增强 django-pyodbc-azure 来做到这一点。

我唯一能想到的就是通过实施 ASP.NET HttpHandler that impersonates the user and manages python processes running under the end user's identity.

来滚动您自己的 Django 托管