ASP.NET MVC5: Role Base Accessibility
Role base accessibility is another integral part of web development because it provides encapsulation for designated information accessibility to designated credential.
Microsoft MVC paradigm provides a very simple and effective mechanism to achieve role base accessibility. So, for today's discussion, I will be demonstrating role base accessibility using ASP.NET MVC5 technology.
Following are some prerequisites before you proceed any further in this tutorial:
2) Knowledge about ADO.NET.
3) Knowledge about entity framework.
4) Knowledge about OWIN.
5) Knowledge about Claim Base Identity Model.
6) Knowledge about C# programming.
7) Knowledge about C# LINQ.
You can download the complete source code for this tutorial or you can follow the step by step discussion below. The sample code is developed in Microsoft Visual Studio 2013 Ultimate. I am using SQL Server 2008 as database.
1) First you need to create a sample database with "Login" & "Role" tables, I am using following scripts to generate my sample database. My database name is "RoleBaseAccessibility", below is the snippet for it:
Here I have created a simple login & role tables with sample data and a store procedure to retrieve the data.
2) Create new visual studio web MVC project and name it "RoleBaseAccessibility".
3) You need to create "ADO.NET" database connectivity. You can visit here for details.
4) You also need to create basic "Login" interface, I am not going to show you how you can create a basic login application by using Claim Base Identity Model. You can either download source code for this tutorial or you can go through detail tutorial here for better understanding.
5) Now, open "App_Start->Startup.Auth.cs" file and replace it with following code:
In above code following line of code will redirect the user to home page if he/she tries to access a link which is not authorized to him/her:
6) Create new controller, name it "AccountController.cs" under "Controller" folder and replace it with following code:
In above code, following piece of code is important i.e.
Here, along with claiming "Username" in OWIN security layer, we are also claiming "role_id" to provide role base accessibility:
7) Now, create new controller under "Controller" folder, name it "HomeController.cs" and replace it with following code i.e.
In above code, we have simply created two views, one is accessible to all the user which is "Index" view and second method is accessible to only "Admin" role user with role_id = 1. Following piece of code will translate the role base accessibility in OWIN security layer i.e.
If you want to define role accessibility for multiple roles you can achieve it like following:
where, 2, 3 are role id(s). 8) Replace following code in "_LoginPartial.cshtml" file:
9) Execute the project and you will see following:
10) When you login as admin account you will able to see a link that only admin can see as follow:
11) When you login as non-admin account you won't see the link that admin can see but, if you try to open the link which supposedly you do not have access of, you will be redirected to your home page as follow:
That's about it!!
Enjoy coding!!!
Microsoft MVC paradigm provides a very simple and effective mechanism to achieve role base accessibility. So, for today's discussion, I will be demonstrating role base accessibility using ASP.NET MVC5 technology.
Prerequisites:
1) Knowledge about ASP.NET MVC5.2) Knowledge about ADO.NET.
3) Knowledge about entity framework.
4) Knowledge about OWIN.
5) Knowledge about Claim Base Identity Model.
6) Knowledge about C# programming.
7) Knowledge about C# LINQ.
You can download the complete source code for this tutorial or you can follow the step by step discussion below. The sample code is developed in Microsoft Visual Studio 2013 Ultimate. I am using SQL Server 2008 as database.
Download Link
Let's Begin now.1) First you need to create a sample database with "Login" & "Role" tables, I am using following scripts to generate my sample database. My database name is "RoleBaseAccessibility", below is the snippet for it:
USE [RoleBaseAccessibility] GO /****** Object: ForeignKey [R_10] Script Date: 04/30/2016 16:32:55 ******/ IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[R_10]') AND parent_object_id = OBJECT_ID(N'[dbo].[Login]')) ALTER TABLE [dbo].[Login] DROP CONSTRAINT [R_10] GO /****** Object: StoredProcedure [dbo].[LoginByUsernamePassword] Script Date: 04/30/2016 16:32:59 ******/ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[LoginByUsernamePassword]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[LoginByUsernamePassword] GO /****** Object: Table [dbo].[Login] Script Date: 04/30/2016 16:32:55 ******/ IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[R_10]') AND parent_object_id = OBJECT_ID(N'[dbo].[Login]')) ALTER TABLE [dbo].[Login] DROP CONSTRAINT [R_10] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Login]') AND type in (N'U')) DROP TABLE [dbo].[Login] GO /****** Object: Table [dbo].[Role] Script Date: 04/30/2016 16:32:55 ******/ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Role]') AND type in (N'U')) DROP TABLE [dbo].[Role] GO /****** Object: Table [dbo].[Role] Script Date: 04/30/2016 16:32:55 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Role]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Role]( [role_id] [int] IDENTITY(1,1) NOT NULL, [role] [nvarchar](max) NOT NULL, CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED ( [role_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END GO SET IDENTITY_INSERT [dbo].[Role] ON INSERT [dbo].[Role] ([role_id], [role]) VALUES (1, N'Admin') INSERT [dbo].[Role] ([role_id], [role]) VALUES (2, N'User') SET IDENTITY_INSERT [dbo].[Role] OFF /****** Object: Table [dbo].[Login] Script Date: 04/30/2016 16:32:55 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Login]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Login]( [id] [int] IDENTITY(1,1) NOT NULL, [username] [varchar](50) NOT NULL, [password] [varchar](50) NOT NULL, [role_id] [int] NOT NULL, CONSTRAINT [PK_Login] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_PADDING OFF GO SET IDENTITY_INSERT [dbo].[Login] ON INSERT [dbo].[Login] ([id], [username], [password], [role_id]) VALUES (1, N'admin', N'admin', 1) INSERT [dbo].[Login] ([id], [username], [password], [role_id]) VALUES (2, N'user', N'user', 2) SET IDENTITY_INSERT [dbo].[Login] OFF /****** Object: StoredProcedure [dbo].[LoginByUsernamePassword] Script Date: 04/30/2016 16:32:59 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[LoginByUsernamePassword]') AND type in (N'P', N'PC')) BEGIN EXEC dbo.sp_executesql @statement = N'-- ============================================= -- Author: <Author,,Name> -- Create date: <Create Date,,> -- Description: <Description,,> -- ============================================= CREATE PROCEDURE [dbo].[LoginByUsernamePassword] @username varchar(50), @password varchar(50) AS BEGIN SELECT id, username, password, role_id FROM Login WHERE username = @username AND password = @password END ' END GO /****** Object: ForeignKey [R_10] Script Date: 04/30/2016 16:32:55 ******/ IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[R_10]') AND parent_object_id = OBJECT_ID(N'[dbo].[Login]')) ALTER TABLE [dbo].[Login] WITH CHECK ADD CONSTRAINT [R_10] FOREIGN KEY([role_id]) REFERENCES [dbo].[Role] ([role_id]) ON UPDATE CASCADE ON DELETE CASCADE GO IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[R_10]') AND parent_object_id = OBJECT_ID(N'[dbo].[Login]')) ALTER TABLE [dbo].[Login] CHECK CONSTRAINT [R_10] GO
Here I have created a simple login & role tables with sample data and a store procedure to retrieve the data.
2) Create new visual studio web MVC project and name it "RoleBaseAccessibility".
3) You need to create "ADO.NET" database connectivity. You can visit here for details.
4) You also need to create basic "Login" interface, I am not going to show you how you can create a basic login application by using Claim Base Identity Model. You can either download source code for this tutorial or you can go through detail tutorial here for better understanding.
5) Now, open "App_Start->Startup.Auth.cs" file and replace it with following code:
using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.DataProtection; using Microsoft.Owin.Security.Google; using Owin; using System; using RoleBaseAccessibility.Models; namespace RoleBaseAccessibility { public partial class Startup { // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { // Enable the application to use a cookie to store information for the signed in user // and to use a cookie to temporarily store information about a user logging in with a third party login provider // Configure the sign in cookie app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), LogoutPath = new PathString("/Account/LogOff"), ExpireTimeSpan = TimeSpan.FromMinutes(5.0), ReturnUrlParameter = "/Home/Index" }); app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // Uncomment the following lines to enable logging in with third party login providers //app.UseMicrosoftAccountAuthentication( // clientId: "", // clientSecret: ""); //app.UseTwitterAuthentication( // consumerKey: "", // consumerSecret: ""); //app.UseFacebookAuthentication( // appId: "", // appSecret: ""); //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() //{ // ClientId = "", // ClientSecret = "" //}); } } }
In above code following line of code will redirect the user to home page if he/she tries to access a link which is not authorized to him/her:
ReturnUrlParameter = "/Home/Index"
6) Create new controller, name it "AccountController.cs" under "Controller" folder and replace it with following code:
//----------------------------------------------------------------------- // <copyright file="AccountController.cs" company="None"> // Copyright (c) Allow to distribute this code. // </copyright> // <author>Asma Khalid</author> //----------------------------------------------------------------------- namespace RoleBaseAccessibility.Controllers { using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Web; using System.Web.Mvc; using Microsoft.AspNet.Identity; using Microsoft.Owin.Security; using RoleBaseAccessibility.Models; /// <summary> /// Account controller class. /// </summary> public class AccountController : Controller { #region Private Properties /// <summary> /// Database Store property. /// </summary> private RoleBaseAccessibilityEntities databaseManager = new RoleBaseAccessibilityEntities(); #endregion #region Default Constructor /// <summary> /// Initializes a new instance of the <see cref="AccountController" /> class. /// </summary> public AccountController() { } #endregion #region Login methods /// <summary> /// GET: /Account/Login /// </summary> /// <param name="returnUrl">Return URL parameter</param> /// <returns>Return login view</returns> [AllowAnonymous] public ActionResult Login(string returnUrl) { try { // Verification. if (this.Request.IsAuthenticated) { // Info. return this.RedirectToLocal(returnUrl); } } catch (Exception ex) { // Info Console.Write(ex); } // Info. return this.View(); } /// <summary> /// POST: /Account/Login /// </summary> /// <param name="model">Model parameter</param> /// <param name="returnUrl">Return URL parameter</param> /// <returns>Return login view</returns> [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult Login(LoginViewModel model, string returnUrl) { try { // Verification. if (ModelState.IsValid) { // Initialization. var loginInfo = this.databaseManager.LoginByUsernamePassword(model.Username, model.Password).ToList(); // Verification. if (loginInfo != null && loginInfo.Count() > 0) { // Initialization. var logindetails = loginInfo.First(); // Login In. this.SignInUser(logindetails.username, logindetails.role_id, false); // setting. this.Session["role_id"] = logindetails.role_id; // Info. return this.RedirectToLocal(returnUrl); } else { // Setting. ModelState.AddModelError(string.Empty, "Invalid username or password."); } } } catch (Exception ex) { // Info Console.Write(ex); } // If we got this far, something failed, redisplay form return this.View(model); } #endregion #region Log Out method. /// <summary> /// POST: /Account/LogOff /// </summary> /// <returns>Return log off action</returns> [HttpPost] [ValidateAntiForgeryToken] public ActionResult LogOff() { try { // Setting. var ctx = Request.GetOwinContext(); var authenticationManager = ctx.Authentication; // Sign Out. authenticationManager.SignOut(); } catch (Exception ex) { // Info throw ex; } // Info. return this.RedirectToAction("Login", "Account"); } #endregion #region Helpers #region Sign In method. /// <summary> /// Sign In User method. /// </summary> /// <param name="username">Username parameter.</param> /// <param name="role_id">Role ID parameter</param> /// <param name="isPersistent">Is persistent parameter.</param> private void SignInUser(string username, int role_id, bool isPersistent) { // Initialization. var claims = new List<Claim>(); try { // Setting claims.Add(new Claim(ClaimTypes.Name, username)); claims.Add(new Claim(ClaimTypes.Role, role_id.ToString())); var claimIdenties = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie); var ctx = Request.GetOwinContext(); var authenticationManager = ctx.Authentication; // Sign In. authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, claimIdenties); } catch (Exception ex) { // Info throw ex; } } #endregion #region Redirect to local method. /// <summary> /// Redirect to local method. /// </summary> /// <param name="returnUrl">Return URL parameter.</param> /// <returns>Return redirection action</returns> private ActionResult RedirectToLocal(string returnUrl) { try { // Verification. if (Url.IsLocalUrl(returnUrl)) { // Info. return this.Redirect(returnUrl); } } catch (Exception ex) { // Info throw ex; } // Info. return this.RedirectToAction("Index", "Home"); } #endregion #endregion } }
In above code, following piece of code is important i.e.
#region Sign In method. /// <summary> /// Sign In User method. /// </summary> /// <param name="username">Username parameter.</param> /// <param name="role_id">Role ID parameter</param> /// <param name="isPersistent">Is persistent parameter.</param> private void SignInUser(string username, int role_id, bool isPersistent) { // Initialization. var claims = new List<Claim>(); try { // Setting claims.Add(new Claim(ClaimTypes.Name, username)); claims.Add(new Claim(ClaimTypes.Role, role_id.ToString())); var claimIdenties = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie); var ctx = Request.GetOwinContext(); var authenticationManager = ctx.Authentication; // Sign In. authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, claimIdenties); } catch (Exception ex) { // Info throw ex; } } #endregion
Here, along with claiming "Username" in OWIN security layer, we are also claiming "role_id" to provide role base accessibility:
claims.Add(new Claim(ClaimTypes.Role, role_id.ToString()));
7) Now, create new controller under "Controller" folder, name it "HomeController.cs" and replace it with following code i.e.
// <copyright file="HomeController.cs" company="None"> // Copyright (c) Allow to distribute this code. // </copyright> // <author>Asma Khalid</author> //----------------------------------------------------------------------- namespace RoleBaseAccessibility.Controllers { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; /// <summary> /// Home controller class. /// </summary> [Authorize] public class HomeController : Controller { #region Index method. /// <summary> /// Index method. /// </summary> /// <returns>Returns - Index view</returns> public ActionResult Index() { return this.View(); } #endregion #region Admin Only Link /// <summary> /// Admin only link method. /// </summary> /// <returns>Returns - Admin only link view</returns> [Authorize(Roles = "1")] public ActionResult AdminOnlyLink() { return this.View(); } #endregion } }
In above code, we have simply created two views, one is accessible to all the user which is "Index" view and second method is accessible to only "Admin" role user with role_id = 1. Following piece of code will translate the role base accessibility in OWIN security layer i.e.
[Authorize(Roles = "1")]
If you want to define role accessibility for multiple roles you can achieve it like following:
[Authorize(Roles = "1, 2, 3")]
where, 2, 3 are role id(s). 8) Replace following code in "_LoginPartial.cshtml" file:
@*@using Microsoft.AspNet.Identity*@ @if (Request.IsAuthenticated) { using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) { @Html.AntiForgeryToken() <ul class="nav navbar-nav navbar-right"> @if (Convert.ToInt32(this.Session["role_id"]) == 1) { <li> @Html.ActionLink("Admin Only Link", "AdminOnlyLink", "Home") </li> } <li> @Html.ActionLink("Hello " + User.Identity.Name + "!", "Index", "Home", routeValues: null, htmlAttributes: new { title = "Manage" }) </li> <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li> </ul> } } else { <ul class="nav navbar-nav navbar-right"> <li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li> </ul> }
9) Execute the project and you will see following:
Enjoy coding!!!
This is really a great post. Thank you for taking time to provide us some of the useful and exclusive information with us. Keep on blogging!!
ReplyDeleteHadoop Training in Chennai
Thanks for appreciation
ReplyDeleteI read your post, it's very useful for me. keep updating..
ReplyDeleteEmbedded Project Center in Chennai | Mat Lab Project Center in Chennai | Big Data Project Center in Chennai
Thank you
DeletePretty article! I found some useful information in your blog, it was awesome to read, thanks for sharing this great content to my vision, keep sharing.
ReplyDeleteJava Project Center in Chennai | Java Project Center in Velachery
Thank you
DeleteReally very awesome Blog..Thanks for sharing..keep sharing such a nice blog.
ReplyDeleteMultiMedia Training Institute in Chennai | MultiMedia Training Center in Velachery | Graphic Designing Course in Chennai
Thank you
Deletewhat a innovative post..thanks for updating your blog...very nice..
ReplyDeleteJava Training in Chennai | Web Designing Training Institute in Chennai | DotNet Training Institute in Chennai
Very informative blog to sharing..Thanks for collecting important points..Keep sharing..
ReplyDeleteNo.1 IOS Training Institute in Chennai | Best IOS Training Institute in Velachery
Very nice blog. I appreciate your coding knowledge. This blog gave me a good idea to develop the android application.Thanks for sharing...No.1 IOS Training Institute in Velachery | Best Android Training Institute in Velachery | Core Java Training Institute in Chennai
ReplyDeleteGlad to be of help.
DeleteI gain more knowledge from your post..Thanks for sharing valuable information from your post..
ReplyDeleteSummer Courses in Adyar | Summer Courses in OMR | Summer Courses in Velachery
Very informative post! There is a lot of information here that can help any business get started with a successful...
ReplyDeleteSummer Courses for Business Administration in Chennai | Best Summer Courses in Porur
Thank you a lot for providing individuals with a very spectacular possibility to read critical reviews from this site.
ReplyDeleteData Science training in Chennai | Data Science Training Institute in Chennai
Data science training in Bangalore | Data Science Training institute in Bangalore
Data science training in pune | Data Science training institute in Pune
Data science online training | online Data Science certification Training-Gangboard
Data Science Interview questions and answers
The content you post in this site is very useful to me.I am very greatful to show my thanks.
ReplyDeleteLivewire Velachery.
9384409662
Thank you for your kind words.
DeleteThis is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.
ReplyDeleterpa training in chennai
rpa training in bangalore
rpa training in pune
rpa training in marathahalli
rpa training in btm
Thank you
DeleteHmm, it seems like your site ate my first comment (it was extremely long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly enjoying your blog. I as well as an aspiring blog writer, but I’m still new to the whole thing. Do you have any recommendations for newbie blog writers? I’d appreciate it.
ReplyDeleteTop 250+AWS Interviews Questions and Answers 2018 [updated]
Learn Amazon Web Services Tutorials 2018 | AWS Tutorial For Beginners
Best AWS Interview questions and answers 2018 | Top 110+AWS Interview Question and Answers 2018
Best and Advanced AWS Training in Bangalore | Best Amazon Web Services Training in Bangalore
Advanced AWS Training in Pune | Best Amazon Web Services Training in Pune
Advanced AWS Online Training 2018 | Best Online AWS Certification Course 2018
Thank you for the kind words. I recommend that if you are tech blogger then do go to online tech communities like technet wiki or C-sharpcorner and respond forums Q/A it will help you a lot.
DeleteThis is a nice post in an interesting line of content.Thanks for sharing this article, great way of bring this topic to discussion.
ReplyDeleteJava interview questions and answers
Core Java interview questions and answers| Java interview questions and answers
Java training in Chennai | Java training in Tambaram
Java training in Chennai | Java training in Velachery
This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me..
ReplyDeleteBest Devops online Training
Online DevOps Certification Course - Gangboard
Thank you for your kind words.
DeleteOnline casino for everyone, come in and win now only we have the best online slots The best online slots we have.
ReplyDeleteFabulous post admin, it was too good and helpful. Waiting for more updates.
ReplyDeleteMachine Learning course in Chennai
Machine Learning Training in Chennai
Data Science Course in Chennai
Data Science Training in Chennai
DevOps certification in Chennai
DevOps Training in Chennai
Machine Learning Training in Velachery
Machine Learning Training in Tambaram
Если возникнет вопрос где купить светодиодную ленту вы всегда можете обратится к нам в Ekodio
ReplyDelete