`
pcajax
  • 浏览: 2162375 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

mvc中有关用户权限的详解

 
阅读更多
When standard types of authentication do not meet your requirements, you need to modify an authentication mechanism to create a custom solution. A user context has principal which represents the identity and roles for that user. A user is authenticated by its identity and assigned roles to a user determine about authorization or permission to access resources.

ASP.NET provides IPrincipal and IIdentity interfaces to represents the identity and role for a user. You can create a custom solution by evaluating the IPrincipal and IIdentity interfaces which are bound to the HttpContext as well as the current thread.

  1. public class CustomPrincipal : IPrincipal
  2. {
  3. public IIdentity Identity { get; private set; }
  4. public bool IsInRole(string role)
  5. {
  6. if (roles.Any(r => role.Contains(r)))
  7. {
  8. return true;
  9. }
  10. else
  11. {
  12. return false;
  13. }
  14. }
  15.  
  16. public CustomPrincipal(string Username)
  17. {
  18. this.Identity = new GenericIdentity(Username);
  19. }
  20.  
  21. public int UserId { get; set; }
  22. public string FirstName { get; set; }
  23. public string LastName { get; set; }
  24. public string[] roles { get; set; }
  25. }

Now you can put this CustomPrincipal objects into the thread’s currentPrinciple property and into the HttpContext’s User property to accomplish your custom authentication and authorization process.

ASP.NET Forms Authentication

ASP.NET forms authentication occurs after IIS authentication is completed. You can configure forms authentication by using forms element with in web.config file of your application. The default attribute values for forms authentication are shown below:

  1. <system.web>
  2. <authentication mode="Forms">
  3. <forms loginUrl="Login.aspx"
  4. protection="All"
  5. timeout="30"
  6. name=".ASPXAUTH"
  7. path="/"
  8. requireSSL="false"
  9. slidingExpiration="true"
  10. defaultUrl="default.aspx"
  11. cookieless="UseDeviceProfile"
  12. enableCrossAppRedirects="false" />
  13. </authentication>
  14. </system.web>

The FormsAuthentication class creates the authentication cookie automatically when SetAuthCookie() or RedirectFromLoginPage() methods are called. The value of authentication cookie contains a string representation of the encrypted and signed FormsAuthenticationTicket object.

You can create the FormsAuthenticationTicket object by specifying the cookie name, version of the cookie, directory path, issue date of the cookie, expiration date of the cookie, whether the cookie should be persisted, and optionally user-defined data as shown below:

  1. FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
  2. "userName",
  3. DateTime.Now,
  4. DateTime.Now.AddMinutes(30), // value of time out property
  5. false, // Value of IsPersistent property
  6. String.Empty,
  7. FormsAuthentication.FormsCookiePath);

Now, you can encrypt this ticket by using the Encrypt method FormsAuthentication class as given below:

  1. string encryptedTicket = FormsAuthentication.Encrypt(ticket);

Note

To encrypt FormsAuthenticationTicket ticket set the protection attribute of the forms element to All or Encryption.

Custom Authorization

ASP.NET MVC provides Authorization filter to authorize a user. This filter can be applied to an action, a controller, or even globally. This filter is based on AuthorizeAttribute class. You can customize this filter by overriding OnAuthorization() method as shown below:

  1. public class CustomAuthorizeAttribute : AuthorizeAttribute
  2. {
  3. public string UsersConfigKey { get; set; }
  4. public string RolesConfigKey { get; set; }
  5.  
  6. protected virtual CustomPrincipal CurrentUser
  7. {
  8. get { return HttpContext.Current.User as CustomPrincipal; }
  9. }
  10.  
  11. public override void OnAuthorization(AuthorizationContext filterContext)
  12. {
  13. if (filterContext.HttpContext.Request.IsAuthenticated)
  14. {
  15. var authorizedUsers = ConfigurationManager.AppSettings[UsersConfigKey];
  16. var authorizedRoles = ConfigurationManager.AppSettings[RolesConfigKey];
  17.  
  18. Users = String.IsNullOrEmpty(Users) ? authorizedUsers : Users;
  19. Roles = String.IsNullOrEmpty(Roles) ? authorizedRoles : Roles;
  20. if (!String.IsNullOrEmpty(Roles))
  21. {
  22. if (!CurrentUser.IsInRole(Roles))
  23. {
  24. filterContext.Result = new RedirectToRouteResult(new
  25. RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
  26.  
  27. // base.OnAuthorization(filterContext); //returns to login url
  28. }
  29. }
  30.  
  31. if (!String.IsNullOrEmpty(Users))
  32. {
  33. if (!Users.Contains(CurrentUser.UserId.ToString()))
  34. {
  35. filterContext.Result = new RedirectToRouteResult(new
  36. RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
  37.  
  38. // base.OnAuthorization(filterContext); //returns to login url
  39. }
  40. }
  41. }
  42. }
  43. }

User Authentication

A user will be authenticated if IsAuthenticated property returns true. For authenticating a user you can use one of the following two ways:

  1. Thread.CurrentPrincipal.Identity.IsAuthenticated

  2. HttpContext.Current.User.Identity.IsAuthenticated

Designing Data Model

Now it’s time to create data access model classes for creating and accessing Users and Roles as shown below:

  1. public class User
  2. {
  3. public int UserId { get; set; }
  4.  
  5. [Required]
  6. public String Username { get; set; }
  7.  
  8. [Required]
  9. public String Email { get; set; }
  10.  
  11. [Required]
  12. public String Password { get; set; }
  13.  
  14. public String FirstName { get; set; }
  15. public String LastName { get; set; }
  16.  
  17. public Boolean IsActive { get; set; }
  18. public DateTime CreateDate { get; set; }
  19.  
  20. public virtual ICollection<Role> Roles { get; set; }
  21. }
  1. public class Role
  2. {
  3. public int RoleId { get; set; }
  4.  
  5. [Required]
  6. public string RoleName { get; set; }
  7. public string Description { get; set; }
  8.  
  9. public virtual ICollection<User> Users { get; set; }
  10. }

Defining Database Context with code first mapping between User and Role

Using Entity Framework code first approach, create a DataContext having User and Role entities with its relational mapping details as shown below:

  1. public class DataContext : DbContext
  2. {
  3. public DataContext()
  4. : base("DefaultConnection")
  5. {
  6.  
  7. }
  8. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  9. {
  10. modelBuilder.Entity<User>()
  11. .HasMany(u => u.Roles)
  12. .WithMany(r=>r.Users)
  13. .Map(m =>
  14. {
  15. m.ToTable("UserRoles");
  16. m.MapLeftKey("UserId");
  17. m.MapRightKey("RoleId");
  18. });
  19. }
  20. public DbSet<User> Users { get; set; }
  21. public DbSet<Role> Roles { get; set; }
  22. }

Code First Database Migrations

With the help of entity framework code first database migrations create the database named as Security in the SQL Server. Run the following command through Visual Studio Package Manager Console to migrate your code into SQL Server database.

After running first command i.e. enabling migrations for your project, add seed data to Configuration.cs file of Migrations folder as shown below:

  1. protected override void Seed(Security.DAL.DataContext context)
  2. {
  3. Role role1 = new Role { RoleName = "Admin" };
  4. Role role2 = new Role { RoleName = "User" };
  5.  
  6. User user1 = new User { Username = "admin", Email = "admin@ymail.com", FirstName = "Admin", Password = "123456", IsActive = true, CreateDate = DateTime.UtcNow, Roles = new List<role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">()</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">};</span></role>
  7. <role style="BOX-SIZING: border-box"></role>
  8. <role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">User</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> user2 </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,0,128); VERTICAL-ALIGN: top" class="kwd">new</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">User</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">{</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Username</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,104,32); VERTICAL-ALIGN: top" class="str">"user1"</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">,</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Email</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,104,32); VERTICAL-ALIGN: top" class="str">"user1@ymail.com"</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">,</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">FirstName</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,104,32); VERTICAL-ALIGN: top" class="str">"User1"</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">,</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Password</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,104,32); VERTICAL-ALIGN: top" class="str">"123456"</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">,</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">IsActive</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,0,128); VERTICAL-ALIGN: top" class="kwd">true</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">,</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">CreateDate</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">DateTime</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">UtcNow</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">,</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Roles</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">=</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(255,0,128); VERTICAL-ALIGN: top" class="kwd">new</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">List</span><role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">()</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">};</span></role></role>
  9. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"></role></role>
  10. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> user1</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Roles</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Add</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">(</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln">role1</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">);</span></role></role>
  11. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> user2</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Roles</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Add</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">(</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln">role2</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">);</span></role></role>
  12. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"></role></role>
  13. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> context</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Users</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Add</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">(</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln">user1</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">);</span></role></role>
  14. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> context</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Users</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">.</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(83,83,166); VERTICAL-ALIGN: top" class="typ">Add</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">(</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln">user2</span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">);</span></role></role>
  15. <role style="BOX-SIZING: border-box"><role style="BOX-SIZING: border-box"><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pln"> </span><span style="BOX-SIZING: border-box; MARGIN: 0px; COLOR: rgb(57,49,36); VERTICAL-ALIGN: top" class="pun">}</span></role></role>

When above three commands will be executed successfully as shown above, the following database will be created in your SQL Server.

Solution Structure

Designing View Model

Create a view model class for handing login process as given below:

  1. public class LoginViewModel
  2. {
  3. [Required]
  4. [Display(Name = "User name")]
  5. public string Username { get; set; }
  6.  
  7. [Required]
  8. [DataType(DataType.Password)]
  9. [Display(Name = "Password")]
  10. public string Password { get; set; }
  11.  
  12. [Display(Name = "Remember me?")]
  13. public bool RememberMe { get; set; }
  14. }
  1. public class CustomPrincipalSerializeModel
  2. {
  3. public int UserId { get; set; }
  4. public string FirstName { get; set; }
  5. public string LastName { get; set; }
  6. public string[] roles { get; set; }
  7. }

Forms Authentication Initialization

  1. public class AccountController : Controller
  2. {
  3. DataContext Context = new DataContext();
  4. //
  5. // GET: /Account/
  6. public ActionResult Index()
  7. {
  8. return View();
  9. }
  10.  
  11. [HttpPost]
  12. public ActionResult Index(LoginViewModel model, string returnUrl = "")
  13. {
  14. if (ModelState.IsValid)
  15. {
  16. var user = Context.Users.Where(u => u.Username == model.Username && u.Password == model.Password).FirstOrDefault();
  17. if (user != null)
  18. {
  19. var roles=user.Roles.Select(m => m.RoleName).ToArray();
  20.  
  21. CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
  22. serializeModel.UserId = user.UserId;
  23. serializeModel.FirstName = user.FirstName;
  24. serializeModel.LastName = user.LastName;
  25. serializeModel.roles = roles;
  26.  
  27. string userData = JsonConvert.SerializeObject(serializeModel);
  28. FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
  29. 1,
  30. user.Email,
  31. DateTime.Now,
  32. DateTime.Now.AddMinutes(15),
  33. false,
  34. userData);
  35.  
  36. string encTicket = FormsAuthentication.Encrypt(authTicket);
  37. HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
  38. Response.Cookies.Add(faCookie);
  39.  
  40. if(roles.Contains("Admin"))
  41. {
  42. return RedirectToAction("Index", "Admin");
  43. }
  44. else if (roles.Contains("User"))
  45. {
  46. return RedirectToAction("Index", "User");
  47. }
  48. else
  49. {
  50. return RedirectToAction("Index", "Home");
  51. }
  52. }
  53.  
  54. ModelState.AddModelError("", "Incorrect username and/or password");
  55. }
  56.  
  57. return View(model);
  58. }
  59.  
  60. [AllowAnonymous]
  61. public ActionResult LogOut()
  62. {
  63. FormsAuthentication.SignOut();
  64. return RedirectToAction("Login", "Account", null);
  65. }
  66. }
  1. public class MvcApplication : System.Web.HttpApplication
  2. {
  3. protected void Application_Start()
  4. {
  5. AreaRegistration.RegisterAllAreas();
  6.  
  7. WebApiConfig.Register(GlobalConfiguration.Configuration);
  8. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  9. RouteConfig.RegisterRoutes(RouteTable.Routes);
  10. BundleConfig.RegisterBundles(BundleTable.Bundles);
  11.  
  12. Database.SetInitializer<DataContext>(new DataContextInitilizer());
  13. }
  14. protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
  15. {
  16. HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
  17. if (authCookie != null)
  18. {
  19.  
  20. FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
  21.  
  22. CustomPrincipalSerializeModel serializeModel = JsonConvert.DeserializeObject<CustomPrincipalSerializeModel>(authTicket.UserData);
  23. CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
  24. newUser.UserId = serializeModel.UserId;
  25. newUser.FirstName = serializeModel.FirstName;
  26. newUser.LastName = serializeModel.LastName;
  27. newUser.roles = serializeModel.roles;
  28.  
  29. HttpContext.Current.User = newUser;
  30. }
  31.  
  32. }
  33. }

Base Controller for accessing Current User

Create a base controller for accessing your User data in your all controller. Inherit, your all controller from this base controller to access user information from the UserContext.

  1. public class BaseController : Controller
  2. {
  3. protected virtual new CustomPrincipal User
  4. {
  5. get { return HttpContext.User as CustomPrincipal; }
  6. }
  7. }
  1. public class HomeController : BaseController
  2. {
  3. //
  4. // GET: /Home/
  5. public ActionResult Index()
  6. {
  7. string FullName = User.FirstName + " " + User.LastName;
  8. return View();
  9. }
  10. }

Base View Page for accessing Current User

Create a base class for all your views for accessing your User data in your all views as shown below:

  1. public abstract class BaseViewPage : WebViewPage
  2. {
  3. public virtual new CustomPrincipal User
  4. {
  5. get { return base.User as CustomPrincipal; }
  6. }
  7. }
  8. public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
  9. {
  10. public virtual new CustomPrincipal User
  11. {
  12. get { return base.User as CustomPrincipal; }
  13. }
  14. }

Register this class with in the \Views\Web.config as base class for all your views as given below:

  1. <system.web.webPages.razor>
  2. <!--Other code has been removed for clarity-->
  3. <pages pageBaseType="Security.DAL.Security.BaseViewPage">
  4. <namespaces>
  5. <!--Other code has been removed for clarity-->
  6. </namespaces>
  7. </pages>
  8. </system.web.webPages.razor>

Now you can access the authenticated user information on all your view in easy and simple way as shown below in Admin View:

  1. @{
  2. ViewBag.Title = "Index";
  3. Layout = "~/Views/Shared/_AdminLayout.cshtml";
  4. }
  5. <h4>Welcome : @User.FirstName</h4>
  6. <h1>Admin DashBoard</h1>

Login View

  1. @model Security.Models.LoginViewModel
  2.  
  3. @{
  4. ViewBag.Title = "Index";
  5. }
  6.  
  7. @using (Html.BeginForm())
  8. {
  9. @Html.AntiForgeryToken()
  10. <div class="form-horizontal">
  11. <h4>User Login</h4>
  12. <hr />
  13. @Html.ValidationSummary(true)
  14.  
  15. <div class="form-group">
  16. @Html.LabelFor(model => model.Username, new { @class = "control-label col-md-2" })
  17. <div class="col-md-10">
  18. @Html.EditorFor(model => model.Username)
  19. @Html.ValidationMessageFor(model => model.Username)
  20. </div>
  21. </div>
  22.  
  23. <div class="form-group">
  24. @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
  25. <div class="col-md-10">
  26. @Html.EditorFor(model => model.Password)
  27. @Html.ValidationMessageFor(model => model.Password)
  28. </div>
  29. </div>
  30.  
  31. <div class="form-group">
  32. @Html.LabelFor(model => model.RememberMe, new { @class = "control-label col-md-2" })
  33. <div class="col-md-10">
  34. @Html.EditorFor(model => model.RememberMe)
  35. @Html.ValidationMessageFor(model => model.RememberMe)
  36. </div>
  37. </div>
  38.  
  39. <div class="form-group">
  40. <div class="col-md-offset-2 col-md-10">
  41. <input type="submit" value="Login" class="btn btn-default" />
  42. </div>
  43. </div>
  44. </div>
  45. }

Applying CustomAuthorize attribute

To make secure your admin or user pages, decorate your Admin and User controllers with CustomAuthorize attribute as defined above and specify the uses or roles to access admin and user pages.

  1. [CustomAuthorize(Roles= "Admin")]
  2. // [CustomAuthorize(Users = "1")]
  3. public class AdminController : BaseController
  4. {
  5. //
  6. // GET: /Admin/
  7. public ActionResult Index()
  8. {
  9. return View();
  10. }
  11. }
  1. [CustomAuthorize(Roles= "User")]
  2. // [CustomAuthorize(Users = "1,2")]
  3. public class UserController : BaseController
  4. {
  5. //
  6. // GET: /User/
  7. public ActionResult Index()
  8. {
  9. return View();
  10. }
  11. }

You can also specify the Roles and Users with in your web.config as a key to avoid hard code values for Users and Roles at the controller level.

  1. <add key="RolesConfigKey" value="Admin"/>
  2. <add key="UsersConfigKey" value="2,3"/>

Use one of these keys within the CustomAuthorize attribute as shown below:

  1. //[CustomAuthorize(RolesConfigKey = "RolesConfigKey")]
  2. [CustomAuthorize(UsersConfigKey = "UsersConfigKey")]
  3.  
  4. public class AdminController : BaseController
  5. {
  6. //
  7. // GET: /Admin/
  8. public ActionResult Index()
  9. {
  10. return View();
  11. }
  12. }
  1. [CustomAuthorize(RolesConfigKey = "RolesConfigKey")]
  2. // [CustomAuthorize(UsersConfigKey = "UsersConfigKey")]
  3. public class UserController : BaseController
  4. {
  5. //
  6. // GET: /User/
  7. public ActionResult Index()
  8. {
  9. return View();
  10. }
  11. }

Test your application

When you will run your application and will login into the application using user1, you will be redirected to User dashboard as shown below:

When user will try to access unauthorized pages such as Admin dashboard using URL: http://localhost:11681/Admin , he will get the custom error page as shown below:


分享到:
评论

相关推荐

    MVC编写的权限系统,有权限,角色,用户,还包括产品测试模块

    **MVC权限系统详解** 在IT行业中,MVC(Model-View-Controller)架构模式被广泛应用于Web应用程序的开发,因为它能有效地分离业务逻辑、数据处理和用户界面。本项目是一个基于MVC模式构建的权限管理系统,它包含了...

    mvc权限控制案例

    ### MVC权限控制案例详解 #### 一、背景与目的 在现代Web开发中,权限管理是确保应用程序安全性和用户访问合理性的关键环节之一。对于基于ASP.NET MVC框架的应用程序而言,设计合理的权限控制系统尤为重要。本文将...

    MVC4通用权限管理源码

    **MVC4通用权限管理源码详解** 在Web开发领域,Microsoft的ASP.NET MVC框架以其灵活性、可测试性和模块化设计而备受青睐。MVC4是该框架的一个版本,它在MVC3的基础上进行了优化和增强,引入了新的功能和性能改进。...

    MVC通用权限系统1

    **MVC模式详解** MVC(Model-View-Controller)是一种广泛应用于Web应用程序设计的软件架构模式,旨在提高代码的可维护性和可扩展性。在MVC模式中,应用程序的逻辑被分成了三个主要组件:模型(Model)、视图(View...

    毕业设计:基于ASP.NET MVC搭建的通用权限后台管理系统.zip

    例如,管理员、普通用户等。系统可能包含角色注册、角色分配、角色权限设置等功能。 5. 权限控制:权限控制是系统安全的核心,通过授权确定用户对资源的访问权限。ASP.NET MVC可以结合授权过滤器实现这一功能,比如...

    asp.net+Web+mvc4.0 EasyUI 最新 权限管理系统源码教程

    **ASP.NET + Web + MVC4.0 + EasyUI 权限管理系统详解** 本文将深入探讨如何使用ASP.NET、Web技术和MVC4.0框架,结合EasyUI库来构建一个先进的权限管理系统。首先,我们需要理解ASP.NET是微软推出的一种用于构建...

    asp.net+Web+mvc4.0 EasyUI 最新 权限管理系统源码

    在权限管理系统中,我们可以利用EasyUI的这些组件创建直观的用户界面,如用户管理界面、角色分配面板、权限设置表单等。 在权限管理中,常见的功能包括用户注册与登录、角色管理、权限分配和访问控制。用户注册与...

    Spring MVC核心组件之HandlerMapping详解

    ### Spring MVC核心组件之HandlerMapping详解 #### 一、引言 在Java Web开发领域,Spring MVC框架因其灵活且强大的特性而备受青睐。它提供了一种简洁的方式来构建可维护、可扩展的应用程序。Spring MVC的核心组件之...

    A014 MVC权限管理系统源码.zip

    - **角色分配(Role Assignment)**:管理员可以将角色分配给用户,赋予其角色所包含的所有权限。 - **权限分配(Permission Assignment)**:除了角色分配,也可以直接给用户分配特定的权限。 **4. MVC4的实现...

    AngelRM_MVC通用权限管理系统 v2.1.zip

    在AngelRM_MVC中,模型层可能包括用户管理、角色管理、权限管理等实体类,用于处理与数据库的交互,如增删改查操作。 2. 视图(View):是用户看到和与之交互的界面。在系统中,视图可能包括各种网页或组件,如登录...

    Spring MVC3构建Web应用详解

    Spring MVC 是一个强大的Java Web应用程序框架,用于构建高效、模块化的Web应用。...在实际开发中,还可以集成其他Spring模块,如Spring Security进行权限管理,Spring Data进行数据访问,进一步提升应用的功能和性能。

    MVC3中文安装包

    如果出现安装问题,可以尝试以管理员权限运行安装程序。 **5. 中文支持** MVC3中文安装包的主要目的是提供用户界面的中文本地化,包括错误消息、帮助文档和开发环境的界面。这使得中国开发者和用户能够更直观地理解...

    spring mvc过程详解

    #### 六、Spring MVC 配置文件详解 Spring MVC 的配置文件通常包含了以下几个关键部分: 1. **DispatcherServlet 配置**:配置 DispatcherServlet 如何初始化以及加载配置文件。 2. **视图解析器配置**:配置 ...

    Spring中的mvc详解

    Spring MVC支持根据用户的locale设置提供不同的资源和服务,通过`LocaleResolver`和`MessageSource`实现。 8. **RESTful风格** Spring MVC支持创建RESTful服务,通过`@GetMapping`、`@PostMapping`等注解映射HTTP...

    MVC+EF框架+EasyUI实现权限管理(源码)

    1. **用户管理**:创建、编辑、删除用户,分配角色。 2. **角色管理**:定义角色,分配权限。 3. **权限分配**:将特定操作或资源授权给角色,角色再授予给用户。 4. **认证与授权**:通过MVC的授权特性,控制用户...

    Struts 2 技术详解:基于WebWork核心的MVC开发与实践

    Struts 2 是一个强大的Java Web应用程序框架,它基于Model-View-Controller(MVC)设计模式,提供了灵活的架构来构建可维护性和扩展性良好的Web应用。在深入讲解Struts 2之前,我们先来了解一下MVC模式的基本概念。 ...

    MVCProject.rar

    在"权限管理、日志管理、用户管理、角色管理、菜单管理"这些场景中,模型会包含各种实体类,如User、Role、Menu等,以及相应的业务逻辑方法,如用户的登录验证、角色权限的分配等。 2. **视图(View)**:视图是...

    基于javaMVC的管理员管理系统,这是java项目基本代码与实现,希望对你有帮助

    在这个基于Java MVC的管理员管理系统中,我们可以看到它主要关注的是后端开发,特别是针对管理者的功能实现。 1. **MVC模式详解**: - **Model(模型)**:负责处理业务逻辑和数据管理,通常与数据库交互,获取或...

    MVC新闻管理系统

    **MVC新闻管理系统详解** MVC(Model-View-Controller)模式是一种软件设计模式,广泛应用于Web应用开发中,尤其在PHP领域。本系统“MVC新闻管理系统”就是基于这种模式构建的,旨在提供高效、模块化的新闻内容管理...

Global site tag (gtag.js) - Google Analytics