使用 MVC 和 ASP.NET 身份进行 URL 授权

Posted

技术标签:

【中文标题】使用 MVC 和 ASP.NET 身份进行 URL 授权【英文标题】:Url Authorization with MVC and ASP.NET Identity 【发布时间】:2017-07-18 02:51:02 【问题描述】:

我想保护我的应用程序中位于我的 mvc 应用程序路由之外的特定文件夹和资源。我希望这些资源只对经过身份验证的用户可用(只要他们经过身份验证,哪个角色就无关紧要)。

最初,UrlAuthorizationModule 似乎是答案。我关注了这篇文章Understanding IIS 7.0 URL Authorization,我可以让模块在它响应web.config 中的配置元素的意义上工作。

我目前的问题是我认为它是基于 IIS 中的匿名用户而不是 asp.net identity 中的经过身份验证的用户来制定规则。

测试环境

我使用标准的html 文件进行测试,而不是尝试加载脚本,因为这也将在 MVC 管道之外加载。

Visual Studio 2015。 新的默认 .net 4.6.2 网络项目 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 路径中的所有内容始终被拒绝,无论用户是否通过身份验证。 如果我在web.config 中切换DenyAllow 的两行,情况也是如此。 如果我完全删除带有Deny 的行,那么即使用户未通过身份验证,也始终允许访问。 如果我添加一个角色并将roles 与角色名称一起使用而不是users 属性,则该角色也会被完全忽略。

现在呢?

我错过了什么?如何让 Url Authorization 模块与 MVC/WebAPI 和 ASP.NET Identity Individual user accounts 一起使用,或者这根本不可行?

我也对其他想法持开放态度,也许答案是编写自定义HttpModuleHttpHandler


旁注

原因和细节

这些资源是 javascript 文件,简而言之,未经身份验证的用户应该可以使用其中的一部分脚本。根目录中有 2 个目录,一个用于应用程序的已验证部分,一个用于应用程序的未验证部分。这样做的原因与应用程序中的用户授权或安全性无关,它是将应用程序的暴露表面区域限制为未经身份验证的请求。

【问题讨论】:

我没有使用 url 授权模块的经验,但是如果您使用 HttpModule,您可以在AuthorizeRequest 事件阶段检查用户是否已通过身份验证以及他想要访问哪个路径... @Legends - 我最初尝试了HttpModule,但在尝试与Asp.net Identity 集成时遇到了麻烦。我也希望我不必重新发明***。 你试过了吗:&lt;add accessType="Deny" users="?"/&gt; &lt;add accessType="Allow" users="*"/&gt;?如果这不起作用,则换行,不知道正确的顺序是什么。 @Legends - 我做到了,该设置在经过身份验证和未经过身份验证时都限制了对请求的访问。切换顺序没关系。 ? 用于匿名用户,* 用于经过身份验证的用户,添加语句的顺序也很重要,只是要清楚;-) 250 赏金,我相信有人会回答它。 ... 【参考方案1】:

[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">

使用runAllManagedModulesForAllRequests="true",所有 HTTP 模块都将在每个请求上运行,而不仅仅是托管请求(例如 .aspx、ashx)。这意味着模块将在每个 .jpg、.gif、.css、.html、.pdf、... 请求上运行。


一件重要的事情 您不必将 UrlAuthorizationModule 添加到模块部分,因为它已经是 ASP.NET 管道的一部分。这意味着,它将仅针对托管文件运行,而不是静态的!

如果您现在将 UrlAuthorizationModule 删除然后重新添加到模块部分,它将在前提条件“integratedMode”下运行,而不是在“managedHandler”下运行!因此可以访问静态文件。

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


如果将前提条件设置为托管: &lt;add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" /&gt;,那么 UrlAuthorizationModule 将不再限制对静态文件的访问。

您可以通过在注销时成功访问脚本文件夹中的脚本文件来测试这一点。按 Ctrl+F5 确保您获得脚本文件的新副本。


Difference between ASP.NET UrlAuthorization <--> IIS URL Authorization

记住 managedHandler 的前提条件很重要 位于 ASP.NET UrlAuthorization 模块上。前提告诉你 URL 授权模块仅在以下代码被调用时 处理请求被映射到托管代码,通常是 .aspx 或 .asmx 页面。另一方面,IIS URL 授权适用于所有 内容。您可以从 ASP.NET URL 授权模块。它在那里防止表演 每次请求时您必须支付的罚款(例如请求 .html 或 .jpg 页面)必须通过托管代码。

P.S.:一些 web.config 属性区分大小写!

【讨论】:

谢谢,使用您的解决方案我向后工作,直到我得到了我需要让它工作的更改。我将编辑您的帖子,完成后请在您认为合适的情况下进一步编辑。 所以我缺少的部分以及为什么authorization 元素从未有任何效果是因为我没有为我的受限文件类型注册HttpHandler。一旦我添加并使用了system.web 元素内的authorization 元素,一切都按预期工作。再次感谢。 我很高兴它有帮助 ;-) 不错的更新(250 名代表。当之无愧!) - 注意:FormsAuthentication 模块在这种情况下未启用,因为 aps.net 身份框架正在用于身份验证/授权。我在我的网站上运行了它,对FormsAuthentication 的唯一引用是删除它的行项目。 我已经删除了添加并保留了删除:D

以上是关于使用 MVC 和 ASP.NET 身份进行 URL 授权的主要内容,如果未能解决你的问题,请参考以下文章

使用 asp.net web api 令牌在 mvc 网站上进行身份验证

配置 ASP.NET MVC 以针对 AD 进行身份验证

使用 ASP.NET 5 MVC 6 Web API 进行 Cookie 身份验证

ASP.Net Core - 使用 WebAPI 和 MVC 前端的 JWT 身份验证不起作用

同时对 Asp.Net core 2.0 MVC 应用程序 (cookie) 和 REST API (JWT) 进行身份验证

在 asp.net mvc 5 中使用身份自定义用户和角色