Single Sign-on with ASP.NET on Windows Home Server

One of the major advantages Windows Home Server has over much of it’s competition (external hard drives, generic network attached storage devices, secondary PCs) is that it’s a full Windows Server under the hood and comes along with the ability to host almost any sort of web page or application you care to deploy to it, including those based on ASP.NET.

With your server hosting all of your content at https://smithfamily.homeserver.com, there exists the need to control access, something Windows Home Server does on it's own through it's remote access web site which uses the underlying Windows accounts. 3rd party developers can leverage Windows or Forms based authentication in their own web applications... however in doing so they are normally responsible for handling authentication... did you know developers you can use the same login page that already ships on Windows Home Server in their own applications?

Why so? The authentication system built in to ASP.NET can be used to offload some of the work of determining if a user is authenticated and what to do with them if they are not (amongst many other things)... these settings, like most other ASP.NET settings in the web.config file within a web application's directory and when the correct sections of config are copied between applications, single sign-on is the result.

Before we go any further, if you do not already know how to use Forms based authentication in ASP.NET I would highly suggest taking a quick read of what it can do for you and how.

Lets take a look at the web.config (c:\Inetpub\remote\web.config) from a Home Server sitting under my desk at work:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <machineKey validationKey="<key removed for length>"
   decryptionKey="<key removed for length>"
   validation="SHA1" decryption="AES" />
        <authentication mode="Forms">
            <forms name="RemotePortalAuth" loginUrl="logon.aspx" protection="All" path="/" timeout="12000" requireSSL="false"/>
        </authentication>
        <authorization>
            <deny users="?"/>
            <allow users="*"/>
        </authorization>
        <httpRuntime maxRequestLength="2097151" executionTimeout="86400"/>
        <customErrors mode="On" defaultRedirect="error.aspx"/>
        <trace enabled="false" requestLimit="100" pageOutput="false" traceMode="SortByTime" localOnly="false"/>
        <sessionState mode="InProc" cookieless="false" timeout="20"/>
        <globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
  </system.web>
</configuration>

In order for our own web application to use the same authentication back end and cookie as the existing Windows Home Server Remote Access web page, we need to copy two sections of the above file to the web.config file being used by our own custom app, specifically the machineKey, and authentication key tags.

The authentication key specifies not only what kind of authentication to use (forms), but what the name of the resulting authentication cookie will be (RemotePortalAuth) and where to send browsers who are not authenticated (login.aspx) while the machineKey defines the encryption keys to use

Before hitting save on my updated web.config file, I will need to tweak it slightly, changing the loginUrl property to point to the logon page that exists in a directory different than where the new web app is running:

        <machineKey validationKey="<key removed for length>"
   decryptionKey="<key removed for length>"
   validation="SHA1" decryption="AES" />
        <authentication mode="Forms">
            <forms name="RemotePortalAuth" loginUrl="../remote/logon.aspx" protection="All" path="/" timeout="12000" requireSSL="false"/>
        </authentication>

What I described above is the manual process behind such a process, it would be the responsibility of an installer of a web site to open the existing web.config file, grab the needed bits and insert it into it's own web.config, which given only involves a bit of xml can be a simple process.

What does this give us? If I installed a web application that lives in the virtual directory SingleSignOnExample on my Home Server and navigated to:

https://smithfamily.homeserver.com/SingleSignOnExample/Default.aspx

Unless I was already logged into the remote access web page, I'd be automatically redirected to:

https://smithfamily.homeserver.com/remote/logon.aspx?ReturnUrl=%2fSingleSignOnExample%2fDefault.aspx

Which would allow me to login with my existing credentials, and then be redirected back to the original URL:

https://smithfamily.homeserver.com/SingleSignOnExample/Default.aspx

After this is all said and done, it may be good to have ones installer also edit the server's websites.xml file to advertise the new web application to existing users of the remote access web site.