Installing WordPress in a subdirectory in a .NET application

When you install WordPress as a root web app using Web Platform Installer, everything just works.  However, adding a WordPress blog to a subdirectory (e.g. /blog) needs quite a few extra steps beyond the base install to get everything ‘working’.

Installing PHP

I used the PHP 7 32 bit. Before installing it you will need the Visual C++ Redistributable (again 32 bit)!

https://www.microsoft.com/en-gb/download/details.aspx?id=48145

Web.config in sub directory

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
      <clear/>
      <rule name="wordpress" patternSyntax="Wildcard">
        <match url=".*"/>
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
          </conditions>
        <action type="Rewrite" url="index.php"/>
      </rule></rules>
    </rewrite>
  </system.webServer>
</configuration>

Web.config in root

No changes required

Permissions

The web.config in the root must have a few permissions added to it before things will work. Add IUSR(Should already by on) and IIS_IUSRS. This will allow the subdirectory to access the parent.

Virtual Application and App Pool

  • Remove the default application and app pool that the wordpress install created.
  • Create a new app pool (unmanaged code) and set the Identity (advanced settings) to LocalSystem
  • Re-add the virtual application and ensure you use the new app pool created above.

Uploads and Imports

To enable uploads to work I had to make a few changes

  • Php uploads to C:\Windows\Temp and then copies to the uploads directory. The problem is that the permissions get inherited. Create a new directory, add IIS_IUSRS permissions and update PHPini.php to point to this as the temp uploads folder.
  • Also in the wp-admin directory I found I needed to add a new phpini.php to allow for better memory management, as a relatively small data import would cause it to tank. Not sure if this is a required step but it seemed to help!
<?php

 phpinfo()

?>

memory_limit = 128M

Summary

So there you have it. There is definitely a learning curve to this if you’re not from PHP land, but overall the installation seems to be working!

Resources

A selection of resource that came in very handy to making this all happen!

http://serverfault.com/questions/613927/500-error-on-fresh-install-of-iis-and-php

http://www.mbrauchler.com/wordpress-image-upload-problem-using-iis-on-windows-server-2008/

https://wordpress.org/support/topic/iis-image-upload-view-issues

http://stackoverflow.com/questions/14966871/second-wordpress-installation-on-iis-server

https://wordpress.org/support/topic/wordpress-installation-on-root-folder-sub-folder-on-iis-server-url-conflict?replies=5

Web deploy and TLS V1.0

Recently I have been using the excellent IISCrypto tool to lock down some servers for PCI compliance. One of the main steps in this process was to close off TLS V1.0.  In the past on Windows 2008R2, this was a problem as disabling it used to kill RDP services too. However on Windows 2012 boxes, the default is TLS V1.2 so you can safely do this.

The gotcha came when using web deploy to push my applications to this server, connections failed to the server. This was a client issue. By default, my Windows 10 install seems to be defaulting to TLS V1.0.

To fix the issue, a registry edit is required.  Simply create a .reg file with the exact content below, run it, happy days again.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

CallerMemberName attribute

Recently I created a WebApi where the client wanted to know what the original method name was when getting a response back.

I found a cool way to do it which .NET 4.5 offers.

The [CallerMemberName] attribute can be added as an optional parameter to any method and give you access to the calling methods name.

public class SomeClass
{
    public void SomeMethod([CallerMemberName]string memberName = "")
    {
        Console.WriteLine(memberName); //output will me name of calling method
    }
}

You can access some other useful properties too such as line number and even file path

public void TraceMessage(string message,
        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
    System.Diagnostics.Trace.WriteLine("message: " + message);
    System.Diagnostics.Trace.WriteLine("member name: " + memberName);
    System.Diagnostics.Trace.WriteLine("source file path: " + sourceFilePath);
    System.Diagnostics.Trace.WriteLine("source line number: " + sourceLineNumber);
}

OAuth Facebook, Twitter, LinkedIn, Instagram and more with WebApi and Identity 2

The Identity 2 system includes OAuth connections for Facebook, Twitter and Google. These are easy enough to configure (well to do a simple register/login) from an MVC website project BUT doing this with Web Api needs a little more knowledge!

Firstly I’ll make reference to this excellent resource on configuring various OAuth providers.

http://www.beabigrockstar.com/guides/aspnet-oauth

So if you’ve followed this correctly you should have your API key/secret in your Startup.Auth file.

http://stackoverflow.com/questions/21065648/asp-net-web-api-2-how-to-login-with-external-authentication-services

Now to use this with WebApi you need to make a call to

GET /api/Account/ExternalLogins?returnUrl=%2F&generateState=true

This will return an object of all your registered OAuth providers along with a URL.

Make a GET request to this URL and you will be redirected to the providers login page which will eventually request the permissions you are needing for your app.  (Typically this will be your client website or native app making this call)

e.g.

http://localhost:2000/api/Account/ExternalLogin?provider=Facebook&response_type=token&client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A30756%2F&state=YRN-9tp3XCn_PUmp6yMBHX896rRu_UOkA9xxxxxxxxx

Once authenticated, you will go back to your callback URL, which will look something like this or back to your native app.

http://localhost:30756/#access_token=SOMETOKENVALUE&token_type=bearer&expires_in=1209600&state=SOMESTATEVALUE

Notice the access_token and token_type values.  So all we need to do now to parse this response and send an Authorized request to our protected Api controller using this token.

e.g.

localhost:30756/api/account/userinfo

or

curl -H "Authorization: OAuth <ACCESS_TOKEN>" http://www.example.com