Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting permission error with rewrite rules within Azure web app

I have a Laravel 4 based PHP application that I have successfully gotten working within an Azure web app, the only issue that I am having is when attempting to access files from example.azurewebsites.net/js/vendor/jquery.slicknav.min.js I get a "You do not have permission to view this directory or page." Response.

The folder site/wwwroot is where I place all my Laravel application files, for those not familiar with Laravel it contains four folders: app, Bootstrap, public, and vendor.

I have set the Virtual applications and directories setting in the Azure portal to map / to site\wwwroot\public and placed within the public directory a web.config file with the following content:

<?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>

With this set up the rewrite works as expected except when the folder name includes either app, Bootstrap, public, or vendor as it does with example.azurewebsites.net/js/vendor/jquery.slicknav.min.js.

My question is how do I amend my rewrite rules to fix this issue? If I rename the folder site\wwwroot\public\js\vendor\ by adding a hyphen to the end, it will work. I have also rebooted the container multiple times.

Edit For more clarity this is my directory structure:

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

With my web.config configuration link-check.js is accessible via example.azurewebsites.net/js/app/link-check.js while sortable.min.js is not accessible via example.azurewebsites.net/js/vendor/sortable.min.js (and nothing else within the /js/vendor path is accessible).

Note: if I rename wwwroot\public\js\vendor to wwwroot\public\js\vendor- I can view sortable.min.js from example.azurewebsites.net/js/vendor-/sortable.min.js

like image 711
carbontwelve Avatar asked Feb 03 '16 12:02

carbontwelve


2 Answers

It turns out the reason for all folders with vendor in the path returning a 403 forbidden was that I had the Azure composer web app extension installed. Within the applicationHost.xdt file for that extension it sets the following rewrite:

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

For me removing the extension obviously fixed the problem, however I have a feeling that adding a <clear/> to my rewrite rules section would clear the rules set by the extension and fix the issue.

For future reference this issue was raised against the extension on 7th Nov 2015 and on the 23rd July 2015.

Below shows my amended web.config that uses <clear/> to fix the problem

<?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>
like image 56
carbontwelve Avatar answered Sep 22 '22 23:09

carbontwelve


You can try the following steps:

  • modify the setting in Virtual applications and directories section back to mapping / to site\wwwroot\

  • move your web.config in the public folder to the root directory which may be the site\wwwroot in your server.

  • modify the web.config content to the following content:

<?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>
like image 32
Gary Liu Avatar answered Sep 22 '22 23:09

Gary Liu