How to Password Protect a PHP Website Directory in Azure
I’m taking a short break from thinking about testing PHP applications in Windows Azure (although, ultimately, this will tie into a post about testing). In this post, I’ll show one way that you can password protect a directory for a PHP website running in Windows Azure. When looking for a way to do this, my searches turned up approaches that involved creating a Windows user and granting the right permissions to that user…which seemed like more overhead than I wanted to incur. Then, I found this post by Ruslan Yakushev: How to Secure WordPress Admin Directory on IIS 7.0. I essentially followed that approach (but generically, not just for WordPress). The only hurdle to getting it working in Azure was figuring out how to install the URL Authorization Module, which isn’t installed by default on IIS in Azure.
I’ve tested the steps below when deploying a custom PHP installation to Azure and when using the default scaffold provided by the Windows Azure SDK for PHP (which uses the Web Platform Installer to install PHP).
Note: There really isn’t anything specific to PHP here. The one assumption I’ve made is that you have a resources\WebPICmdLine directory in your root that contains the Web PI command line tools (which is the case if you use the default scaffold or follow my post about packaging a custom PHP installation). With that in place, you can use this approach with any language.
1. Download the FormsAuthForWordPress.zip file from Ruslan’s post. After you have extracted the files, copy and paste the App_Data and App_Code directories and the login.aspx file into your project’s root directory.
2. Edit the users.xml file in the App_Data directory. You will need to supply the name of the user (and his/her password) who will have access to the secured directory:
<Users> <User> <UserName>user_name_here</UserName> <Password>password_here</Password> <EMail>user_email_here</EMail> </User> </Users>
3. Edit the web.config file. You’ll need to add (or add to) the following elements:
Add this to the <system.web> element:
<authentication mode="Forms" /> <membership defaultProvider="AspNetReadOnlyXmlMembershipProvider"> <providers> <add name="AspNetReadOnlyXmlMembershipProvider" type="ReadOnlyXmlMembershipProvider" description="Read-only XML membership provider" xmlFileName="~/App_Data/Users.xml" /> </providers> </membership>
Add this to the <configuration> element (replacing PrivateDir with the name of the directory you want to secure):
<location path="PrivateDir"> <system.webServer> <security> <authorization> <add accessType="Deny" users="?" /> </authorization> </security> </system.webServer> </location>
Add this to the <system.webserver> element:
<modules> <remove name="UrlAuthorization" /> <remove name="FormsAuthentication" /> <remove name="DefaultAuthentication" /> <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="" /> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="" /> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" /> </modules>
4. Add the following script (install-urlauthmodule.cmd) to your project’s bin directory:
@echo off cd ..\resources\WebPiCmdLine webpicmdline.exe /Products:URLAuthorization /AcceptEula
5. Edit your ServiceDefinition.csdef file so that install-urlauthmodule.cmd is called as a startup task. Add the following element as the last child element of the <Startup> element:
<Task commandLine="install-urlauthmodule.cmd" executionContext="elevated" taskType="simple" />
Now you are ready to package and deploy your application. After deployment, when you attempt to browse to http://yoursite.cloudapp.net/PrivateDir, you should be greeted with this login in dialog:
Supplying the username/password specified in the users.xml file will then take you to the default document for the PrivateDir directory. To understand how this works, I recommend reading Ruslan’s post: How to Secure WordPress Admin Directory on IIS 7.0.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)