Windows 使用CredSpec的经典ASP/MSSQL身份验证问题

Windows 使用CredSpec的经典ASP/MSSQL身份验证问题,windows,docker,iis,vbscript,gmsa,Windows,Docker,Iis,Vbscript,Gmsa,我目前正在尝试对一些旧的(即将被淘汰的)基础设施进行一些改进,为迁移到.NETCore做准备。我们有一个小的反馈表单,它使用SQLOLEDB连接字符串写入SQL表。这些字符串与明文中定义的用户名/密码配合得很好,尽管我希望放弃这种方法,转而支持集成身份验证 我已经做了很多工作来达到我的目标: 基于安装了ASP功能的IIS构建docker容器 在Windows主机上群集运行容器-加入我们的广告域 设置gMSAs以提供对数据库的域帐户访问 目前,我已经完成了MS'gMSA on Windows Co

我目前正在尝试对一些旧的(即将被淘汰的)基础设施进行一些改进,为迁移到.NETCore做准备。我们有一个小的反馈表单,它使用SQLOLEDB连接字符串写入SQL表。这些字符串与明文中定义的用户名/密码配合得很好,尽管我希望放弃这种方法,转而支持集成身份验证

我已经做了很多工作来达到我的目标:

  • 基于安装了ASP功能的IIS构建docker容器
  • 在Windows主机上群集运行容器-加入我们的广告域
  • 设置gMSAs以提供对数据库的域帐户访问
  • 目前,我已经完成了MS'gMSA on Windows Containers guide()中的所有步骤。测试签出后,我可以在中运行所有测试,没有问题,但是当我尝试使用连接字符串进行连接时,我在日志中收到一个错误,显示:

    2020-09-28 19:36:43 172.17.173.120 POST /Default.asp |42|80040e4d|Login_failed_for_user_'NT_AUTHORITY\ANONYMOUS_LOGON'.
    
    对我来说,这没有多大意义,因为应用程序池标识设置为网络,测试在容器上签出

    现在我尝试了一些方法,比如编辑web.config,将模拟设置为true/false,通过Windows进行身份验证,但我仍然有点困惑。我已将主机设置为允许通过Kerberos委派任何服务

    我还尝试使用以下方式登录:

    docker exec -it --user "NT AUTHORITY\NETWORK SERVICE" cb4 powershell
    
    然后运行:

    $connectionString = 'Data Source=serverhostname.domain.local;database=databasename;Integrated Security = True;'
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $connectionString
    $sqlConnection.Open()
    $sqlConnection | select *
    
    这将导致数据库连接处于打开状态

    应用程序池是使用NetworkService标识设置的

    Get-ItemProperty IIS:\AppPools\domain.co.uk\ -Name processModel
    
    identityType           : NetworkService
    userName               :
    password               :
    loadUserProfile        : False
    setProfileEnvironment  : True
    logonType              : LogonBatch
    manualGroupMembership  : False
    idleTimeout            : 00:20:00
    idleTimeoutAction      : Terminate
    maxProcesses           : 1
    shutdownTimeLimit      : 00:01:30
    startupTimeLimit       : 00:01:30
    pingingEnabled         : True
    pingInterval           : 00:00:30
    pingResponseTime       : 00:01:30
    logEventOnProcessModel : IdleTimeout
    PSPath                 : WebAdministration::\\413E8843BBEF\AppPools\domain.co.uk\
    PSParentPath           : WebAdministration::\\413E8843BBEF\AppPools
    PSChildName            : domain.co.uk\
    PSDrive                : IIS
    PSProvider             : WebAdministration
    Attributes             : {identityType, userName, password, loadUserProfile...}
    ChildElements          : {}
    ElementTagName         : processModel
    Methods                :
    Schema                 : Microsoft.IIs.PowerShell.Framework.ConfigurationElementSchema
    

    如有任何建议,将不胜感激

    连接到数据库时,需要注意以下几点

  • 应用程序池的标识应具有域帐户
  • 域帐户具有读取或更改数据库的权限
  • IIS服务器和sql server应位于同一intranet中并使用同一域

  • 有关更多详细信息,请参阅。

    连接到数据库时,需要注意以下几点

  • 应用程序池的标识应具有域帐户
  • 域帐户具有读取或更改数据库的权限
  • IIS服务器和sql server应位于同一intranet中并使用同一域

  • 更多细节可以参考这一点。

    好的,所以我找到了答案,并将我的发现发布在了一篇公开的摘要中:

    基本上,问题在于,虽然应用程序池标识设置为网络,但站点没有,它使用的似乎是IUSR。鉴于此,我没有将gMSA帐户转发给ASP的脚本,因此我无法使用integrated auth。解决方案是运行:

    Set-WebConfigurationProperty system.webServer/security/authentication/anonymousAuthentication -Name "userName" -Value ""; if ($?) {
    Set-WebConfigurationProperty system.webServer/security/authentication/anonymousAuthentication -Name "password" -Value ""; if ($?) {
    Set-WebConfigurationProperty system.webServer/security/authentication/anonymousAuthentication -Name "logonMethod" -Value 2;}}
    
    这样做的目的是将用户名和密码设置为空,并将登录方法设置为网络。这是完美的,因为这意味着应用程序池和站点都使用了预期的帐户,即gMSA帐户

    我发现了一个非常有用的方法,那就是制作一个测试脚本:

    <%
    Set objNetwork = CreateObject("WScript.Network")
    strNAME = objNetwork.computername
    response.write("Value of strNAME variable: " & strNAME & "<br>")
    response.write("Domain = " & objNetwork.UserDomain & "<br/>")
    response.write("ComputerName = " & objNetwork.ComputerName & "<br/>")
    response.write("UserName = " & objNetwork.UserName & "<br/>")
    %>
    
    
    

    在解决之前,这显示了IUSR,是我对问题的重要线索。解决方案完成后,用户名为
    app$
    (其中app是gMSA的名称)和预期的域。

    好的,所以我找到了这个问题,并将我的发现发布在了一个公开摘要中:

    基本上,问题在于,虽然应用程序池标识设置为网络,但站点没有,它使用的似乎是IUSR。鉴于此,我没有将gMSA帐户转发给ASP的脚本,因此我无法使用integrated auth。解决方案是运行:

    Set-WebConfigurationProperty system.webServer/security/authentication/anonymousAuthentication -Name "userName" -Value ""; if ($?) {
    Set-WebConfigurationProperty system.webServer/security/authentication/anonymousAuthentication -Name "password" -Value ""; if ($?) {
    Set-WebConfigurationProperty system.webServer/security/authentication/anonymousAuthentication -Name "logonMethod" -Value 2;}}
    
    这样做的目的是将用户名和密码设置为空,并将登录方法设置为网络。这是完美的,因为这意味着应用程序池和站点都使用了预期的帐户,即gMSA帐户

    我发现了一个非常有用的方法,那就是制作一个测试脚本:

    <%
    Set objNetwork = CreateObject("WScript.Network")
    strNAME = objNetwork.computername
    response.write("Value of strNAME variable: " & strNAME & "<br>")
    response.write("Domain = " & objNetwork.UserDomain & "<br/>")
    response.write("ComputerName = " & objNetwork.ComputerName & "<br/>")
    response.write("UserName = " & objNetwork.UserName & "<br/>")
    %>
    
    
    

    在解决之前,这显示了IUSR,是我对问题的重要线索。在解决方案之后,用户名将与预期域一起读取
    app$
    (其中app是gMSA的名称)。

    1。应用程序池被分配了网络服务帐户,这似乎是MS在第2节中建议的。本例中的域帐户是一个gMSA,但该帐户已被提供至少读取的验证访问权限,并且我们的DBA确认insert也应该可以(尽管我还没有对此进行测试)。当然,由于登录是完全正确的(请参阅为连接SQL而执行的powershell),我希望显示不同的错误。3。IIS服务器和SQL server位于Azure中的同一局域网内,也是同一域的一部分。通过文本描述很难解决此问题,您可以从这里获得支持:事实上,尽管我们指的是经典的ASP。请记住,如果MS这些天还为此费心,我会非常惊讶。1。应用程序池被分配了网络服务帐户,这似乎是MS在第2节中建议的。本例中的域帐户是一个gMSA,但该帐户已被提供至少读取的验证访问权限,并且我们的DBA确认insert也应该可以(尽管我还没有对此进行测试)。当然,由于登录是完全正确的(请参阅为连接SQL而执行的powershell),我希望显示不同的错误。3。IIS服务器和SQL server位于Azure中的同一局域网内,也是同一域的一部分。通过文本描述很难解决此问题,您可以从这里获得支持:事实上,尽管我们指的是经典的ASP。记住,如果MS这些天还为此费心,我会非常惊讶。