在ASP.NET MVC5中建置以角色为基础的授权机制
在前一篇贴文中,已探索过如何在MVC5中自定ASP.NET Identity,接下来要来试试在MVC5中如何运用 ASP.NET Identity来设定一个以 "角色"为基础的授权机制。为了方便起见,简化了这个认证机制的内容,同时假设这是一个公司内部使用的应用程序,所以拿掉了"注册"的功能,所有的使用账 号管理都必须透过某一管理权限(Admin)的使用者来进行,也就是说只有具备有 Admin 角色的使用者可以执行”账户管理"的功能。
贴文内容:
建立MVC5新项目
修改相关 Mdels
扩展Identity Management Mdel
加入新字段
建立Helper Class
扩展Accunt Management ViewMdels (AccuntViewMdels.cs)
在RegisterViewMdel加入新字段 及 GetUser methd
新增 EditUserViewMdel、SelectUserRlesViewMdel、SelectRleEditrViewMdel
修改相关 Cntrllers
修改AccuntCntrller 中 Register Methd 加入 Authrize attribute
加入 Index Methd (ActinResult)
加入 Edit Methd (ActinResult)
加入 Delete Methd (ActinResult)
加入 UserRles Methd (ActinResult)
修改相关 Views
修改Register.cshtml View
新增Edit、Delete、Index 等方法的Views
新增UserRles.cshtml View 并 新增程序代码
新增 SelectRleEditrViewMdel.cshtml 在 Shared/EditrTemplates目录下
在主页面上新增”账号管理" 功能按钮
移除主页面上的注册功能
启动 Migratin功能
在Seed()方法中加入建立测试数据的程序代码
更新数据库
执行结果
建立MVC5新项目


修改相关 Models
1. 扩展Identity Management Model (IdentityModels.cs)
加入新字段:为使用者数据多加三个属性字段,分别是FirstName、LastName、Email。

建立Helper Class:利用Asp.Net Identity API建立一个 Identity Management Helper class: IdentityManager class,包含有建立角色、建立使用者...等功能。

IdentityModels.cs 完整程序


