This this a SimpleMembership implementation using MongoDB as the backing store that provides a custom Membership provider (ExtendedMembershipProvider to be exact) and Role provider.
For more information about SimpleMembership see this post by Jon Galloway : SimpleMembership, Membership Providers, Universal Providers and the new ASP.NET 4.5 Web Forms and ASP.NET MVC 4 templates
Available on NuGet:
PM> Install-Package LyphTEC.MongoSimpleMembership
You must complete the following steps after you have installed the NuGet package before your app will run:
-
Configure your data connection string to the MongoDB database
eg.
<connectionStrings> <clear/> <add name="MongoSimpleMembership" connectionString="mongodb://localhost/SimpleMembership?safe=true" /> </connectionStrings>
Note that the connection string must also include the database name. In the example above, this will use the database named "SimpleMembership".
-
Update the system.web/membership & system.web/roleManager sections to use the connection string name as defined above
Also make sure that the "defaultProvider" attributes are set to use the matching MongoSimpleMembership provider names.
eg.
<membership defaultProvider="MongoSimpleMembershipProvider"> <providers> <clear /> <add name="MongoSimpleMembershipProvider" type="LyphTEC.MongoSimpleMembership.MongoSimpleMembershipProvider, LyphTEC.MongoSimpleMembership" connectionStringName="MongoSimpleMembership" /> </providers> </membership> <roleManager enabled="true" defaultProvider="MongoRoleProvider"> <providers> <clear /> <add name="MongoRoleProvider" type="LyphTEC.MongoSimpleMembership.MongoRoleProvider, LyphTEC.MongoSimpleMembership" connectionStringName="MongoSimpleMembership" /> </providers> </roleManager>
-
If you are using the default "ASP.NET MVC4 Internet" template. You must make some changes to AccountController:
-
Remove the [InitializeSimpleMembership] attribute (the ActionFilterAttribute defined in Filters/InitializeSimpleMembershipAttribute.cs). This is used by the default SimpleMembershipProvider that needs to initialize SQL Server. Since we are not using SQL Server, this is no longer required.
-
Make changes to the ExternalLoginConfirmation() method to remove Entity Framework related hooks used by the default SimpleMembershipProvider.
Here's what it looks like before the change:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl) { string provider = null; string providerUserId = null; if (User.Identity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId)) { return RedirectToAction("Manage"); } if (ModelState.IsValid) { // Insert a new user into the database using (UsersContext db = new UsersContext()) { UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == model.UserName.ToLower()); // Check if user already exists if (user == null) { // Insert name into the profile table db.UserProfiles.Add(new UserProfile { UserName = model.UserName }); db.SaveChanges(); OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName); OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name."); } } } ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName; ViewBag.ReturnUrl = returnUrl; return View(model); }
And here's what it should look like after the change:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl) { string provider = null; string providerUserId = null; if (User.Identity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId)) { return RedirectToAction("Manage"); } if (ModelState.IsValid) { // check if user exists if (!WebSecurity.UserExists(model.UserName)) { // TODO : Add custom user profile logic here // this will create a non-local account OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName); OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name."); } } ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName; ViewBag.ReturnUrl = returnUrl; return View(model); }
See the sample MVC4 app for reference.
By default, the persisted entities are stored in collections with the following names:
This matches the table names used in the standard SQL Server based SimpleMembershipProvider.
If desired, you can change the default collection names by using the following appSettings:
<appSettings>
<add key="MongoSimpleMembership:MembershipAccountName" value="webpages_Membership" />
<add key="MongoSimpleMembership:OAuthMembershipName" value="webpages_OAuthMembership" />
<add key="MongoSimpleMembership:OAuthTokenName" value="webpages_OAuthToken" />
<add key="MongoSimpleMembership:RoleName" value="webpages_Role" />
</appSettings>