When I developed the WCF Membership Provider, I envisioned it being used as the basis for authentication across a wide array of products on any number of platforms.  The only requirement that the client application would need to have is that it could speak to web services using SOAP.  Out of the box, the code I presented in my article does not directly achieve that goal.  More work is necessary to make that a reality. 

Specifically, I would implement System.Web.ApplicationServices as the front end of the WCF Membership Provider by adding these services to a web site in the DMZ.  Non-ASP.Net clients and external web sites that did not need to have CreateUser/CreateRole/DeleteUser/... functionality would use these services.  ApplicationServices implements the subset of functionality required to authenticate against an ASP.Net membership store.  The Sql Server membership store that I chose to use is installed into a database in your application's database layer.  There's a command line tool that ships with all versions of the .Net framework.  I used .Net 4.0 for the code in my article.

Click here for a walk through on how to install SqlMembershipProvider's membership store.

Click here for a walk through on setting up System.Web.ApplicationServices.

I had a few people ask me what all the complexity bought me in terms of functionality.  They mentioned that there's at least one web service call which is significantly slower than a DLL that is linked into a web site.  I'm going to have to run tests in a production environment under load to see just how bad the performance is but performance wasn't the main consideration I had when designing the approach.  Using WCF, I've effectively decoupled the storage of usernames with the authentication code and that presents me with the following benefits.

  1. The WCF services are hosted in IIS at this time.  This means that I can deploy them to a web farm and scale horizontally if necessary.
  2. The DLL used by Internet ASP.Net web site in the DMZ is forced to abide by all of the WCF security conventions.  I would expect at least transport layer security to be turned on in a production environment which would require the DMZ web servers to use SSL to communicate with the back end authentication WCF services. 
  3. WCF comes packed with ways to handle denial of service attacks and other forms of hacking.  Additional work could be done here to prevent a DMZ web server's compromise from impacting the back end servers.  There's no way to protect the Sql Server membership store from a compromised web site if SqlMembershipProvider is used directly.
  4. Since the Internet ASP.Net web site is effectively using a Url based WCF service to authenticate users (through the EPI.Web.Security DLL), I can implement all sorts of partitioning schemes simply by changing the way the ASP.Net web site chooses a Url to pass to the DLL.  All users with usernames from A - L use login server A @ Url A which stores users in Sql Server A.  M - Z uses login server B @ Url B which stores users in Sql Server B.  That's achieved by improving upon the discovery of which Url is used to connect the DLL to the back end web service.  Login server A could be a single box, a web farm or a virtual web farm.  The same thing applies to SQL Server A so the solution is inherently scalable.

As for non web site clients or web sites hosted outside of our hosting environment, I could envision an OAuth provider being supplied to integrate authentication with other online services in addition to implementing System.Web.ApplicationServices.  In the end, the entire system uses the same web services in the back end against the same user store.  Here's a few other things that come to mind that could be implemented with a bit of work.

  1. Message level security through message encryption between the back end Membership Service and the EPI.Web.Security DLL.
  2. Caching of tokens and other data on the DMZ side of the web site to enhance performance.  This comes with security considerations but it is not out of the question if user volume is high enough to warrant the caching.  Implementing this is simply adding so custom code to the WCF service.
  3. GZiping the communication between the EPI.Web.Security DLL and the back end Membership service so that the DLL can more effectively use the bandwidth between the DMZ and the back end.

Hopefully, this let's you see a little bit more of why I did what I did in the project.  The original article can be found here and the download for the code can be found here.