2

我正在开发一个实现为静态 html 文件的单页应用程序,该文件向 Web Api Web 服务发出 AJAX 请求。它托管在 IIS 7.5 上。

当用户对自己的身份验证和 web api 服务(与网站共享相同的机器密钥)进行身份验证时,我无法在静态 html 文件上进行身份验证。

我基本上有一个带有静态 .html 文件的基本网站和一个带有 Web Api Web 服务的 asp.net 应用程序。大多数静态 html 文件应该只对经过身份验证的用户可用(具有有效 FormsAuthentication cookie 的请求,由 web api 应用程序中的 /api/login 路由发出),这些文件位于网站根目录下的“安全”文件夹中. Web Api ASP.NET 应用程序位于网站根目录下的“api”文件夹中:

WebsiteRoot/api/
secure/login.html 1.html 2.html

这很好用,像 1.html 这样的静态文件可以向 /api 路由下方的 web api 路由发出 AJAX 请求。现在我想将 1.html 和 2.html 移到 secure/ 中,以限制只有经过身份验证的用户才能访问它们。

Web api 服务本身使用 FormsAuthentication 来限制对服务路由的访问。用户通过向 /api/login(使用 [AllowAnnonymous] 配置)发出 AJAX 请求进行身份验证,现在我希望只有通过这种方式进行身份验证的用户才能被授予访问安全 / 文件夹中的静态 .html 文件的权限。

所以我的想法是这样的:

1) 确保 ASP.NET 管道处理对 .html 文件的请求。

2) 在静态网站中启用表单身份验证

3) 拒绝匿名访问 websiteroot/secure 文件夹。

4) 确保对 /api/login 进行身份验证时发出的 Auth cookie 对 /secure 文件夹上的身份验证机制也有效。

我已经尝试过这样做,但目前我被拒绝访问 websiteroot/secure 中的文件,即使请求已经过身份验证(它有一个由 web api 应用程序中的 /api/login 路由发出的 .ASPFORMSAUTHI cookie)

这是我所做的:我有 3 个 web.config 文件:1 个在 WebsiteRoot,1 个在 WebsiteRoot/api(Web api 应用程序的根)和 1 个在 WebsiteRoot/secure

为确保 4),我对 FormsAuthentication 进行了相同的配置,并在网站根目录和 websiteroot/api web.config 文件中使用了相同的机器密钥。cookie 的域在两个文件中设置为相同。

然后,为了确保 1),我将其添加到网站根 web.config 文件中,以确保 .html 文件(所有文件)由 ASP.NET 管道处理和验证:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
          <add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" />
          <remove  name="UrlAuthorization" />
          <add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />
          <remove  name="DefaultAuthentication" />
          <add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" />
    </modules>
</system.webServer>

以下是位于 websiteroot/api/ 的 web api 应用程序 web.config 文件中的相关内容:

<system.web>
<authentication mode="Forms">
  <forms name=".ASPXFORMSAUTH" protection="All" path="/" domain=".mydomain.com" timeout="7200" slidingExpiration="true" />
</authentication>
<machineKey validationKey="SAME_IN_BOTH_FILES" decryptionKey="SAME_IN_BOTH_FILES" validation="SHA1" decryption="AES" />
<roleManager enabled="true" defaultProvider="simple">
  <providers>
    <clear />
    <add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
  </providers>
</roleManager>
<membership defaultProvider="simple">
  <providers>
    <clear />
    <add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
  </providers>
</membership>
...

这是位于 websiteroot/ 的网站根 web.config 文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <authentication mode="Forms">
          <forms loginUrl="login.html" name=".ASPXFORMSAUTH" protection="All" domain=".mydomain.com" path="/" timeout="7200" slidingExpiration="true" />
        </authentication>
        <machineKey validationKey="SAME_IN_BOTH_FILES" decryptionKey="SAME_IN_BOTH_FILES" validation="SHA1" decryption="AES" />
    </system.web>
            <system.webServer>
                <modules runAllManagedModulesForAllRequests="true">
                      <add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" />
                      <remove  name="UrlAuthorization" />
                      <add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />
                      <remove  name="DefaultAuthentication" />
                      <add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" />
                </modules>
            </system.webServer>
</configuration>

这是位于 websiteroot/secure/ 中的 web.config 文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <authorization>
            <deny users="?" />
        </authorization>
    </system.web>
</configuration>

请注意,如果我改变

<deny users="?" /> 

<allow users="?" />  

然后我被授予访问 websiteroot/secure/ 中的 .html 文件的权限

所以我的问题是:

1) 当请求包含 /api/login 发出的 .ASPFORMSAUTH cookie 时,为什么对 /secure 的请求会被拒绝?

2) 对于如何制作静态网站,是否有替代解决方案,其中某些文件仅限于在同一站点上通过 Web api 服务进行身份验证的用户?

4

1 回答 1

4

我相信您已经意识到,但是您面临的问题与真正的 WebAPI 环境中的无会话有关。表单身份验证基于保存在客户端的会话 cookie,并由服务器端在每个后续请求中进行解释。

如果您通过 WebAPI 调用进行身份验证,则需要直接处理 cookie 的创建/读取。使用这种真正的 RESTful 实现的主要好处之一是您不应该真正拥有“会话”本身。

在我的应用程序中,我处理此问题的方法之一是使用唯一标识我的用户身份的数据密钥 - 然后将其存储在客户端的 cookie 中,以只有我的服务器可以理解的方式加密。我不会在这里讨论安全要求 - 因为有更好的论坛供您查看有关如何加密/解密等方面的信息 - 但基本交易是这样的:

  1. 当您的客户进行身份验证时,为他们创建一个安全的 cookie
  2. 为您的对象创建一个基类,该基类Controller知道如何解释该 cookie

然后,执行以下操作之一:

1)为您的静态内容创建一个消息处理程序,该处理程序还根据您设置的cookie处理身份验证 - 并检查对静态文件的权限......

或者 2) 创建一个新Controller的,它有一个可以为您的静态内容提供服务的操作。这样做的好处是能够从您的基本控制器类继承并从第 2 步免费获得身份验证。

于 2013-02-28T20:25:15.740 回答