IIS 上的 Python Flask 应用程序-代表用户更新 Active Directory 属性

IIS 上的 Python Flask 应用程序-代表用户更新 Active Directory 属性

我已经在 stackoverflow 上发布了此内容,但在这里发布是因为我希望得到熟悉 kerberos 委派和 IIS 的人们的帮助。我目前正在尝试弄清楚如何让我的 flask 应用程序代表域中的用户处理 Active Directory 属性更新,例如他们的电话号码。我目前在 Windows Server 2019 VM 上的 IIS 10 中运行它。我在 Hyper-V 上有一个小型虚拟实验室,它复制了一个原始 Active Directory 域,其中我有一个名为的域控制器直流1,一个名为web服务器1以及一台名为客户端1

Web 应用程序在名为的服务帐户下运行服务帐户在 IIS 中。目前,HTTP 请求为我提供了请求用户的 Windows 身份验证令牌(通过 asp net core 模块),这使我能够模拟他们。

Web.配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <security>
            <authentication>   
                <anonymousAuthentication enabled="false" />
                <windowsAuthentication enabled="true" useKernelMode="true" useAppPoolCredentials="true" />
            </authentication>
        </security> 
        <handlers>
            <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" requireAccess="Script" />
        </handlers>
        <aspNetCore processPath="C:\apps\Test\venv\scripts\python.exe" arguments="app.py" startupTimeLimit="10" stdoutLogEnabled="true" stdoutLogFile=".\logs\log.log" processesPerApplication="10" forwardWindowsAuthToken="true">
            <environmentVariables>
            </environmentVariables>
        </aspNetCore>
        <httpErrors errorMode="Detailed" />
    </system.webServer>
    <system.web>
        <identity impersonate="true" />
    </system.web>
</configuration>

工作流程如下:

User hits IIS --> Web Server receives HTTP request --> Flask parses the header and gets the windows authentication token --> continue with endpoint python logic

在模仿方面,我能够使用安全python 模块模拟用户并在 Web 服务器内执行有限的操作(例如创建文件夹);但是,尝试通过 flask 端点更新用户的活动目录凭据会导致权限错误(通过皮亚德Python 模块):

pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Active Directory', 'An operations error occurred.\r\n', None, 0, -2147217865), None)

我使用的相关端点python代码如下:

    @app.route("/TestImpersonation")
    def TestImpersonation():
        key = 'Ms-Aspnetcore-Winauthtoken'
        if key in request.headers.keys():
            handle_str = request.headers[key]
            handle = int(handle_str, 16) # need to convert from Hex / base 16
            win32security.ImpersonateLoggedOnUser(handle)
            user = win32api.GetUserName()

            from pyad import pyad

            user_obj = pyad.from_cn(user)

            description = "Changed by "+ str(user) + " on " + datetime.datetime.today().strftime("%Y/%m/%d %H:%M:%S")
            user_obj.update_attribute('description', description)

            win32security.RevertToSelf() # undo impersonation
            win32api.CloseHandle(handle) # don't leak resources, need to close the handle!
            
        # Continue...

搜索错误表明我在尝试执行活动目录操作时遇到权限问题,这让我认为这是一个双跳问题。我尝试允许 ADUC 中的服务帐户进行 kerberos 委派,并为其创建了 SPN,如下所示:

setspn -s HTTP/webSERVER1 contoso\service-acct
setspn -s HTTP/webserver1.contoso.com contoso\service-acct

但是,这似乎仍然存在问题,我似乎陷入了困境。有什么建议吗?

相关内容