Create ASP.NET MVC Project
On the Visual Studio, create new ASP.NET MVC Web Application project
Select Empty Template and Core Reference is MVC
Entities Class
In Models folder, create new entities class as below:
Account Entity
Create new class named Account.cs as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace LearnASPNETMVCWithRealApps.Models
{
public class Account
{
[Display(Name = "Username")]
public string Username
{
get;
set;
}
[Display(Name = "Password")]
public string Password
{
get;
set;
}
public string[] Roles
{
get;
set;
}
}
}
Models Class
In Models folder, create new class named AccountModel.cs as below:
AccountModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LearnASPNETMVCWithRealApps.Models
{
public class AccountModel
{
private List<Account> accounts = new List<Account>();
public AccountModel()
{
accounts.Add(new Account { Username = "acc1", Password = "123", Roles = new string[] { "superadmin", "admin", "employee" } });
accounts.Add(new Account { Username = "acc2", Password = "123", Roles = new string[] { "admin", "employee" } });
accounts.Add(new Account { Username = "acc3", Password = "123", Roles = new string[] { "employee" } });
}
public Account find(string username)
{
return accounts.Single(acc => acc.Username.Equals(username));
}
public Account login(string username, string password)
{
return accounts.Where(acc => acc.Username.Equals(username) && acc.Password.Equals(password)).FirstOrDefault();
}
}
}
Security Classes
Create Security folder in project. This folder contains classes need for security in ASP.NET MVC. Create classes: CustomPrincipal.cs, MyAuthorizeAttribute.cs and SimpleSessionPersister.cs as below:
CustomPrincipal.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal;
using LearnASPNETMVCWithRealApps.Models;
namespace LearnASPNETMVCWithRealApps.Security
{
public class CustomPrincipal : IPrincipal
{
public IIdentity Identity
{
get;
set;
}
private Account Account;
public CustomPrincipal(Account Account)
{
this.Account = Account;
this.Identity = new GenericIdentity(Account.Username);
}
public bool IsInRole(string role)
{
var roles = role.Split(new char[] { ',' });
return roles.Any(r => this.Account.Roles.Contains(r));
}
}
}
MyAuthorizeAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using LearnASPNETMVCWithRealApps.Security;
using LearnASPNETMVCWithRealApps.Models;
namespace LearnASPNETMVCWithRealApps.Security
{
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (string.IsNullOrEmpty(SimpleSessionPersister.Username))
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "Index" }));
}
else
{
AccountModel accountModel = new AccountModel();
CustomPrincipal customPrincipal = new CustomPrincipal(accountModel.find(SimpleSessionPersister.Username));
if (!customPrincipal.IsInRole(Roles))
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "Index" }));
}
}
}
}
}
SimpleSessionPersister.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LearnASPNETMVCWithRealApps.Security
{
public static class SimpleSessionPersister
{
static string usernameSessionvar = "username";
public static string Username
{
get
{
if (HttpContext.Current == null) {
return string.Empty;
}
var sessionVar = HttpContext.Current.Session[usernameSessionvar];
if (sessionVar != null) {
return sessionVar as string;
}
return null;
}
set
{
HttpContext.Current.Session[usernameSessionvar] = value;
}
}
}
}
Create View Model
Create new folder named ViewModels, create new class named AccountViewModel.cs as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using LearnASPNETMVCWithRealApps.Models;
namespace LearnASPNETMVCWithRealApps.ViewModels
{
public class AccountViewModel
{
public Account Account
{
get;
set;
}
}
}
Create Controllers
In Controllers folder, create new controllers as below:
Demo Controller
Create new controller named DemoController.cs as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LearnASPNETMVCWithRealApps.Security;
namespace LearnASPNETMVCWithRealApps.Controllers
{
public class DemoController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
[MyAuthorizeAttribute(Roles = "superadmin")]
public ActionResult Work1()
{
return View("Work1");
}
[MyAuthorizeAttribute(Roles = "superadmin,admin")]
public ActionResult Work2()
{
return View("Work2");
}
[MyAuthorizeAttribute(Roles = "superadmin,admin,employee")]
public ActionResult Work3()
{
return View("Work3");
}
}
}
Account Controller
Create new controller named AccountController.cs as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LearnASPNETMVCWithRealApps.Security;
using LearnASPNETMVCWithRealApps.Models;
using LearnASPNETMVCWithRealApps.ViewModels;
namespace LearnASPNETMVCWithRealApps.Controllers
{
public class AccountController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Login(AccountViewModel accountViewModel)
{
AccountModel accountModel = new AccountModel();
if (string.IsNullOrEmpty(accountViewModel.Account.Username) || string.IsNullOrEmpty(accountViewModel.Account.Password) || accountModel.login(accountViewModel.Account.Username, accountViewModel.Account.Password) == null)
{
ViewBag.Error = "Please provide your username and password correct!!!";
return View("Index");
}
SimpleSessionPersister.Username = accountViewModel.Account.Username;
return View("Welcome");
}
public ActionResult Logout()
{
SimpleSessionPersister.Username = string.Empty;
return RedirectToAction("Index");
}
}
}
Error Controller
Create new controller named ErrorController.cs as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace LearnASPNETMVCWithRealApps.Controllers
{
public class ErrorController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
Create View
In Views folder, create razor new views as below:
Account Views
In Views/Account folder, create new views as below:
Index View
Create new view named Index.cshtml as below:
@{
Layout = null;
}
@model LearnASPNETMVCWithRealApps.ViewModels.AccountViewModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
@using (Html.BeginForm("Login", "Account", FormMethod.Post))
{
@ViewBag.Error
<table cellpadding="2" cellspacing="2">
<tr>
<td>@Html.LabelFor(model => model.Account.Username)</td>
<td>@Html.TextBoxFor(model => model.Account.Username)</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.Account.Password)</td>
<td>@Html.PasswordFor(model => model.Account.Password)</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Save" /></td>
</tr>
</table>
}
</body>
</html>
Welcome View
Create new view named Welcome.cshtml as below:
@{
Layout = null;
}
@using LearnASPNETMVCWithRealApps.Security
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Welcome</title>
</head>
<body>
<div>
Welcome @SimpleSessionPersister.Username - <a href="@Url.Action("Logout", "Account")">Logout</a>
</div>
</body>
</html>
Demo Views
In Views/Demo folder, create new views as below:
Index View
Create new view named Index.cshtml as below:
@{
Layout = null;
}
@using LearnASPNETMVCWithRealApps.Security
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<h3>Index Page</h3>
</body>
</html>
Work1 View
Create new view named Work1.cshtml as below:
@{
Layout = null;
}
@using LearnASPNETMVCWithRealApps.Security
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Work 1</title>
</head>
<body>
<h3>Work 1 Page</h3>
<br />
Welcome @SimpleSessionPersister.Username - <a href="@Url.Action("Logout", "Account")">Logout</a>
</body>
</html>
Work2 View
Create new view named Work2.cshtml as below:
@{
Layout = null;
}
@using LearnASPNETMVCWithRealApps.Security
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Work 2</title>
</head>
<body>
<h3>Work 2 Page</h3>
<br />
Welcome @SimpleSessionPersister.Username - <a href="@Url.Action("Logout", "Account")">Logout</a>
</body>
</html>
Work3 View
Create new view named Work3.cshtml as below:
@{
Layout = null;
}
@using LearnASPNETMVCWithRealApps.Security
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Work 3</title>
</head>
<body>
<h3>Work 3 Page</h3>
<br />
Welcome @SimpleSessionPersister.Username - <a href="@Url.Action("Logout", "Account")">Logout</a>
</body>
</html>
Error Views
In Views/Error folder, create new views as below:
Index View
Create new view named Index.cshtml as below:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<h3>Access Denied</h3>
</body>
</html>
Structure of ASP.NET MVC Project
Run Application
Access Index action in Account controller with following url: http://localhost:49328/Account/Index
Output
Test access Index action in Demo controller without account with url: http://localhost:49328/Demo/Index
Output
Test access Work1 action in Demo controller without account with url: http://localhost:49328/Demo/Work1
Output
Test access Work2 action in Demo controller without account with url: http://localhost:49328/Demo/Work2
Output
Test access Work3 action in Demo controller without account with url: http://localhost:49328/Demo/Work3
Output
Test login with invalid account: username is abc and password is 123
Output
Test login with valid account: username is acc2 and password is 123. This account have roles: admin and employee
Output
Use acc2 has logged access Work1 action in Demo controller with url: http://localhost:49328/Demo/Work1
Output
Use acc2 has logged access Work2 action in Demo controller with url: http://localhost:49328/Demo/Work2
Output
Use acc2 has logged access Work3 action in Demo controller with url: http://localhost:49328/Demo/Work3
Output
References
I recommend you refer to the books below to learn more about the knowledge in this article:
- ASP.NET MVC Framework Unleashed
- Programming Microsoft ASP.NET MVC (3rd Edition) (Developer Reference)
- Pro ASP.NET MVC 5 Platform
- Pro ASP.NET MVC Framework
- Professional ASP.NET MVC 5