2010-12-16 81 views
13

之前,我有一個控制器的ASP.NET MVC應用程序,它看起來是這樣的:ASP.NET MVC的控制器構造函數調用驗證

[Authorize] 
public class MyController : Controller 
{ 
IMyRepository myRepository; 
public MyController(IMyRepository myRepository) 
{ 
    this.myRepository = myRepository; 
} 

... 
} 

我注意到,這個構造函數將之前驗證用戶調用,所以如果你第一次訪問該頁面,在將你重定向到登錄屏幕之前調用構造函數。這有很多問題,登錄頁面加載速度較慢,網站對DOS攻擊的暴露程度更高,對於未經認證的未經授權的用戶能夠調用幕後代碼的說法,我有點緊張。

我可以在構造函數和保釋中檢查包含的請求,除非用戶被授權,但我使用IOC(Windsor),這使得有點棘手,我的存儲庫將被初始化,無論我是否與I存儲實例,所以我將在每個存儲庫的構造函數中檢查身份驗證。有沒有簡單的方法讓.NET MVC認證用戶之前的來調用構造函數?我在想像是將[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]添加到控制器,但可能還有更好的方法。

編輯:

好了,心裏很不是滋味,但演出必須繼續現在。我不能延遲初始化存儲庫,直到從控制器中稍後的某個時間點開始。當你的控制器像我的例子那樣使用IOC時,在控制器被實例化的時候,你已經實例化了你的版本庫接口。如果我可以控制創建的存儲庫,那麼我可以輕鬆地調用IsAuthenticated,不需要新的方法。爲了控制資源庫的初始化,你必須在每個實現中在資源庫本身中實現某種延遲/延遲初始化。我不喜歡這個解決方案,因爲它增加了不必要的複雜性,更重要的是控制器和存儲庫之間的耦合。存儲庫實現可以用在懶惰初始化沒有意義的其他上下文中。

+1

假設您的IMyRepository實現的構造函數是輕量級的,那麼在這裏我不會看到一個主要問題(即,如果將實際連接設置爲您的後備存儲是昂貴的過程,那麼請懶惰地執行,即首次讀取/寫入)。您不再通過登錄頁面暴露這種情況,因爲它也在實例化控制器,並可能訪問後備存儲以驗證憑據。 – Lazarus 2010-12-16 12:34:39

+1

@Lazarus但是如果對我的控制器的依賴需要訪問非空的用戶名(即用戶需要在那一點進行認證)會怎麼樣?目前我正在使用一個'懶惰的'實例,但我討厭它。我認爲在他到達控制器之前認證用戶是非常有意義的。 – julealgon 2015-06-09 00:02:51

回答

0

保羅,

控制器的實例化是未來該控制器可調用的任何行動的許多許多的進程。即使攻擊者試圖從實例化和登錄屏幕之間的時間間隔中受益,控制器動作也只能在動作有權這樣做時才能運行,即我假設你的動作或控制器都是在它們上面有[Authorize]屬性。

我不認爲你需要太擔心這件事,可以輕鬆休息,我明白你明顯的好奇心。

4

控制器需要在授權發生之前實例化,因爲它可以通過OnAuthorization方法充當自己的授權過濾器。改變這種行爲將涉及替換mvc管道的一些核心部分。爲什麼你認爲AuthorizedAttribute可能無法完成工作,是否有特殊原因?

+0

我的控制器有相當重的構造函數,我不希望未經身份驗證的用戶能夠啓動代碼。我明白授權不能在控制器實例化之前發生,我只是想事先進行認證。當我完成時,我會發布我在這裏找到的任何內容。 – Paul 2010-12-16 22:44:17

+0

哦,如果你只是想阻止未經身份驗證的用戶訪問你的控制器,那麼你可以考慮編寫一個自定義的路由,這個路由與未經身份驗證的客戶端不匹配。 – marcind 2010-12-16 22:57:15

+2

您可以考慮的另一個選擇是在您的控制器方法的OnActionExecuting中初始化您的存儲庫,而不是在構造函數中。 – marcind 2010-12-17 00:35:48

0

就DOS攻擊而言,它真的不應該出現 - 在第一次打擊後,開發人員會看到很多,控制器實例化應該便宜。那麼,除非你讓構造函數做實際的工作,比如預緩存數據庫查找,否則就是DDOS。 。 。