内核模式身份validation:从远程计算机访问站点时出现401错误

我有几个使用集成Windows身份validation和Kerberos委派的经典ASP站点。

它们可以在活动服务器(最近移动到Server 2008 / IIS7服务器)上正常工作,但不能在我的开发PC或我的开发服务器上正常工作。 两台机器上的IIS都是通过从旧机器导出的IIS Web部署工具包configuration的; 部署没有完美的工作,我不得不修补一点让网站的工作。

在任何一台机器上本地访问应用程序时,都能正常工作。 当从另一台机器访问时,用户将被用户名/密码对话框提示,无论您input什么内容,最终都会导致401(未授权)错误。

我已经尝试过将这些机器的configuration与类似的活动服务器进行比较(所有这些工作都正常),并且它们看起来大体相当(假设IIS7.5(Windows 7 / Server 2008 R2)上还没有活动的服务器。

这些应用程序运行在一个通用的应用程序池中,该应用程序池使用一个特殊的域用户作为身份标识 – 该用户在实时和开发机器上具有相似的权限 在IIS6平台上,为了启用Kerberos委派,我需要为这个用户设置一些SPN,并且他们仍然在位(即使我不相信由于内核模式身份validation,他们已经不再需要IIS7 +),

此外,在Active Directory中为这个帐户启用了Kerberos委托,就像我正在处理的每台机器一样。

我正在考虑部署可能更改/无法对IISconfiguration进行更改从而导致此问题的可能性。 也许一个完整的重build(减去另一个Web部署尝试)将解决这个问题,但我宁愿修复(从而理解)当前的问题。

任何想法到目前为止?

我刚刚尝试解决这个问题,并取得了一些进展,但我还没有完全解决。

我发现,如果我通过IP地址访问网站(比通过NetBIOS名称),我得到相同的对话框,除了它接受我的凭据,从而应用程序的工作 – 不是一个修复,但一个有用的步骤。

更有趣的是,我发现,如果我禁用内核模式身份validation(在IISpipe理器>网站>身份validation>高级设置 ),应用程序工作完美。 我的模糊的理解是,这是有效的工作在IIS7以前的方式。 一个合理的短期解决scheme,但是在这个问题上考虑以下来自IIS的明确build议:

默认情况下,IIS启用内核模式身份validation,这可能会提高身份validation性能并防止configuration为使用自定义身份的应用程序池的身份validation问题。 最佳做法是,如果您的环境中使用了Kerberos身份validation,并且应用程序池configuration为使用自定义标识,则不要禁用此设置。

显然,这不是我的应用程序应该工作的方式。 那么问题是什么?

尝试使用其他浏览器,例如现在使用IE浏览器。 这可能是来自位于Intranet或信任区域的域名。 这可能会导致它尝试保存可能无法远程工作的凭据,具体取决于您是否来自域外。

我已经为这个问题奋斗了好几年了。 定期地,我设法得到它的工作,但一年后有一个服务器的举动,我不得不再次争取让它在新的服务器上工作。

这样一个时代又来了……在努力debugging这些kerberos问题之后,我又回到了基础知识:其他人必须按照我曾经尝试过的做法 – 他们使用了什么?

虽然有人在用我的技术,但他们显然没有问题。 但是有十几种方法可以解决大多数问题,所以我把两三个例子在networking和游戏中find的技术结合起来,采用了不同的方法,这种方法似乎比我以前的方法更可靠,也更复杂,没有涉及臭名昭着的kerberos“双跳”:

Sub Authuser() 'Swap out values enclosed in [] If Session("UID") = "" or 1 then Dim rsUser, aUserID, aGroups, i Dim connAD, sBase, sFilter, sAttributes, sScope, sFullCommand, rsADUserInfo, oADSysInfo aUserID = Split(Request.servervariables("AUTH_USER"),"\") Set connAD = Server.CreateObject("ADODB.Connection") connAD.Provider = "ADsDSOObject" connAD.Properties("User ID") = "[MyDomain]\[MyDomainUser]" ' ### remember to make sure this user has rights to access AD connAD.Properties("Password") = "[password]" connAD.Properties("Encrypt Password") = true connAD.Open sBase = "<LDAP://DC=[MyDomain], DC=[MyDomainExt]>" sFilter = "(sAMAccountName=" & aUserID(1) & ")" sAttributes = "cn, mail, company, givenName, sn, ADsPath, name, sAMAccountName, telephoneNumber, memberof" sScope = "subtree" sFullCommand = sBase & ";" & sFilter & ";" & sAttributes & ";" & sScope set rsUser = Server.CreateObject("ADODB.Recordset") set rsUser = connAD.Execute(sFullCommand) If not rsUser.EOF then Session("UID") = aUserID(1) Session("Name") = rsUser("cn") Session("Email") = rsUser("mail") If IsArray(rsUser.Fields(9)) Then aGroups = rsUser.Fields(9) For i = LBound(aGroups) To UBound(aGroups) If InStr(1, aGroups(i), "[MyUsersGroup]", 1) Then Session("Auth") = 1 End If If InStr(1, aGroups(i), "[MyAdminGroup]", 1) Then Session("Admin") = 1 End If Next Else Response.Write "No groups<BR>" Session("Auth") = 1 Session("Admin") = 1 End If Else Response.Write "User not recognised in AD<br>" End if connAD.Close set rsUser = Nothing Set connAD = Nothing End If End Sub