核心模式身份驗證:從遠端電腦訪問站點時出現 401 錯誤
我有幾個使用集成 Windows 身份驗證和 Kerberos 委派的經典 ASP 站點。
它們在實時伺服器上工作正常(最近移至 Server 2008/IIS7 伺服器),但在我的開發 PC 或我的開發伺服器上不能完全工作。兩台機器上的 IIS 都是通過從舊機器導出的 IIS Web 部署工具包配置的;部署並不完美,我不得不稍作修改才能使站點正常工作。
在任何一台機器上本地訪問應用程序時,它們都可以正常工作;從另一台機器訪問時,使用者名/密碼對話框會提示使用者,無論您輸入什麼,最終都會導致*401(未經授權)*錯誤。
我嘗試將這些機器的配置與類似的實時伺服器(一切正常)進行比較,它們看起來通常具有可比性(假設沒有任何實時伺服器在 IIS7.5(Windows 7/Server 2008 R2)上。
這些應用程序在一個公共應用程序池中執行,該應用程序池使用一個特殊的域使用者作為它的身份——這個使用者在實時和開發機器上具有相似的權限。在 IIS6 平台上,為了啟用 kerberos 委派,我需要為該使用者設置一些 SPN,它們仍然存在(儘管由於核心模式身份驗證,我認為 IIS7+ 不再需要它們),
此外,該帳戶已啟用 Active Directory 中的 Kerberos 委派,就像我正在處理的每台電腦一樣。
我正在考慮部署可能已更改/未能更改 IIS 配置從而導致此問題的可能性。也許完全重建(減去另一個 Web 部署嘗試)會解決問題,但我寧願修復(從而理解)目前問題。
到目前為止有什麼想法嗎?
我剛剛再次嘗試解決此問題,並且取得了一些進展,但我還沒有一個完整的解決方案……還沒有。
我發現如果我通過 IP 地址(而不是通過 NetBIOS 名稱)訪問站點,我會得到相同的對話框,除了它接受我的憑據,因此應用程序可以工作 - 不是完全修復,而是一個有用的步驟。
更有趣的是,我發現如果我禁用核心模式身份驗證(在IIS 管理器 > 網站 > 身份驗證 > 高級設置中),應用程序可以完美執行。我模糊的理解是,這有效地以 IIS7 之前的方式工作。一個合理的短期解決方案,但請考慮 IIS 關於此問題的以下明確建議:
預設情況下,IIS 啟用核心模式身份驗證,這可以提高身份驗證性能並防止配置為使用自定義標識的應用程序池出現身份驗證問題。作為最佳實踐,如果在您的環境中使用 Kerberos 身份驗證並且應用程序池配置為使用自定義身份,請不要禁用此設置。
顯然,這不是我的應用程序應該工作的方式。那麼問題是什麼?
我已經為這個問題苦苦掙扎了好幾年了。定期,我設法讓它工作,但一年後有一個伺服器移動,我必須再次戰鬥才能讓它在新伺服器上工作。
這樣的時刻又來了……在努力調試了這些 kerberos 問題之後,我回到了基礎:其他人一定經常做我嘗試過的事情——他們用了什麼?
雖然有人使用我的技術,但他們顯然沒有問題,我有。但是有十幾種方法可以解決大多數問題,所以我將在網路上的 2 或 3 個範例中找到的技術結合起來,並使用不同的方法進行遊戲,這似乎比我以前的方法更可靠且不復雜,而且至關重要的是’不涉及臭名昭著的 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
如果您現在使用 IE,請嘗試使用其他瀏覽器,例如 Chrome。這可能來自位於 Intranet 或受信任區域中的域名。這可能會導致它嘗試保存可能無法遠端工作的憑據,具體取決於您是否來自域外。