A Beginner ' s Tutorial on Custom Forms authentication in asp.net MVC applicationby Rahul Rajat Singh, APR 2013
4.98/5 -Votesμ4.98,σa 1.08 [?] |
|
|
Rate this: |
vote 1 Vote 2 vote 3 vote 4 vote 5 |
|
|
& nbsp; please Sign up or Sign in to vote. |
Download sample-1.4 MB
Introduction
In this we'll discuss about the ASP.net Roles and membership API from MVC perspective. We'll try to Roles and membership provides can is used for authentication and authorization in an MV C application. We'll also can implement custom forms authentication in a asp.net MVC application. Background
When we are working on application in which authentication and authorization are a key requirement, we'll find t He asp.net roles and Membership feature very useful. The basic principle and mechanism for forms authentication in ASP.net MVC are same as of that of ASP.net. But since we don ' t have the server controls with us the way to-use it'll be a little different from that of the WebForms . Nevertheless, since the core principle behind the Forms authentication is same, I suggest following articles would Provide a quick recap on ASP.net Forms authentication and, it can be implemented and customized in WebForms application S. Understanding asp.net Roles and membership-a beginner ' s tutorial[^] understanding and implementing ASP.NET Custom for Ms authentication[^] authentication and Authorization
Authentication means validating users. In this step, we verify user credentials to check whether the person tying to log in are the right one or. Authorization on the other hand is keeping track of what the "current user is allowed to" and what should be hidden M him. It is more like keeping-a register to what to show and what.
Whenever a user logs in, and he would have to authenticate himself and his credentials. Once He was authenticated, he would be authorized to the resources/pages of the website. Mostly these two concepts go together. Type of Authentications
Before moving ahead, let us-i-two main type of authentications that are used to mostly in asp.net. Windows Authentication: In this mode, the users are authenticated on their Windows username and password. This is least recommended in Internet scenario. In the Internet scenario, we should always use "Forms based Authentication". Forms based authentication: In this type of authentication, the user would explicitly have to provide he credentials and these credentials, once Veri Fied by the server, would let the user to log in.
We are discussing the form authentication in the rest of the article. Using The Code
The default ASP.net Roles and Membership classes come in very handy when we want to provide authentication and Authorizat Ion in our applications. Using The default membership API would use the membership database and provide us would all functionality required to MA Nage the user roles and membership.
ASP.net also provides a way to implement custom Roles and membership the more take control over granular. We might still find ourselves into situations where we need to have we own the database for tracking users and their roles. The reasons could be:we have a existing database and We are trying to implement a using that. The Roles and membership functionality is overkill to our application. The Roles and membership functionality are not sufficient for our applications and we need custom data.
So let us a discuss the default membership API and what Visual Studio provides us out of the box. We'll then move on to taking ' full Control ' authorization and authentication on our hand by implementing custom for MS Authentication. Forms Authentication
To enable forms authentication we need to perform following steps in our application. Configure the application to use Forms authentication. Create a login page. Whenever a user tries to access the restricted area and push him to the Login page. When the user tries to login, verify his credentials using the database. If the login is successful, keep the username and his Roles in a sessions variable to use it further. Create A authentication ticket for the user (an encrypted cookie). We can have this persistent or non persistent. Facilitate the user/roles extraction using the authentication ticket. Use the ' user/roles found in ' The last step and create a Principal using this so this asp.net Forms authentication mech Anism can use this data.
Now we'll have the membership API does all of things for us and how we can implement all of these steps ourse Lves. Default Membership API
When we create an MVC Internet application. The Visual Studio Project Wizard does all this above mentioned steps for us. It would create a membership database in the App_Data directory of my application (actually the location depends on the CO nnectionstring specified in Web.config file).
It'll generate the Controller ode that'll check the database for user authentication, create the authentication cookie and creation of Principal based on the roles configured into our database. It'll also generate all the view required for authentication. The image below shows the generated Controller, views and the database.
The Roles and user can is configured either from code or from the Web Site administration Tool (WSAT) in the same manner a S of that in WebForms application. So let us create a role called "admin" and 2 users "admin" and "user" using Wsat. The ' admin ' is in ' admin ' role and the ' user ' is ' not ' be ' in '.
Now from the applications perspective, we are need to mark the views of that need authentication and authorization and the Default membership classes and the generated classed'll take care of performing the authentication and authorization.
Let us say which we want only authentication users to be able to view the Home/index page. And only the users in ' Admin ' role can access the Home/about page. To doing this we need to decorate the respective action in controller with the authorize attribute As:collapse | Copy Code
public class Homecontroller:controller
{
[authorize] public
ActionResult Index ()
{
Viewbag.message = "Welcome to asp.net mvc!";
return View ();
}
[Authorize (roles= "Admin")]
Public ActionResult About ()
{return
View ();
}
}
And that are all are required to require authentication and authorization if we are the using default membership API and th E Visual Studio generated code for authentication and authorization. We can do some level of customization in the AccountController class if we need some added.
Note: The article does not contain a sample for the default membership usage because it is just the matter of creating a new MVC 3 Internet application and all the code is generated by Visual Studio itself. It is highly recommended to look at the AccountController class to the "it is performing various operations." Custom Forms Authentication
Now if we don ' t want to use the default membership API and the Visual Studio generated code then we can choose to implemen T our own authentication and authorization mechanism. To doing this we'll have take care of implementing all steps required for forms authentication that we discussed Earlie R in the article. So let us create and empty MVC 3 application and to how we can implement custom forms authentication. Configuring Forms Authentication
Now the "I" thing "we need to" to "Configure" application to "use" Forms authentication. This can is done in the Web.config file. Collapse | Copy Code
<authentication mode= "Forms" >
<forms loginurl= "~/account/login" timeout= "2880"/>
</ Authentication>
preparing the user Database
Let us now create a small database, we'll use the to perform authentication. This is the database contains only two the users like we old earlier example. "Admin" and "user". ' admin ' in ' admin ' role and ' user ' is ' not ' role.
Note: The "database is neither optimized nor normalized as" is not the main intent of this article. A Real World example of database would be the more optimized and perhaps more complex. The passwords is not being in clear text for sure, They'll either be encrypted or hashed & salted.
Now to perform data access let us use the Entity Framework so we don ' t have to write all the boilerplate code required to Create our model and data access logic. The generated entity for our database would look like:
creating the Controllers and views
Let-us now-go ahead and create-a controller that would take care of the authentication logic. We'll create the functionality for Login and Logout but other functionality are user creation and password change can Easily implemented on same lines (its matter of validating the user Model and performing CRUD operations on the table After encryption or hashing and salting).
This is US controller with login and logout Action:collapse | Copy Code
Public ActionResult Login () {return View ();}
[HttpPost] public actionresult Login (User model, string ReturnUrl) {//lets a-I-if the model is valid or not if (modelstate.isvalid) {using (userdbentities entities = new Userdbentities ()) {str
ing username = model.username;
string password = Model.password; Now if we password is enctypted or hashed we would have do the//same operation on the user entered PA ssWOrd here, But for now//since the password are in plain text lets just authenticate directly b Ool Uservalid = entities.
Users.any (user => User.username = = Username && User.password = = password); User found in the database if (uservalid) {Formsauthentication.setauthcookie (
Username, false); if (Url.islocalurl (returnurl) && returnurl.length > 1 && Returnurl.starTswith ("/") &&!returnurl.startswith ("//") &&!returnurl.startswith ("/\\")
{return Redirect (ReturnUrl);
else {return redirecttoaction ("Index", "Home"); } else {Modelstate.addmodelerror ("", "the user name or Password Pro
Vided is incorrect. ");}}
If we got this far, something failed, redisplay form return View (model);
Public ActionResult LogOff () {formsauthentication.signout ();
Return redirecttoaction ("Index", "Home");
}
Now in the above code as the user tries to login we'll check if the user with the given user credentials exist in the User database or not. If It exist we set the authentication ticket and move forward. Now if we password is encrypted or hashed we would have do the same operation on the user entered password before CHEC King in database, but since the password are in plain text lets just authenticate directly.
Now before moving ahead let us look in the view that would take the user credentials and perform the authentication.
Let us now create a simple Controller which would contain two actions. One action that can is performed by any authenticated user and the can is performed by the users in ' admin ' role on Ly. Collapse | Copy Code
public class Homecontroller:controller
{
[authorize] public
ActionResult Index ()
{
Viewbag.message = "This can is viewed only by the Authenticated users only";
return View ();
}
[Authorize (roles= "admin")]
Public ActionResult Adminindex ()
{
Viewbag.message = ' This can is viewed only by the users in Admin ' only ';
return View ();
}
Now when we run the application, we can then the the users'll be asked to enter their credentials when they try to acces s the home controller ' s views. Upon successful Login They is able to the Index page.
But If we try to look at the Adminindex page we won't be able to. The reason for this is this currently users roles are not being used. facilitating Roles extraction using the authentication ticket
The roles specified in our database, there are one thing to understand. When Forms authentication are being used, whenever the need for authentication arises, the ASP.net framework checks with T He iprinciple type object. The user ID and role contained in this Iprinciple type object would determine whether the user is allowed access or not.
So far we have is not written code to push our user's role for details in this principle object. To do so we need to override A is called FormsAuthentication_OnAuthenticate in Global.asax. This are called the ASP.net framework tries to check authentication and authorization with respect to the CUR Rent principle.
What We need to does now to override this method. Check for the authentication ticket (since the user has already been validated and the ticket is created) Then supply this user/role information in the Iprinciple type object. We-can implement our custom principle type to o but to keep it simple, we'll simply create a Genericpriciple object and set our user specific details into it Co Llapse | Copy Code
protected void FormsAuthentication_OnAuthenticate (Object sender, Formsauthenticationeventargs e) {if (formsauthentication.cookiessupported = = True) {if (request.cookies[ Formsauthentication.formscookiename]!= null) {try {//let us take out th E username now string username = Formsauthentication.decrypt (request.cookies[formsauthenti cation. FormsCookieName]. Value).
Name; string roles = String.
Empty; using (userdbentities entities = new Userdbentities ()) {User user = entities.
Users.singleordefault (U => u.username = = username); roles = user.
Roles; }//let us extract the roles from our own custom cookie//let US set the Pricipal with our user specific details E.user = new Syste