首页 文章

如何为单页面应用程序/静态html网站和Web api服务组合ASP.NET窗体身份验证

提问于
浏览
2

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

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

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

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

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

Web api服务本身使用FormsAuthentication来限制对服务路由的访问 . 用户通过向/ api / login(使用[AllowAnnonymous]配置)发出AJAX请求进行身份验证,现在我只希望以这种方式通过身份验证的用户可以访问secure /文件夹中的静态.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文件:WebsiteRoot中的1个,WebsiteRoot / api中的1个(web api应用程序的根目录)和WebsiteRoot中的1个/ secure

为了确保4),我已经相同地配置了FormsAuthentication,并在网站根目录和websiteroot / api web.config文件中使用了相同的machoine密钥 . 在两个文件中,cookie的主要部分设置为相同 .

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

<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时,为什么请求/安全被拒绝?

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

1 回答

  • 4

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

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

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

    • 在客户端进行身份验证时为其创建安全Cookie

    • Controller 对象创建一个基类,该基类知道如何解释该cookie

    然后,做其中一个以下:

    1)为静态内容创建一个message handler,它还根据您设置的cookie处理身份验证 - 并检查静态文件的权限...

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

相关问题