使用 IIS HTTP PlatformHandler 并使用 Windows auth 时,如何在 Python 中获取经过身份验证的用户名?

How to get the authenticated user name in Python when fronting it with IIS HTTP PlatformHandler and using Windows auth?

HttpPlatformHandler 通过启用 web.config 中的 forwardWindowsAuthToken 设置来支持转发授权令牌。 当需要使用 Windows 集成身份验证时,这听起来像是一个有用的功能。 document 对此非常含糊,没有解释如何使用此令牌来获取经过身份验证的用户名。

If this setting is set to true, the token will be forwarded to the child process listening on %HTTP_PLATFORM_PORT% as a header 'X-IIS-WindowsAuthToken' per request. It is the responsibility of that process to call CloseHandle on this token per request. The default value is false.

在我的 use-case 中,我需要将 Windows 集成身份验证与 Python 结合使用,因此使用 IIS 前端进行设置并使用 HTTP 平台处理程序将请求转发到 Python.

问题是,如何从 Python 中提供的令牌中获取用户名? 'X-IIS-WindowsAuthToken' header 中的标记看起来像 3 个字符的十六进制,如 22b。

好的,所以我对此进行了一些研究,最后回顾了 Microsoft.AspNetCore.Server.IISIntegrateion.AuthenticationHandler 是如何做到的。

然后在找到一种方法后,我想 post 这个答案,这样 1) 我可以稍后找到它,2) 至少它已经在 SO 上,以防其他人想知道。

好的,十六进制值就是句柄,有了句柄我们可以调用模拟用户然后获取用户名,完成。

您只需要 pywin32 包:

pip install pywin32

Python中的完整示例:

import win32api
import win32security
if 'x-iis-windowsauthtoken' in request.headers.keys():
    handle_str = request.headers['x-iis-windowsauthtoken']
    handle = int(handle_str, 16) # need to convert from Hex / base 16
    win32security.ImpersonateLoggedOnUser(handle)
    user = win32api.GetUserName()
    win32security.RevertToSelf() # undo impersonation
    win32api.CloseHandle(handle) # don't leak resources, need to close the handle!
    print(f"user name: {user}")