01.using Microsoft.AspNet.Identity;02.using Microsoft.AspNet.Identity.EntityFramework;03.using System.Collections.Generic;04.using System.ComponentModel.DataAnnotations;05. 06.namespace RoleBaseProject.Models07.{08.// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.09.public class ApplicationUser : IdentityUser10.{11.[Required]12.public string FirstName { get; set; }13. 14.[Required]15.public string LastName { get; set; }16.[Required]17.public string Email { get; set; }18.}19. 20.public class ApplicationDbContext : IdentityDbContext<ApplicationUser>21.{22.public ApplicationDbContext()23.: base("DefaultConnection")24.{25.}26.}27. 28.public class IdentityManager29.{30.// 判断角色是否已在存在31.public bool RoleExists(string name)32.{33.var rm = new RoleManager<IdentityRole>(34.new RoleStore<IdentityRole>(new ApplicationDbContext()));35.return rm.RoleExists(name);36.}37.// 新增角色38.public bool CreateRole(string name)39.{40.var rm = new RoleManager<IdentityRole>(41.new RoleStore<IdentityRole>(new ApplicationDbContext()));42.var idResult = rm.Create(new IdentityRole(name));43.return idResult.Succeeded;44.}45.// 新增角色46.public bool CreateUser(ApplicationUser user, string pass<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>)47.{48.var um = new UserManager<ApplicationUser>(49.new UserStore<ApplicationUser>(new ApplicationDbContext()));50.var idResult = um.Create(user, pass<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>);51.return idResult.Succeeded;52.}53.// 将使用者加入角色中54.public bool AddUserToRole(string userId, string roleName)55.{56.var um = new UserManager<ApplicationUser>(57.new UserStore<ApplicationUser>(new ApplicationDbContext()));58.var idResult = um.AddToRole(userId, roleName);59.return idResult.Succeeded;60.}61.// 清除使用者的角色设定62.public void ClearUserRoles(string userId)63.{64.var um = new UserManager<ApplicationUser>(65.new UserStore<ApplicationUser>(new ApplicationDbContext()));66.var user = um.FindById(userId);67.var currentRoles = new List<IdentityUserRole>();68.currentRoles.AddRange(user.Roles);69.foreach(var role in currentRoles)70.{71.um.RemoveFromRole(userId, role.Role.Name);72.}73.}74.}75.}
2. 扩展Account Management ViewModels (AccountViewModels.cs)
在RegisterViewModel加入新字段 及 GetUser method

针对要新增的"账号管理"功能新增三个ViewModel,分别是: EditUserViewModel、SelectUserRolesViewModel、SelectRoleEditorViewModel
AccountViewModels.cs 完整程序
001.using Microsoft.AspNet.Identity.EntityFramework;002.using System.Collections.Generic;003.using System.ComponentModel.DataAnnotations;004. 005.namespace RoleBaseProject.Models006.{007.public class ExternalLoginConfirmationViewModel008.{009.[Required]010.[Display(Name = "使用者名称")]011.public string UserName { get; set; }012.}013. 014.public class ManageUserViewModel015.{016.[Required]017.[DataType(DataType.Password)]018.[Display(Name = "目前密码")]019.public string OldPassword { get; set; }020. 021.[Required]022.[StringLength(100, ErrorMessage = "{0} 的长度至少必须为 {2} 个字符。", MinimumLength = 6)]023.[DataType(DataType.Password)]024.[Display(Name = "新密码")]025.public string NewPassword { get; set; }026. 027.[DataType(DataType.Password)]028.[Display(Name = "确认新密码")]029.[Compare("NewPassword", ErrorMessage = "新密码与确认密码不相符。")]030.public string ConfirmPassword { get; set; }031.}032. 033.public class LoginViewModel034.{035.[Required]036.[Display(Name = "使用者名称")]037.public string UserName { get; set; }038. 039.[Required]040.[DataType(DataType.Password)]041.[Display(Name = "密码")]042.public string Password { get; set; }043. 044.[Display(Name = "记住我?")]045.public bool RememberMe { get; set; }046.}047. 048.public class RegisterViewModel049.{050.[Required]051.[Display(Name = "使用者名称")]052.public string UserName { get; set; }053. 054.[Required]055.[StringLength(100, ErrorMessage = "{0} 的长度至少必须为 {2} 个字符。", MinimumLength = 6)]056.[DataType(DataType.Password)]057.[Display(Name = "密码")]058.public string Password { get; set; }059. 060.[DataType(DataType.Password)]061.[Display(Name = "确认密码")]062.[Compare("Password", ErrorMessage = "密码和确认密码不相符。")]063.public string ConfirmPassword { get; set; }064. 065.[Required]066.[Display(Name = "First Name")]067.public string FirstName { get; set; }068. 069.[Required]070.[Display(Name = "Last Name")]071.public string LastName { get; set; }072. 073.[Required]074.[Display(Name = "电子邮件信箱")]075.public string Email { get; set; }076. 077.public ApplicationUser GetUser()078.{079.var user = new ApplicationUser()080.{081.UserName = this.UserName,082.FirstName = this.FirstName,083.LastName = this.LastName,084.Email = this.Email,085.};086.return user;087.}088.}089. 090.public class EditUserViewModel091.{092.public EditUserViewModel() { }093. 094.// Allow Initialization with an instance of ApplicationUser:095.public EditUserViewModel(ApplicationUser user)096.{097.this.UserName = user.UserName;098.this.FirstName = user.FirstName;099.this.LastName = user.LastName;100.this.Email = user.Email;101.}102. 103.[Required]104.[Display(Name = "使用者账号")]105.public string UserName { get; set; }106. 107.[Required]108.[Display(Name = "名")]109.public string FirstName { get; set; }110. 111.[Required]112.[Display(Name = "姓")]113.public string LastName { get; set; }114. 115.[Required]116.[Display(Name = "电子邮件信箱")]117.public string Email { get; set; }118.}119. 120.public class SelectUserRolesViewModel121.{122.public SelectUserRolesViewModel()123.{124.this.Roles = new List<SelectRoleEditorViewModel>();125.}126. 127.// Enable initialization with an instance of ApplicationUser:128.public SelectUserRolesViewModel(ApplicationUser user)129.: this()130.{131.this.UserName = user.UserName;132.this.FirstName = user.FirstName;133.this.LastName = user.LastName;134. 135.var Db = new ApplicationDbContext();136. 137.// Add all available roles to the list of EditorViewModels:138.var allRoles = Db.Roles;139.foreach (var role in allRoles)140.{141.// An EditorViewModel will be used by Editor Template:142.var rvm = new SelectRoleEditorViewModel(role);143.this.Roles.Add(rvm);144.}145. 146.// Set the Selected property to true for those roles for 147.// which the current user is a member:148.foreach (var userRole in user.Roles)149.{150.var checkUserRole =151.this.Roles.Find(r => r.RoleName == userRole.Role.Name);152.checkUserRole.Selected = true;153.}154.}155. 156.public string UserName { get; set; }157.public string FirstName { get; set; }158.public string LastName { get; set; }159.public List<SelectRoleEditorViewModel> Roles { get; set; }160.}161. 162.// Used to display a single role with a checkbox, within a list structure:163.public class SelectRoleEditorViewModel164.{165.public SelectRoleEditorViewModel() { }166.public SelectRoleEditorViewModel(IdentityRole role)167.{168.this.RoleName = role.Name;169.}170. 171.public bool Selected { get; set; }172. 173.[Required]174.public string RoleName { get; set; }175.}176. 177.}
修改相关 Controllers
修改AccountController 中 Register Method 加入 Authorize attribute

必须具有Admin 角色者才能执行。
加入 Index Method (ActionResult)
01.[Authorize(Roles = "Admin")]02.public ActionResult Index()03.{04.var Db = new ApplicationDbContext();05.var users = Db.Users;06.var model = new List<EditUserViewModel>();07.foreach(var user in users)08.{09.var u = new EditUserViewModel(user);10.model.Add(u);11.}12.return View(model);13.}加入 Edit Method (ActionResult)
01.//02.// GEG: /Account/Edit03.[Authorize(Roles = "Admin")]04.public ActionResult Edit(string id , ManageMessageId? Message = null)05.{06.var Db = new ApplicationDbContext();07.var user = Db.Users.First(u => u.UserName == id);08.var model = new EditUserViewModel(user);09.ViewBag.MessageId = Message;10.return View(model);11.}12.//13.// POST: /Account/Edit14.[HttpPost]15.[Authorize(Roles = "Admin")]16.[ValidateAntiForgeryToken]17.public async Task<ActionResult> Edit(EditUserViewModel model)18.{19.if (ModelState.IsValid)20.{21.var Db = new ApplicationDbContext();22.var user = Db.Users.First(u => u.UserName == model.UserName);23.user.FirstName = model.FirstName;24.user.LastName = model.LastName;25.user.Email = model.Email;26.Db.Entry(user).State = System.Data.Entity.EntityState.Modified;27.await Db.SaveChangesAsync();28.return RedirectToAction("Index");29.}30.return View(model);31.}
加入 Delete Method (ActionResult)
01.//02.// GEG: /Account/Delete03.[Authorize(Roles="Admin")]04.public ActionResult Delete(string id = null)05.{06.var Db = new ApplicationDbContext();07.var user = Db.Users.First(u => u.UserName == id);08.var model = new EditUserViewModel(user);09.return View(model);10.}11.//12.// POST: /Account/Delete13.[HttpPost, ActionName("Delete")]14.[Authorize(Roles = "Admin")]15.[ValidateAntiForgeryToken]16.public ActionResult DeleteConfirmed(string id)17.{18.var Db = new ApplicationDbContext();19.var user = Db.Users.First(u => u.UserName == id);20.Db.Users.Remove(user);21.Db.SaveChanges();22.return RedirectToAction("Index");23.}加入 UserRoles Method (ActionResult)
01.//02.// GEG: /Account/UserRoles03.[Authorize(Roles = "Admin")]04.public ActionResult UserRoles(string id)05.{06.var Db = new ApplicationDbContext();07.var user = Db.Users.First(u => u.UserName == id);08.var model = new SelectUserRolesViewModel(user);09.return View(model);10.}11. 12.//13.// POST: /Account/UserRoles14.[HttpPost]15.[Authorize(Roles = "Admin")]16.[ValidateAntiForgeryToken]17.public ActionResult UserRoles(SelectUserRolesViewModel model)18.{19.if (ModelState.IsValid)20.{21.var idManager = new IdentityManager();22.var Db = new ApplicationDbContext();23.var user = Db.Users.First(u => u.UserName == model.UserName);24.idManager.ClearUserRoles(user.Id);25.foreach (var role in model.Roles)26.{27.if (role.Selected)28.{29.idManager.AddUserToRole(user.Id, role.RoleName);30.}31.}32.return RedirectToAction("index");33.}34.return View();35.}AccountController.cs 完整程序
001.using System;002.using System.Collections.Generic;003.using System.Linq;004.using System.Security.Claims;005.using System.Threading.Tasks;006.using System.Web;007.using System.Web.Mvc;008.using Microsoft.AspNet.Identity;009.using Microsoft.AspNet.Identity.EntityFramework;010.using Microsoft.Owin.Security;011.using RoleBaseProject.Models;012. 013.namespace RoleBaseProject.Controllers014.{015.[Authorize]016.public class AccountController : Controller017.{018.public AccountController()019.: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))020.{021.}022. 023.public AccountController(UserManager<ApplicationUser> userManager)024.{025.UserManager = userManager;026.}027. 028.public UserManager<ApplicationUser> UserManager { get; private set; }029. 030.//031.// GET: /Account/Login032.[AllowAnonymous]033.public ActionResult Login(string returnUrl)034.{035.ViewBag.ReturnUrl = returnUrl;036.return View();037.}038. 039.//040.// POST: /Account/Login041.[HttpPost]042.[AllowAnonymous]043.[ValidateAntiForgeryToken]044.public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)045.{046.if (ModelState.IsValid)047.{048.var user = await UserManager.FindAsync(model.UserName, model.Password);049.if (user != null)050.{051.await SignInAsync(user, model.RememberMe);052.return RedirectToLocal(returnUrl);053.}054.else055.{056.ModelState.AddModelError("", "Invalid username or password.");057.}058.}059. 060.// 如果执行到这里,发生某项失败,则重新显示窗体061.return View(model);062.}063. 064.//065.// GET: /Account/Register066.[Authorize(Roles="Admin")]067.public ActionResult Register()068.{069.return View();070.}071. 072.//073.// POST: /Account/Register074.[HttpPost]075.[Authorize(Roles = "Admin")]076.[ValidateAntiForgeryToken]077.public async Task<ActionResult> Register(RegisterViewModel model)078.{079.if (ModelState.IsValid)080.{081.var user = new ApplicationUser() { 082.UserName = model.UserName,083.FirstName = model.FirstName,084.LastName = model.LastName,085.Email = model.Email,086.};087.var result = await UserManager.CreateAsync(user, model.Password);088.if (result.Succeeded)089.{090.await SignInAsync(user, isPersistent: false);091.return RedirectToAction("Index", "Home");092.}093.else094.{095.AddErrors(result);096.}097.}098. 099.// 如果执行到这里,发生某项失败,则重新显示窗体100.return View(model);101.}102. 103.//104.// GEG: /Account/Index105.[Authorize(Roles = "Admin")]106.public ActionResult Index()107.{108.var Db = new ApplicationDbContext();109.var users = Db.Users;110.var model = new List<EditUserViewModel>();111.foreach(var user in users)112.{113.var u = new EditUserViewModel(user);114.model.Add(u);115.}116.return View(model);117.}118. 119.//120.// GEG: /Account/Edit121.[Authorize(Roles = "Admin")]122.public ActionResult Edit(string id , ManageMessageId? Message = null)123.{124.var Db = new ApplicationDbContext();125.var user = Db.Users.First(u => u.UserName == id);126.var model = new EditUserViewModel(user);127.ViewBag.MessageId = Message;128.return View(model);129.}130.//131.// POST: /Account/Edit132.[HttpPost]133.[Authorize(Roles = "Admin")]134.[ValidateAntiForgeryToken]135.public async Task<ActionResult> Edit(EditUserViewModel model)136.{137.if (ModelState.IsValid)138.{139.var Db = new ApplicationDbContext();140.var user = Db.Users.First(u => u.UserName == model.UserName);141.user.FirstName = model.FirstName;142.user.LastName = model.LastName;143.user.Email = model.Email;144.Db.Entry(user).State = System.Data.Entity.EntityState.Modified;145.await Db.SaveChangesAsync();146.return RedirectToAction("Index");147.}148.return View(model);149.}150. 151.//152.// GEG: /Account/Delete153.[Authorize(Roles="Admin")]154.public ActionResult Delete(string id = null)155.{156.var Db = new ApplicationDbContext();157.var user = Db.Users.First(u => u.UserName == id);158.var model = new EditUserViewModel(user);159.return View(model);160.}161.//162.// POST: /Account/Delete163.[HttpPost, ActionName("Delete")]164.[Authorize(Roles = "Admin")]165.[ValidateAntiForgeryToken]166.public ActionResult DeleteConfirmed(string id)167.{168.var Db = new ApplicationDbContext();169.var user = Db.Users.First(u => u.UserName == id);170.Db.Users.Remove(user);171.Db.SaveChanges();172.return RedirectToAction("Index");173.}174.//175.// GEG: /Account/UserRoles176.[Authorize(Roles = "Admin")]177.public ActionResult UserRoles(string id)178.{179.var Db = new ApplicationDbContext();180.var user = Db.Users.First(u => u.UserName == id);181.var model = new SelectUserRolesViewModel(user);182.return View(model);183.}184. 185.//186.// POST: /Account/UserRoles187.[HttpPost]188.[Authorize(Roles = "Admin")]189.[ValidateAntiForgeryToken]190.public ActionResult UserRoles(SelectUserRolesViewModel model)191.{192.if (ModelState.IsValid)193.{194.var idManager = new IdentityManager();195.var Db = new ApplicationDbContext();196.var user = Db.Users.First(u => u.UserName == model.UserName);197.idManager.ClearUserRoles(user.Id);198.foreach (var role in model.Roles)199.{200.if (role.Selected)201.{202.idManager.AddUserToRole(user.Id, role.RoleName);203.}204.}205.return RedirectToAction("index");206.}207.return View();208.}209. 210.//211.// POST: /Account/Disassociate212.[HttpPost]213.[ValidateAntiForgeryToken]214.public async Task<ActionResult> Disassociate(string loginProvider, string providerKey)215.{216.ManageMessageId? message = null;217.IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));218.if (result.Succeeded)219.{220.message = ManageMessageId.RemoveLoginSuccess;221.}222.else223.{224.message = ManageMessageId.Error;225.}226.return RedirectToAction("Manage", new { Message = message });227.}228. 229.//230.// GET: /Account/Manage231.public ActionResult Manage(ManageMessageId? message)232.{233.ViewBag.StatusMessage =234.message == ManageMessageId.ChangePasswordSuccess ? "您的密码已变更。"235.: message == ManageMessageId.SetPasswordSuccess ? "已设定您的密码。"236.: message == ManageMessageId.RemoveLoginSuccess ? "已移除外部登入。"237.: message == ManageMessageId.Error ? "发生错误。"238.: "";239.ViewBag.HasLocalPassword = HasPassword();240.ViewBag.ReturnUrl = Url.Action("Manage");241.return View();242.}243. 244.//245.// POST: /Account/Manage246.[HttpPost]247.[ValidateAntiForgeryToken]248.public async Task<ActionResult> Manage(ManageUserViewModel model)249.{250.bool hasPassword = HasPassword();251.ViewBag.HasLocalPassword = hasPassword;252.ViewBag.ReturnUrl = Url.Action("Manage");253.if (hasPassword)254.{255.if (ModelState.IsValid)256.{257.IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);258.if (result.Succeeded)259.{260.return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });261.}262.else263.{264.AddErrors(result);265.}266.}267.}268.else269.{270.// User does not have a password so remove any validation errors caused by a missing OldPassword field271.ModelState state = ModelState["OldPassword"];272.if (state != null)273.{274.state.Errors.Clear();275.}276. 277.if (ModelState.IsValid)278.{279.IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);280.if (result.Succeeded)281.{282.return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });283.}284.else285.{286.AddErrors(result);287.}288.}289.}290. 291.// 如果执行到这里,发生某项失败,则重新显示窗体292.return View(model);293.}294. 295.//296.// POST: /Account/ExternalLogin297.[HttpPost]298.[AllowAnonymous]299.[ValidateAntiForgeryToken]300.public ActionResult ExternalLogin(string provider, string returnUrl)301.{302.// 要求重新导向至外部登入提供者303.return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));304.}305. 306.//307.// GET: /Account/ExternalLoginCallback308.[AllowAnonymous]309.public async Task<ActionResult> ExternalLoginCallback(string returnUrl)310.{311.var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();312.if (loginInfo == null)313.{314.return RedirectToAction("Login");315.}316. 317.// Sign in the user with this external login provider if the user already has a login318.var user = await UserManager.FindAsync(loginInfo.Login);319.if (user != null)320.{321.await SignInAsync(user, isPersistent: false);322.return RedirectToLocal(returnUrl);323.}324.else325.{326.// If the user does not have an account, then prompt the user to create an account327.ViewBag.ReturnUrl = returnUrl;328.ViewBag.LoginProvider = loginInfo.Login.LoginProvider;329.return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { UserName = loginInfo.DefaultUserName });330.}331.}332. 333.//334.// POST: /Account/LinkLogin335.[HttpPost]336.[ValidateAntiForgeryToken]337.public ActionResult LinkLogin(string provider)338.{339.// Request a redirect to the external login provider to link a login for the current user340.return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId());341.}342. 343.//344.// GET: /Account/LinkLoginCallback345.public async Task<ActionResult> LinkLoginCallback()346.{347.var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());348.if (loginInfo == null)349.{350.return RedirectToAction("Manage", new { Message = ManageMessageId.Error });351.}352.var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);353.if (result.Succeeded)354.{355.return RedirectToAction("Manage");356.}357.return RedirectToAction("Manage", new { Message = ManageMessageId.Error });358.}359. 360.//361.// POST: /Account/ExternalLoginConfirmation362.[HttpPost]363.[AllowAnonymous]364.[ValidateAntiForgeryToken]365.public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)366.{367.if (User.Identity.IsAuthenticated)368.{369.return RedirectToAction("Manage");370.}371. 372.if (ModelState.IsValid)373.{374.// 从外部登入提供者处取得使用者信息375.var info = await AuthenticationManager.GetExternalLoginInfoAsync();376.if (info == null)377.{378.return View("ExternalLoginFailure");379.}380.var user = new ApplicationUser() { UserName = model.UserName };381.var result = await UserManager.CreateAsync(user);382.if (result.Succeeded)383.{384.result = await UserManager.AddLoginAsync(user.Id, info.Login);385.if (result.Succeeded)386.{387.await SignInAsync(user, isPersistent: false);388.return RedirectToLocal(returnUrl);389.}390.}391.AddErrors(result);392.}393. 394.ViewBag.ReturnUrl = returnUrl;395.return View(model);396.}397. 398.//399.// POST: /Account/LogOff400.[HttpPost]401.[ValidateAntiForgeryToken]402.public ActionResult LogOff()403.{404.AuthenticationManager.SignOut();405.return RedirectToAction("Index", "Home");406.}407. 408.//409.// GET: /Account/ExternalLoginFailure410.[AllowAnonymous]411.public ActionResult ExternalLoginFailure()412.{413.return View();414.}415. 416.[ChildActionOnly]417.public ActionResult RemoveAccountList()418.{419.var linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId());420.ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1;421.return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);422.}423. 424.protected override void Dispose(bool disposing)425.{426.if (disposing && UserManager != null)427.{428.UserManager.Dispose();429.UserManager = null;430.}431.base.Dispose(disposing);432.}433. 434.#region Helper435.// Used for XSRF protection when adding external logins436.private const string XsrfKey = "XsrfId";437. 438.private IAuthenticationManager AuthenticationManager439.{440.get441.{442.return HttpContext.GetOwinContext().Authentication;443.}444.}445. 446.private async Task SignInAsync(ApplicationUser user, bool isPersistent)447.{448.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);449.var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);450.AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);451.}452. 453.private void AddErrors(IdentityResult result)454.{455.foreach (var error in result.Errors)456.{457.ModelState.AddModelError("", error);458.}459.}460. 461.private bool HasPassword()462.{463.var user = UserManager.FindById(User.Identity.GetUserId());464.if (user != null)465.{466.return user.PasswordHash != null;467.}468.return false;469.}470. 471.public enum ManageMessageId472.{473.ChangePasswordSuccess,474.SetPasswordSuccess,475.RemoveLoginSuccess,476.Error477.}478. 479.private ActionResult RedirectToLocal(string returnUrl)480.{481.if (Url.IsLocalUrl(returnUrl))482.{483.return Redirect(returnUrl);484.}485.else486.{487.return RedirectToAction("Index", "Home");488.}489.}490. 491.private class ChallengeResult : HttpUnauthorizedResult492.{493.public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null)494.{495.}496. 497.public ChallengeResult(string provider, string redirectUri, string userId)498.{499.LoginProvider = provider;500.RedirectUri = redirectUri;501.UserId = userId;502.}503. 504.public string LoginProvider { get; set; }505.public string RedirectUri { get; set; }506.public string UserId { get; set; }507. 508.public override void ExecuteResult(ControllerContext context)509.{510.var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };511.if (UserId != null)512.{513.properties.Dictionary[XsrfKey] = UserId;514.}515.context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);516.}517.}518.#endregion519.}520.}
修改相关 Views
修改Register.cshtml View
01.@model RoleBaseProject.Models.RegisterViewModel02.@{03.ViewBag.Title = "注册";04.}05. 06.<h2>@ViewBag.Title.</h2>07. 08.@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))09.{10.@Html.AntiForgeryToken()11.<h4>建立新的账户。</h4>12.<hr />13.@Html.ValidationSummary()14.<div class="form-group">15.@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })16.<div class="col-md-10">17.@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })18.</div>19.</div>20.<div class="form-group">21.@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })22.<div class="col-md-10">23.@Html.PasswordFor(m => m.Password, new { @class = "form-control" })24.</div>25.</div>26.<div class="form-group">27.@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })28.<div class="col-md-10">29.@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })30.</div>31.</div>32.<div class="form-group">33.@Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" })34.<div class="col-md-10">35.@Html.TextBoxFor(m => m.FirstName, new { @class = "form-control" })36.</div>37.</div>38.<div class="form-group">39.@Html.LabelFor(m => m.LastName, new { @class = "col-md-2 control-label" })40.<div class="col-md-10">41.@Html.TextBoxFor(m => m.LastName, new { @class = "form-control" })42.</div>43.</div>44.<div class="form-group">45.@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })46.<div class="col-md-10">47.@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })48.</div>49.</div>50.<div class="form-group">51.<div class="col-md-offset-2 col-md-10">52.<input type="submit" class="btn btn-default" value="注册" />53.</div>54.</div>55.}56. 57.@section Scripts {58.@Scripts.Render("~/bundles/jqueryval")59.}
新增Edit、Delete、Index 等方法的Views
新增Edit Views


