在 Azure Web 应用程序中使用重写规则获取权限错误

Getting permission error with rewrite rules within Azure web app

我有一个基于 Laravel 4 的 PHP 应用程序,我已经成功地在 Azure 网络应用程序中运行,我遇到的唯一问题是尝试从 example.azurewebsites.net/js/vendor/jquery.slicknav.min.js 我收到 "You do not have permission to view this directory or page." 回复。

文件夹 site/wwwroot 是我放置所有 Laravel 应用程序文件的地方,对于那些不熟悉 Laravel 的人,它包含四个文件夹:app、Bootstrap、public,和供应商。

我已在 Azure 门户中设置 虚拟应用程序和目录 设置以将 / 映射到 site\wwwroot\public 并放置在 public 中目录一个 web.config 文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>
        <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="true"/>
        <staticContent>
            <remove fileExtension=".svg" />
            <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
            <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
            <clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
        </staticContent>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type" />
                <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,DELETE,PUT,PATCH" />
            </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <rule name="Laravel4" stopProcessing="true">
                    <match url="^" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>    
    </system.webServer>
</configuration>

通过此设置,重写将按预期进行,除非文件夹名称包含应用程序、Bootstrap、public 或供应商,就像在 example.azurewebsites.net/js/vendor/jquery.slicknav.min.js.[=26 中一样=]

我的问题是如何修改我的重写规则来解决这个问题?如果我通过在末尾添加连字符来重命名文件夹 site\wwwroot\public\js\vendor\,它将起作用。我也多次重启容器。

编辑 为了更清晰,这是我的目录结构:

├─ wwwroot
│  └─ app
│  └─ bootstrap
│  ├─ public
│  │  └─ css
│  │  └─ files
│  │  └─ fonts
│  │  └─ imgs
│  │  ├─ js
│  │  │  └─ admin
│  │  │  ├─ app
│  │  │  │  └─ link-check.js
│  │  │  └─ old
│  │  │  ├─ vendor
│  │  │  │  └─ sortable.min.js
│  │  └─ less
│  │  └─ packages
│  │  └─ tmp
│  │  └─ uploads
│  └─ vendor
└─ ...

使用我的 web.config 配置 link-check.js 可通过 example.azurewebsites.net/js/app/link-check.js 访问,而 sortable.min.js 不能 通过 [=21= 访问](并且 /js/vendor 路径中的任何其他内容都不可访问)。

注意:如果我将 wwwroot\public\js\vendor 重命名为 wwwroot\public\js\vendor-,我可以从 example.azurewebsites.net/js/vendor-/sortable.min.js

查看 sortable.min.js

您可以尝试以下步骤:

  • 虚拟应用程序和目录 部分中的设置修改回映射 /site\wwwroot\

  • public文件夹中的web.config移动到根目录,可能是服务器中的site\wwwroot

  • web.config内容修改为以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Rewrite routed access to assets(img, css, files, js, favicon)"
                  stopProcessing="true">
                    <match url="^(img|css|files|js|favicon.ico)(.*)$" />
                </rule>
                <rule name="Imported Rule 1">
                    <match url="^(.*)$" ignoreCase="false" />
                    <action type="Rewrite" url="/public/{R:1}" />
                </rule>
                <rule name="Imported Rule 2" stopProcessing="true">
                    <match url="^(.*)$" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" 
                                matchType="IsFile" 
                                ignoreCase="false" 
                                negate="true" />
                        <add input="{REQUEST_FILENAME}" 
                                matchType="IsDirectory" 
                                ignoreCase="false" 
                                negate="true" />
                    </conditions>
                    <action type="Rewrite" url="public/index.php/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

事实证明,路径中所有带有 vendor 的文件夹返回 403 禁止的原因是我有 Azure composer web app extension installed。在该扩展的 applicationHost.xdt 文件中,它设置了以下重写:

<rewrite xdt:Transform="InsertIfMissing">
  <rules xdt:Transform="InsertIfMissing">
    <rule name="RequestBlockingRule1" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{URL}" pattern="vendor/(.*)$" />
                </conditions>
                <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to     view this directory or page using the credentials that you supplied." />
            </rule>
  </rules>
</rewrite>

对我来说,删除扩展显然解决了问题,但我觉得在我的重写规则部分添加 <clear/> 会清除扩展设置的规则并解决问题。

为了将来参考,此问题是针对 7th Nov 2015 and on the 23rd July 2015 上的扩展提出的。

下面显示了我修改后的 web.config,它使用 <clear/> 来解决问题

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>
        <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="true"/>
        <staticContent>
            <remove fileExtension=".svg" />
            <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
            <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
            <clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
        </staticContent>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type" />
                <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,DELETE,PUT,PATCH" />
            </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <clear/>
                <rule name="Laravel4" stopProcessing="true">
                    <match url="^" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>    
    </system.webServer>
</configuration>

我在 webconfig 中添加了 clear 并为我工作。

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Imported Rule 1" stopProcessing="true">
          <match url="^(.*)/$" ignoreCase="false" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
          </conditions>
          <action type="Redirect" redirectType="Permanent" url="/{R:1}" />
        </rule>
         <clear/>
        <rule name="Imported Rule 2" stopProcessing="true">
          <match url="^" ignoreCase="false" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
          </conditions>
          <action type="Rewrite" url="index.php" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>