To be honest, to achieve what I wanted was quite a simple process. I haven't implemented the AuthorizationService yet but this will follow a similar pattern.
My authentication service is quite simple:
public interface IAuthenticationService
{
bool IsValidLogin(string username, string password);
}
There will be a CreateUser method but I haven't implemented this yet.
Creating an authentication service using the standard membership provider is a simple task:
public class AspNetAuthenticationService : IAuthenticationService
{
public bool IsValidLogin(string username, string password)
{
return Membership.ValidateUser(username, password);
}
}
If I want to swap out the default SqlMembershipProvider with my own then I just need to change web.config. In order to support different types of authentication (perhaps forms auth and open id) I can just create a controller action for each and call the appropriate IAuthenticationService.ValidateUser implementation before setting an auth cookie.
The authentication process if for identifying the "user". In order to get the "Customer" I am using a PersonalizationService. The interface for this is again quite simple:
public interface IPersonalizationService {
Customer GetCustomer(string username);
}
This returns my customer (with addresses, past orders - the stuff we really care about). The GetCustomer method will create a customer object if one doesn't exist with the passed in username. So if using standard forms auth a customer will be created anyway during registration. If using something like OpenID, the first time they login a customer object will be created and linked to their OpenID username (hence the reason for separating what an authenticated "user" is from a "customer".
This process also works well for anonymous checkout since I can create an in memory customer object for "guest" customers, and finally persist this to the database if they make a purchase. In this case, I don't have a user (cause they didn't authenticate) but I do have a customer.
I am quite happy with this implementation. I think I will roll my own Membership Provider (since it's not really that difficult) and I would like to use the repository pattern for the data access. Interested to hear any opinions / suggestions on this approach.
Some resources I have used:
http://noahblu.wordpress.com/2009/02/19/custom-membershipprovider-using-repository-dependency-injection-pattern-magic/
http://davidhayden.com/blog/dave/archive/2007/10/11/CreateCustomMembershipProviderASPNETWebsiteSecurity.aspx
http://pbdj.sys-con.com/node/837990/mobile
http://mattwrock.com/post/2009/10/14/Implementing-custom-Membership-Provider-and-Role-Provider-for-Authinticating-ASPNET-MVC-Applications.aspx