2012-11-27 61 views
1

HttpConext對象具有SkipAutorization property,用於禁用UrlAuthorizationModule中的授權檢查,UrlAuthorizationModule是標準asp.net管道的一部分。使用ImageResizer跳過授權的正確方法

ImageResizer直接調用UrlAuthorizationModule.CheckUrlAccessForPrincipal,在正常的asp.net管道之外。因此,SkipAutorization屬性不受尊重。

的解決方法,這將是:

protected void Application_Start(object sender, EventArgs e) 
{ 
    // Ask ImageResizer not to re-check authorization if it's skipped 
    // by means of the context flag 
    Config.Current.Pipeline.OnFirstRequest += 
     (m, c) => 
     { 
      Config.Current.Pipeline.AuthorizeImage += 
       (module, context, args) => 
        { 
         if (context.SkipAuthorization) 
         { 
          args.AllowAccess = true; 
         } 
        }; 
     }; 
} 

這裏的外OnFirstRequest是要確保AuthorizeImage訂閱正在發生的所有插件後,已被載入所以它最後在鏈執行。

因爲它是相當依賴於實現的,我不喜歡這種解決方法。例如,如果ImageResizer插件加載從onFirstRequest移動到其他地方,它將會中斷。

如果固定在ImageResizer本身這將是很好。我會建議沿着這些線路改變附加Autorization檢查中InterceptModule的東西:

//Run the rewritten path past the auth system again, using the result as the default "AllowAccess" value 
bool isAllowed = true; 
if (canCheckUrl) try { 
     isAllowed = conf.HonourSkipAutorization && app.Context.SkipAuthorization 
        || UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtualPath, user, "GET"); 
    } catch (NotImplementedException) { } //For MONO support 

請問這是否合適,或者是有沒有更好的解決辦法?

在問題的最後部分,我將描述我的用例,閱讀完全是可選的,但它給出了這個查詢是如何產生的。

在asp.net應用程序我有一個服務的PDF文檔一個HttpHandler。它接受URL和標題中的文檔ID和安全信息(我使用OAuth),它執行所有安全檢查,如果它們成功,則從數據庫中檢索pdf文檔路徑,並通過Response將文件提供給客戶端。 WriteFile的。

我需要提供PDF頁面預覽作爲圖像,並且我正在使用ImageResize和PdfRenderer插件。

不幸的是,直到我的文件處理程序已經運行,pdf的路徑才知道,這對於ImageResizer對請求採取行動來說太遲了,因爲所有的魔法都發生在PostAuthorizeRequest中,這顯然是在處理程序運行之前發生的。

要解決此問題,我將HttpHandler重寫爲HttpModule,它在BeginRequest上執行。如果授權檢查失敗,請求將在那裏被切斷。如果他們沒問題,那麼我使用PathRewrite指向生成的pdf,同時將正確的Content-Type和其他頭文件寫入響應。同時,我設置了context.SkipAutorization標誌,因爲由於根據web.config配置,pdf文件無法通過直接url訪問,所以如果不跳過授權,管道甚至不會訪問PostAuthorizeRequest。在這種情況下跳過授權是安全的,因爲所有必需的檢查已經由模塊執行。

所以這允許執行流程到達ImageResizer。但是,然後,圖片調整器決定它要重新檢查pdf網址上的授權。除非您應用上述解決方法,否則將失敗。

,這是什麼重新檢查的原理是什麼?在上面的場景中,當ImageResizer有工作要做時,它所服務的圖像不是URL中出現的圖像,而且現在當我們處於PostAuthorizeRequest中時,已經由asp.net管道完成auth檢查。在這種情況下,這種重新檢查有用嗎?

回答

1

更新:ImageResizer的最新版本尊重HttpContext.SkipAuthorization布爾值,不再需要事件處理程序。


你的解決辦法是精確地處理這個正確的方式,並且是前鋒,comaptible。存在

重新檢查因爲

  1. 地址重寫是很常見的,鼓勵,甚至某些ImageResizer插件(如FolderResizeSyntax和ImageHandlerSyntax)來實現。
  2. 在授權階段之後的URL重寫允許完全規避UrlAuthorization。

HttpContext.SkipAuthorization 應該被ImageResizer尊重;並可能將在未來的版本中。

這就是說,你的解決方法涉及AuthorizeImage實際上正是我所暗示的。我不明白它本身如何比SkipAuthorization更脆弱;事實上,無論ImageResizer將來如何重新排序事件,都應該可以工作。

ImageResizer尊重管道中的事件順序 - 在PostAuthorize之前發生授權的V2是完全正確的(儘管如果您希望在BeginRequest期間支持額外的前端調整大小,它可以移動到PreAuthorize)。

此外,使用RewritePath來提供原始PDF比調用WriteFile更有效率,尤其是在IIS6 +上,正如您可能發現的那樣。

+0

感謝您的快速響應。這一切都非常有意義。只有一個想法我想澄清。我認爲工作很脆弱的原因是.net中的代表在返回/更改值時不能很好地工作。特別是,任何插件都可以根據需要將AllowAccess設置爲true或false。 –

+0

在這種情況下,鏈中的最後一個插件將獲勝。哪一個委託最後是由訂閱的順序決定的,所以至關重要的是a)在加載插件之後執行工作站中的OnFirstRequest,以及b)在所有插件訂閱之後,工作周圍的AuthorizeImage被訂閱。通常很難找到處理程序添加到委託的確切順序。在目前的實施中,這是完全正確的,但我相信這可能會在不經意間改變 –

+1

啊,我明白你的意思了。現在唯一使用AuthorizeImage的官方插件是DiskCache,它爲直接定位緩存的請求設置DenyRequest = true。在你的情況下,除非你爲/ imagecache/url設置.SkipAuthorization,否則順序並不重要。 –