Url MVC 授权和 ASP.NET 身份
Url Authorization with MVC and ASP.NET Identity
我想保护我的应用程序中位于我的 mvc 应用程序路由之外的特定文件夹和资源。我希望这些资源仅对经过身份验证的用户可用(只要经过身份验证,哪个角色无关紧要)。
最初似乎 UrlAuthorizationModule would be the answer. I followed this article, Understanding IIS 7.0 URL Authorization,我可以让模块工作,因为它响应 web.config
中的配置元素。
我目前的问题是我认为它是根据 IIS 中的匿名用户而不是 asp.net identity 中的经过身份验证的用户制定规则的。
测试环境
我使用标准 html
文件进行测试,而不是尝试加载脚本,因为这也会在 MVC 管道之外加载。
- 在
Visual Studio 2015
。
- 新建默认
.net 4.6.2
web 项目
- 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
. 中切换 Deny
和 Allow
的 2 行,也是如此
- 如果我完全删除带有
Deny
的行,那么即使用户未通过身份验证也始终允许访问。
- 如果我添加角色并使用
roles
和角色名称而不是 users
属性,角色也会被完全忽略。
现在怎么办?
我错过了什么?我怎样才能得到 Url Authorization module to work with MVC/WebAPI and ASP.NET Identity Individual user accounts
或者这根本不可行?
我也对其他想法持开放态度,也许答案是编写自定义 HttpModule
或 HttpHandler
?
旁注
原因和细节
这些资源是 javascript 个文件,简而言之,只有一部分脚本应该可供未经身份验证的用户使用。根目录中有 2 个目录,一个用于应用程序的认证部分,一个用于应用程序的非认证部分。这样做的原因与应用程序中的用户授权或安全无关,它是为了将应用程序的暴露表面区域限制为未经身份验证的请求。
[TL;DR;]
转到 "Complete root web.config" 部分查看所需的 web.config 设置。
在隐身模式下测试以防止浏览器缓存问题!
并使用 Ctrl+F5
因为脚本和 html 文件被缓存。
首先拒绝根目录下所有匿名用户的访问web.config。
<authorization>
<deny users="?"/>
</authorization>
这里的web.config允许一个文件夹public仅可访问。在我的示例中,此文件夹名为 css
,位于 MVC 应用程序的根目录中。对于 css 文件夹,我将以下授权添加到根 web.config:
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
如果您想要更多 public 个文件夹,可以添加更多这些位置路径。
虽然在用户登录之前无法访问所有其他文件,但 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" />
如果将前提条件设置为托管:
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
,那么 UrlAuthorizationModule 将不再限制对静态文件的访问。
您可以通过在注销时成功访问脚本文件夹中的脚本文件来对此进行测试。按 Ctrl+F5 以确保您获得脚本文件的新副本。
Difference between ASP.NET UrlAuthorization <--> IIS URL Authorization
It is important to keep in mind that the managedHandler precondition
is on the ASP.NET UrlAuthorization module. The precondition tells you
that the URL authorization module is invoked only when the code that
handles the request is mapped to managed code, typically an .aspx or
.asmx page. IIS URL Authorization, on the other hand, applies to all
content. You can remove the managedHandler precondition from the
ASP.NET Url Authorization module. It is there to prevent a performance
penality you have to pay when every request (such as a request to
.html or .jpg pages) would have to go through managed code.
P.S.: 部分web.config属性区分大小写!
我想保护我的应用程序中位于我的 mvc 应用程序路由之外的特定文件夹和资源。我希望这些资源仅对经过身份验证的用户可用(只要经过身份验证,哪个角色无关紧要)。
最初似乎 UrlAuthorizationModule would be the answer. I followed this article, Understanding IIS 7.0 URL Authorization,我可以让模块工作,因为它响应 web.config
中的配置元素。
我目前的问题是我认为它是根据 IIS 中的匿名用户而不是 asp.net identity 中的经过身份验证的用户制定规则的。
测试环境
我使用标准 html
文件进行测试,而不是尝试加载脚本,因为这也会在 MVC 管道之外加载。
- 在
Visual Studio 2015
。- 新建默认
.net 4.6.2
web 项目 - 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
. 中切换 - 如果我完全删除带有
Deny
的行,那么即使用户未通过身份验证也始终允许访问。 - 如果我添加角色并使用
roles
和角色名称而不是users
属性,角色也会被完全忽略。
Deny
和 Allow
的 2 行,也是如此
现在怎么办?
我错过了什么?我怎样才能得到 Url Authorization module to work with MVC/WebAPI and ASP.NET Identity Individual user accounts
或者这根本不可行?
我也对其他想法持开放态度,也许答案是编写自定义 HttpModule
或 HttpHandler
?
旁注
原因和细节
这些资源是 javascript 个文件,简而言之,只有一部分脚本应该可供未经身份验证的用户使用。根目录中有 2 个目录,一个用于应用程序的认证部分,一个用于应用程序的非认证部分。这样做的原因与应用程序中的用户授权或安全无关,它是为了将应用程序的暴露表面区域限制为未经身份验证的请求。
[TL;DR;]
转到 "Complete root web.config" 部分查看所需的 web.config 设置。
在隐身模式下测试以防止浏览器缓存问题!
并使用 Ctrl+F5
因为脚本和 html 文件被缓存。
首先拒绝根目录下所有匿名用户的访问web.config。
<authorization>
<deny users="?"/>
</authorization>
这里的web.config允许一个文件夹public仅可访问。在我的示例中,此文件夹名为 css
,位于 MVC 应用程序的根目录中。对于 css 文件夹,我将以下授权添加到根 web.config:
<location path="css">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
如果您想要更多 public 个文件夹,可以添加更多这些位置路径。
虽然在用户登录之前无法访问所有其他文件,但 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" />
如果将前提条件设置为托管:
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
,那么 UrlAuthorizationModule 将不再限制对静态文件的访问。
您可以通过在注销时成功访问脚本文件夹中的脚本文件来对此进行测试。按 Ctrl+F5 以确保您获得脚本文件的新副本。
Difference between ASP.NET UrlAuthorization <--> IIS URL Authorization
It is important to keep in mind that the managedHandler precondition is on the ASP.NET UrlAuthorization module. The precondition tells you that the URL authorization module is invoked only when the code that handles the request is mapped to managed code, typically an .aspx or .asmx page. IIS URL Authorization, on the other hand, applies to all content. You can remove the managedHandler precondition from the ASP.NET Url Authorization module. It is there to prevent a performance penality you have to pay when every request (such as a request to .html or .jpg pages) would have to go through managed code.
P.S.: 部分web.config属性区分大小写!