用以下内容取代原程序



01.@model RoleBaseProject.Models.EditUserViewModel02. 03.@{04.ViewBag.Title = "数据者数据编辑";05.}06. 07.<h2>数据者数据编辑</h2>08. 09.@using (Html.BeginForm())10.{11.@Html.AntiForgeryToken()12.<div class="form-horizontal">13.<h4>修改原有账号数据</h4>14.<hr />15.@Html.ValidationSummary(true)16.<div class="form-group">17.@Html.LabelFor(model => model.UserName, new { @class = "control-label col-md-2" })18.<div class="col-md-10">19.@Html.EditorFor(model => model.UserName)20.@Html.ValidationMessageFor(model => model.UserName)21.</div>22.</div>23. 24.<div class="form-group">25.@Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })26.<div class="col-md-10">27.@Html.EditorFor(model => model.FirstName)28.@Html.ValidationMessageFor(model => model.FirstName)29.</div>30.</div>31. 32.<div class="form-group">33.@Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" })34.<div class="col-md-10">35.@Html.EditorFor(model => model.LastName)36.@Html.ValidationMessageFor(model => model.LastName)37.</div>38.</div>39. 40.<div class="form-group">41.@Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })42.<div class="col-md-10">43.@Html.EditorFor(model => model.Email)44.@Html.ValidationMessageFor(model => model.Email)45.</div>46.</div>47. 48.<div class="form-group">49.<div class="col-md-offset-2 col-md-10">50.<input type="submit" value="存档" class="btn btn-default" />51.</div>52.</div>53.</div>54.}55. 56.<div>57.@Html.ActionLink("回到使用者清单画面", "Index")58.</div>59. 60.@section Scripts {61.@Scripts.Render("~/bundles/jqueryval")62.}新增Delete的Views


