2013-03-28 226 views
8

將我的網站部署到IIS7.5後,我發現了一個奇怪的行爲:默認情況下應用程序池標識爲ApplicationPoolIdentityIIS Application Pool Identities中推薦)時,Ninject似乎被忽略,因爲出現以下錯誤創建第一個控制器:如何正確設置IIS 7應用程序池標識?

System.InvalidOperationException:試圖 當創建 類型的控制裝置發生了錯誤「..MainController」。確保 控制器有一個無參數的公共構造函數。 ---> System.DirectoryServices.DirectoryServicesCOMException:發生操作 錯誤。

我試圖給予FullAccessIIS AppPool\<MySiteAppPool>到文件夾,包含該網站(包括所有子文件夾和文件),但這並沒有改變任何東西。

但是,當我將應用程序池標識設置爲任何域帳戶(即使是簡單的,沒有管理權限,也沒有任何對該站點文件夾的訪問權限)時,它可以正常工作。

Ninject根據Setting up an MVC3 application教程通過NuGet包安裝。

我不確定,如果它是相關的,該網站應該在Windows身份驗證的域Intranet中工作。

所以,唯一的問題似乎與應用程序池的身份。據我急於使用推薦的方式,我喜歡有ApplicationPoolIdentity,而不是一個域帳戶。

這可以連接什麼?是否有可能將所有這些混合在一起?


下面是一個SO有類似的問題線程:ASP.NET MVC 4 + Ninject MVC 3 = No parameterless constructor defined for this object。然而,在那裏也沒有合適的答案。


作爲建議刪除的評論,我嘗試使用NetworkSerive作爲身份。它運作正常。但是,我想這比沒有特權的域帳戶好多了。


編輯

突然發現另一相關性:應用程序池標識用於SQL Server上的Windows身份驗證,但筆者預計客戶端用戶的憑據並在那裏使用。

基於評論

同意,遠程SQL Server可以通過模擬的驗證的憑據訪問。


但是,仍然不清楚ApplicationPoolIdentity和Ninject存在什麼問題。

在這個問題的最頂端文章mentiond讓我想,這可能由以下事實造成的,即虛擬賬戶沒有用戶配置文件。這方面仍然不清楚,因爲我們仍然可以啓用IIS來加載具有LoadUserProfile屬性的用戶配置文件。我無法得到,如果虛擬帳戶沒有配置文件,IIS將加載什麼?

它的存在表示:

IIS不會加載Windows用戶配置文件,但某些應用可能 利用它反正來存儲臨時數據。 SQL Express 是執行此操作的應用程序的一個示例。但是,必須創建用戶 配置文件才能將臨時數據存儲在 配置文件目錄或註冊表配置單元中。網絡服務帳戶 的用戶配置文件是由系統創建的,並始終可用 。但是,通過切換到唯一的應用程序池 身份,系統不會創建用戶配置文件。只有 標準應用程序池(DefaultAppPool和Classic .NET AppPool) 具有磁盤上的用戶配置文件。如果 管理員創建新的應用程序池,則不會創建用戶配置文件。

但是,如果需要,可以通過將「LoadUserProfile」屬性設置爲「true」來將IIS應用程序池配置爲加載 用戶配置文件。


我發現下面的線程上serverfault.com:

How can I assign active directory permission to the default app pool identity

在那裏,它也指出,應用程序池的身份是不能作爲網絡服務工作,特別是查詢AD。

+0

您授予完全訪問權限給誰? – V4Vendetta 2013-03-28 08:32:53

+0

@ V4Vendetta我將'FullAccess'授予'IIS AppPool \ '到包含該站點的文件夾(包括所有子目錄和文件) – horgh 2013-03-28 08:35:15

+0

好吧,你有什麼額外的事件日誌顯示嗎? – V4Vendetta 2013-03-28 08:48:02

回答

2

從問題中的詳細信息,它聽起來很像權限問題,導致COMException被拋出,這阻止Ninject實例化MainController。異常與System.DirectoryServices有關,這些類別是用於查詢Active Directory的類。

當IIS在正常應用程序池帳戶下運行時,這些帳戶沒有權限對Active Directory進行查詢,並且可以引發COMException。我認爲,在異常(不能找到一個參數的構造函數),實際的消息是有點紅鯡魚的,是Ninject試圖回落到另一個構造,因爲正常的一個沒有工作。

這可以解釋爲什麼當您更改IIS應用程序池爲它突然工作的域帳戶運行,因爲該帳戶確實有權限查詢域。

它是否不是你是否Ninject/IIS/ASP使用它們使用System.DirectoryServices自己或不是從問題明確。如果您自己使用它們,請確保AD類中的構造函數都不會拋出異常(捕獲並記錄它們),這將防止您的應用程序在啓動時崩潰。你可能會發現我上面關於權限的說法。

如果您需要IIS作爲普通應用程序池帳戶運行(這是一個好主意),但仍然作爲域用戶查詢AD,那麼您可以指定憑據DirectoryEntry並使用DirectorySearcher來執行AD搜索。如果您使用.Net 4或更高版本,則建議使用新的System.DirectoryServices.AccountManagement類(它們還允許您指定憑據)。

使用該方法,您不需要任何模擬AD查詢,並且您的應用程序池仍可以作爲普通應用程序池帳戶運行。

+0

這不完全正確。網絡服務是可以訪問網絡資源的低權限帳戶。當它這樣做的時候,它就像機器域賬號一樣。因此,如果您要訪問AD,並且該機器名爲domain \ webserver,則它將使用憑據域\ webserver $。但是,這些憑據可能擁有的權限比您需要的少。 – 2013-04-05 23:53:06

+1

@Simon我已經更新了我的答案,以澄清AD模型不需要進行AD查找並刪除了對NetworkService帳戶的引用。由於通常的IIS應用程序池帳戶(如ASP.Net v4.0)和NetworkService帳戶(如您所說的)略有不同,這可能會產生誤導。 – 2013-04-06 12:32:00

+0

@AdamRodger我認爲你已經指出我正確的方向,因爲我確實訪問AD,這一定是在虛擬帳戶下運行失敗的原因。我會盡快檢查一切。 – horgh 2013-04-08 00:39:10

9

iispool \ appPoolName帳戶被稱爲虛擬帳戶&被添加到Windows 2008.這個想法是,他們並不真正意義上的帳戶。他們允許的是增強使用基本帳戶的進程之間的安全性。

您的機器上的許多服務使用networkService,這是一個內置的網絡訪問帳戶。因此,如果攻擊者利用這些服務之一,則可以訪問在同一帳戶下運行的任何其他進程。虛擬帳戶(如IIS使用的虛擬帳戶)通過顯示爲不同的帳戶來防止這種情況發生,同時仍然是同一帳戶 - 您的asp.net應用程序仍然在技術上運行,因爲網絡服務&授予此帳戶訪問權仍然有效。這也意味着如果您需要訪問網絡資源,則iispool帳戶將這樣做,因爲networkservice確實使用了機器域帳戶&。

如果您正在訪問遠程SQL服務器,這是您應該添加以允許從您的Web服務器訪問的帳戶。我不會建議使用模擬,除非您確實需要查看用戶在SQL服務器上的用戶。如果你離開它,你的應用程序安全性更簡單。

至於爲什麼你的注射不起作用,它可能是你的任何依賴失敗。如果控制器A注入ClassB,而ClassB又注入ClassC &該類未能注入ClassD,則整個鏈失敗。我曾經遇到過這種情況,我花了一段時間才意識到這是從我看到的東西中刪除的東西。

相關問題