I started out developing an ASP.Net MVC which did not require authentication during the prototyping stage.
But sooner or later, authentication became a requirement, and so I needed to add authentication, membership providers, etc. as provided by the ASP.Net framework.
First, I came across this article on asp.net, which contains really detailed information on the membership database schema. (There’s another detailed introduction by 4guysfromrolla – it’s dealing with .Net 2 (2007!), but still very useful)
To install the database, you need to run
provide connection details for your SQL Server database, and have your membership schema installed.
Once installed, you can created users and roles directly from SQL Server Management studio:
Locate the stored procedure aspnet_Membership_CreateUser, right click, “Script Stored Procedure as”, “EXECUTE to”, “New Query Window”, and edit the parameter values
Note that the @ApplicationName must be the same for all procedure calls (relating to the same application) and must match the applicationName values in web.config.
The stored procedure will create records in aspnet_Applications, aspnet_Users and aspnet_Memberships.
The values of @PasswordFormat are 0=Plaintext, 1=Hashed, 2=Encrypted, and match the allowed values of passwordFormat=”" in web.config.
Next, I created the required roles:
and added the users to the correct roles
The step deals with the (already existing) sections of web.config, namely <authentication>, <membership>, <profile> and <roleManager>
Set the value of <forms loginUrl=”"> to point to your login form. Any controller method having an [Authorize] attribute will redirect to the login URL if invoked without login.
The connectionStringName value must be set to a connection string name as defined in the <connectionStrings> entry that points to the database we initialized by calling aspnet_regsql.exe.
The [Authorize] attribute needs to be added to controller methods that must not be accessible to unauthorized users.
The LogOn controller method is quite minimalistic, as it only calls ValidateUser() and then sets the username, and looks like this:
So we can log in, and we can display the user name as implemented by default in LogOnUserControl.ascx.
We need roles! To make roles work, you need to set <roleManager enabled=”true”>. Otherwise the exception
ProviderException: The Role Manager feature has not been enabled
is raised when accessing the Roles class. (see SO and SO)
Additionally, I did not want to hard-code the roles all over the place throughout the application, but rather check a limited set of (probably configurable) roles.
So based on this asp.net forum post and this question on SO the solution was to copy the AuthorizeAttribute from CodePlex, remove the Users and Roles from the class, and change the AuthorizeCore() method (of the authorization attribute base class) to
Derived from this base class, we simple define one authorization attribute per pre-defined role using Roles.IsUserInRole()
and apply these attributes to the respective controller methods.