用以下内容取代原程序
01.@model RoleBaseProject.Models.EditUserViewModel02. 03.<h3>使用者账号删除</h3>04.<div>05.<h4>确定要删除这个使用者账号?</h4>06.<hr />07.<dl class="dl-horizontal">08.<dt>09.@Html.DisplayNameFor(model => model.UserName)10.</dt>11. 12.<dd>13.@Html.DisplayFor(model => model.UserName)14.</dd>15. 16.<dt>17.@Html.DisplayNameFor(model => model.FirstName)18.</dt>19. 20.<dd>21.@Html.DisplayFor(model => model.FirstName)22.</dd>23. 24.<dt>25.@Html.DisplayNameFor(model => model.LastName)26.</dt>27. 28.<dd>29.@Html.DisplayFor(model => model.LastName)30.</dd>31. 32.<dt>33.@Html.DisplayNameFor(model => model.Email)34.</dt>35. 36.<dd>37.@Html.DisplayFor(model => model.Email)38.</dd>39. 40.</dl>41. 42.@using (Html.BeginForm()) {43.@Html.AntiForgeryToken()44. 45.<div class="form-actions no-color">46.<input type="submit" value="删除" class="btn btn-default" /> |47.@Html.ActionLink("回到使用者清单画面", "Index")48.</div>49.}50.</div>新增Index Views


