Wednesday, February 20, 2013

ASP.NET MVC 4 Membership, Users, Passwords, Roles, Profile, Authentication and Authorization

----------------

TLDR: Search for this line in your project and update it:


WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

----------------


There is a new Membership Provider in ASP.NET MVC 4 that can be used for Membership, Users, Passwords, Roles, Profile, Authentication and Authorization!  It is called the Simple Membership Provider.  It uses the WebMatrix WebData WebSecurity class as a facade.

The Old Way


You will no longer need to execute the old .NET 2.0 aspnet_regsql.exe like this:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe -sqlexportonly C:\aspnet_membership.sql -A all

Or even execute the newer scripts updated for SQL Azure:
InstallCommon.sql
InstallMembership.sql
InstallRoles.sql
http://archive.msdn.microsoft.com/KB2006191
http://support.microsoft.com/kb/2006191

You won't even have to change the Web.config AspNetSqlMembershipProvider, SqlProfileProvider, or SqlRoleProvider applicationName, or ApplicationServices connection string, or profile, role provider or roleManager settings.


The New Way


Now all you need to do is update one line of code!

After creating a new ASP.NET MVC 4 "Internet Application" - update the following line in the [Project Folder]/Filters/InitializeSimpleMembershipAttribute.cs file:

(Note: this file contains a class that inherits from ("is a") ActionFilterAttribute.  The default ~/Controllers/AccountController.cs class is adorned with this attribute.  This means that a route associated with the AccountController needs to be called before the SimpleMembershipProvider will be initialized.  The code within this attribute can be merged into the Global.asax.cs file so that the SimpleMembershipProvider is initialized at application startup.  An example of that code is available via the link below.)


Search for this line in your project and update it:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);


"DefaultConnection" can be found in the [Project Folder]/Web.config file

"UserProfile" is the name of your own User table (can have any structure as long as it has UserId and UserName columns)

"UserId" is the name of a column in your User table that holds the User's Id

"UserName" is the name of a column in your User table that can hold a UserName

autoCreateTables: true - will create all the tables needed by the new Simple Membership Provider if they do not already exist.  The link below contains the SQL for the tables created:

https://github.com/aaronhoffman/aspnetmvc4membership

And only tables are created.  No aspnet_* stored procedures, no SQL views, no SQL Database Roles, only tables!



Simple Table Definitions


dbo.webpages_Membership
UserId                                     int
CreateDate                                 datetime
ConfirmationToken                          nvarchar(128)
IsConfirmed                                bit
LastPasswordFailureDate                    datetime
PasswordFailuresSinceLastSuccess           int
Password                                   nvarchar(128)
PasswordChangedDate                        datetime
PasswordSalt                               nvarchar(128)
PasswordVerificationToken                  nvarchar(128)
PasswordVerificationTokenExpirationDate    datetime

dbo.webpages_OAuthMembership
Provider               nvarchar(30)
ProviderUserId         nvarchar(100)
UserId                 int

dbo.webpages_Roles
RoleId                 int
RoleName               nvarchar(256)

dbo.webpages_UsersInRoles

UserId                 int
RoleId                 int


Initialize SimpleMembershipProvider in Global.asax.cs Application_Start()


As mentioned previously in this post, by default the WebSecurity.InitializeDatabaseConnection() call is within the InitializeSimpleMembershipAttribute class, and by default the AccountController is adored with this attribute.  The trouble with that is that a route associated with the AccountController must first be invoked for the SimpleMembershipProvider to be initialized - this is not ideal.  Instead, that initialization can take place in the Global.asax.cs Application_Start() method so that it is initialized at application startup.  See the link below for an example.  Be sure to change the "MvcApplication1" to be the namespace of your own project.

https://github.com/aaronhoffman/aspnetmvc4membership



More Info:
http://blog.osbornm.com/2010/07/21/using-simplemembership-with-asp.net-webpages/
and
http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx
Post a Comment