Asp.net

使用 MVC 和 ASP.NET 身份進行 URL 授權

  • June 1, 2020

我想保護我的應用程序中位於我的 mvc 應用程序路由之外的特定文件夾和資源。我希望這些資源只對經過身份驗證的使用者可用(只要他們經過身份驗證,哪個角色並不重要)。

最初似乎UrlAuthorizationModule將是答案。我關注了這篇文章,了解 IIS 7.0 URL 授權,我可以讓模組在它響應web.config.

我目前的問題是我認為它是基於 IIS 中的匿名使用者而不是asp.net identity中的經過身份驗證的使用者來製定規則。

測試環境

我使用標准html文件進行測試,而不是嘗試載入腳本,因為這也將在 MVC 管道之外載入。

  • Visual Studio 2015.

    • 新的預設.net 4.6.2Web 項目
    • MVC 模板
    • 身份驗證 =Individual User Accounts
  • IIS 8(用於在 Visual Studio 之外進行測試

    • 身份驗證 -> 匿名身份驗證(已啟用)

添加web.config

<configuration>
...
<location path="Data">
 <system.webServer>
   <security>
     <authorization>
       <clear/>
       <add accessType="Deny" users="*"/>
       <add accessType="Allow" users="?"/>
     </authorization>
   </security>
 </system.webServer>
</location>
...
</configuration>

添加到文件夾結構

/Data/Protected.html // this file just has some basic Hello World content to display so you can see if it is loaded or not.

觀察結果

  • 使用此配置,Data路徑中的所有內容始終被拒絕,使用者是否經過身份驗證都沒有關係。
  • 如果我將 2 行切換為DenyAllow,情況也是如此web.config
  • 如果我完全刪除該行,Deny則即使使用者未通過身份驗證,也始終允許訪問。
  • 如果我添加一個角色並使用roles角色名稱而不是users屬性,則該角色也將被完全忽略。

怎麼辦?

我錯過了什麼?如何讓Url Authorization模組與 MVC/WebAPI 和ASP.NET Identity Individual user accounts一起使用,或者這根本不可行?

我也對其他想法持開放態度,也許答案是編寫自定義HttpModuleHttpHandler


旁注

為什麼和細節

這些資源是 javascript 文件,簡而言之,未經身份驗證的使用者應該可以使用其中的一部分腳本。根目錄中有 2 個目錄,一個用於應用程序的已驗證部分,一個用於應用程序的未驗證部分。這樣做的原因與應用程序中的使用者授權或安全性無關,它是將應用程序的暴露表面區域限制為未經身份驗證的請求。

$$ TL;DR; $$

轉到**“完成根 web.config”**部分以查看所需的 web.config 設置。

在隱身模式下進行測試以防止瀏覽器記憶體問題! 並使用Ctrl+F5,因為腳本和 html 文件被記憶體。

首先在根 web.config 中拒絕所有匿名使用者的訪問。

<authorization>
   <deny users="?"/>        
</authorization>

這裡的 web.config 允許一個文件夾可以公開 訪問。在我的範例中,此文件夾被呼叫css並位於 MVC 應用程序的根目錄中。對於 css 文件夾,我將以下授權添加到根 web.config:

<location path="css">
   <system.web>
       <authorization>          
           <allow users="*"/>
       </authorization>
   </system.web>
</location>

如果您需要更多公用文件夾,可以添加更多這些位置路徑。

雖然在使用者登錄之前無法訪問所有其他文件,但 css 文件夾及其內容將始終可以訪問。

我還在根 web.config 中添加了一個靜態文件處理程序,這很關鍵,因為您希望特定文件類型的請求由 asp.net 管道管理

<handlers>
   <add name="HtmlScriptHandler" path="*.html" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
</handlers> 

完成根 web.config

<system.web>
   <authentication mode="None" />
   <authorization>
       <deny users="?"/>        
   </authorization>
   <compilation debug="true" targetFramework="4.6.2" />
   <httpRuntime targetFramework="4.6.2" />
</system.web>
<location path="css">
   <system.web>
       <authorization>          
           <allow users="*"/>
       </authorization>
   </system.web>
</location>
<system.webServer>
   <modules>
       <remove name="FormsAuthentication" />           
       <remove  name="UrlAuthorization" />
       <add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />     
   </modules>
   <handlers>
       <add name="HtmlScriptHandler" path="*.html" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" />
   </handlers>      
</system.webServer>

預設情況下,ASP.NET 只會將允許和拒絕規則應用於託管處理程序處理的文件。靜態文件不由託管處理程序管理。

你也可以設置:(不要這樣做,如果不是真的需要!

<modules runAllManagedModulesForAllRequests="true">

所有 HTTP 模組都將在runAllManagedModulesForAllRequests="true"每個請求上執行,而不僅僅是託管請求(例如 .aspx、ashx)。這意味著模組將在每個 .jpg 、.gif 、.css 、.h​​tml、.pdf ……請求上執行。


一件重要的事情

您不必將 UrlAuthorizationModule 添加到模組部分,因為它已經是 ASP.NET 管道的一部分。這意味著,它將僅針對託管文件執行,而不是靜態的!

如果您現在刪除然後將 UrlAuthorizationModule 重新添加到模組部分,它將在前提條件“integratedMode”下執行,而不是在“managedHandler”下執行!因此可以訪問靜態文件。

<remove  name="UrlAuthorization" />
<add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />

如果您將前提條件設置為 managed: <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />,則 UrlAuthorizationModule 將不再限制對靜態文件的訪問。

您可以通過在註銷時成功訪問腳本文件夾中的腳本文件來測試這一點。按 Ctrl+F5 以確保您獲得腳本文件的新副本。


ASP.NET UrlAuthorization <–> IIS URL授權之間的區別

請務必記住,managedHandler 前提條件位於 ASP.NET UrlAuthorization 模組上。前提條件告訴您,僅當處理請求的程式碼映射到託管程式碼(通常是 .aspx 或 .asmx 頁面)時,才會呼叫 URL 授權模組。另一方面,IIS URL 授權適用於所有內容。您可以從 ASP.NET Url Authorization 模組中刪除 managedHandler 前提條件。當每個請求(例如對 .html 或 .jpg 頁面的請求)都必須通過託管程式碼時,它可以防止您必須支付的性能損失。

PS:一些 web.config 屬性區分大小寫!

引用自:https://stackoverflow.com/questions/42486638