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
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.
<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>
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With