用以下内容取代原程序
01.@model IEnumerable<RoleBaseProject.Models.EditUserViewModel>02. 03.@{04.ViewBag.Title = "账号管理";05.}06. 07.<h2>账号管理</h2>08. 09.<p>10.@Html.ActionLink("新增账号", "Register")11.</p>12.<table class="table">13.<tr>14.<th>15.@Html.DisplayNameFor(model => model.UserName)16.</th>17.<th>18.@Html.DisplayNameFor(model => model.FirstName)19.</th>20.<th>21.@Html.DisplayNameFor(model => model.LastName)22.</th>23.<th>24.@Html.DisplayNameFor(model => model.Email)25.</th>26.<th></th>27.</tr>28. 29.@foreach (var item in Model) {30.<tr>31.<td>32.@Html.DisplayFor(modelItem => item.UserName)33.</td>34.<td>35.@Html.DisplayFor(modelItem => item.FirstName)36.</td>37.<td>38.@Html.DisplayFor(modelItem => item.LastName)39.</td>40.<td>41.@Html.DisplayFor(modelItem => item.Email)42.</td>43.<td>44.@Html.ActionLink("编辑", "Edit", new { id=item.UserName }) |45.@Html.ActionLink("角色", "UserRoles", new { id=item.UserName }) |46.@Html.ActionLink("删除", "Delete", new { id=item.UserName })47.</td>48.</tr>49.}50. 51.</table>新增好的三個View

新增UserRoles.cshtml View 并 新增程序代码


用以下内容取代原程序
01.@model RoleBaseProject.Models.SelectUserRolesViewModel02.@{03.ViewBag.Title = "使用者角色";04.}05. 06.<h2>使用者角色 @Html.DisplayFor(model => model.UserName)</h2>07.<hr />08. 09.@using (Html.BeginForm("UserRoles", "Account", FormMethod.Post, new { encType = "multipart/form-data", name = "myform" }))10.{11.@Html.AntiForgeryToken()12. 13.<div class="form-horizontal">14.@Html.ValidationSummary(true)15.<div class="form-group">16.<div class="col-md-10">17.@Html.HiddenFor(model => model.UserName)18.</div>19.</div>20. 21.<h4>选择要加入的角色</h4>22.<br />23.<hr />24. 25.<table>26.<tr>27.<th>28.勾选29.</th>30.<th>31.角色32.</th>33.</tr>34.@Html.EditorFor(model => model.Roles)35.</table>36.<br />37.<hr />38. 39.<div class="form-group">40.<div class="col-md-offset-2 col-md-10">41.<input type="submit" value="存档" class="btn btn-default" />42.</div>43.</div>44.</div>45.}
新增SelectRoleEditorViewModel.cshtml 在 Shared/EditorTemplates目录下

01.@model RoleBaseProject.Models.SelectRoleEditorViewModel02.@Html.HiddenFor(model => model.RoleName)03.<tr>04.<td style="text-align:center">05.@Html.CheckBoxFor(model => model.Selected)06.</td>07.<td>08.@Html.DisplayFor(model => model.RoleName)09.</td>10.</tr>
在主页面上新增”账号管理" 功能按钮

移除主页面上的注册功能

启动 Migration功能

在Seed()方法中加入建立测试数据的程序代码

完整程序:
01.namespace RoleBaseProject.Migrations02.{03.using RoleBaseProject.Models;04.using System;05.using System.Data.Entity;06.using System.Data.Entity.Migrations;07.using System.Linq;08. 09.internal sealed class Configuration : DbMigrationsConfiguration<RoleBaseProject.Models.ApplicationDbContext>10.{11.public Configuration()12.{13.AutomaticMigrationsEnabled = false;14.}15. 16.protected override void Seed(RoleBaseProject.Models.ApplicationDbContext context)17.{18.// This method will be called after migrating to the latest version.19. 20.// You can use the DbSet<T>.AddOrUpdate() helper extension method 21.// to avoid creating duplicate seed data. E.g.22.//23.// context.People.AddOrUpdate(24.// p => p.FullName,25.// new Person { FullName = "Andrew Peters" },26.// new Person { FullName = "Brice Lambson" },27.// new Person { FullName = "Rowan Miller" }28.// );29.//30.this.AddUserAndRoles();31.}32. 33.bool AddUserAndRoles()34.{35.bool success = false;36. 37.var idManager = new IdentityManager();38.success = idManager.CreateRole("Admin");39.if (!success == true) return success;40. 41.success = idManager.CreateRole("CanEdit");42.if (!success == true) return success;43. 44.success = idManager.CreateRole("User");45.if (!success) return success;46. 47.var newUser = new ApplicationUser()48.{49.UserName = "jatten",50.FirstName = "John",51.LastName = "Atten",52.Email = "jatten@typecastexception.com"53.};54. 55.success = idManager.CreateUser(newUser, "Password1");56.if (!success) return success;57. 58.success = idManager.AddUserToRole(newUser.Id, "Admin");59.if (!success) return success;60. 61.success = idManager.AddUserToRole(newUser.Id, "CanEdit");62.if (!success) return success;63. 64.success = idManager.AddUserToRole(newUser.Id, "User");65.if (!success) return success;66. 67.return success;68.}69.}70.}
更新数据库


执行结果

以具有Admin角色的使用者登入后执行账户管理功能:


浙公网安备 33010602011771号