本文將介紹如何在 ASP.NET MVC 5 應用程序 中使用 ASP.NET Identity 創建和使用角色、擴展用戶屬性及相關知識。
主要內容包括:
- 創建管理員角色和超級用戶
- 用戶注冊時選擇角色
- 使用用戶名進行登錄
- 角色管理
- 擴展用戶屬性
- 針對Controller或Action的授權
准備工作
在 Visual Studio 2017 中 創建 ASP.NET Web 應用程序(.NET Framework),我們將應用程序命名為“UserRoleDemo”,在創建應用程序時更改身份驗證方式為“個人用戶賬戶”,其他均為默認設置。
創建管理員角色和超級用戶
修改 Startup.cs 文件,在 Configuration 方法中調用自定義的CreateRolesandUsers() 方法來創建默認角色和管理員用戶。
在CreateRolesandUsers() 方法中將檢查管理員角色(命名為“Admin”)是否已被創建,如果名稱為“Admin”的角色沒有創建,則創建一個名稱為“Admin”的新角色和一個超級用戶(命名為“sa”),並將該用戶的角色設置為“Admin”。
Startup.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Owin;
using UserRoleDemo.Models;
[assembly: OwinStartup(typeof(UserRoleDemo.Startup))]
namespace UserRoleDemo
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
CreateRolesAndUsers();
}
// 創建管理員角色和超級用戶
private void CreateRolesAndUsers()
{
ApplicationDbContext context = new ApplicationDbContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
// 判斷管理員角色是否存在
if (!roleManager.RoleExists("Admin"))
{
// 創建角色 - Admin
var role = new IdentityRole
{
Name = "Admin"
};
roleManager.Create(role);
// 創建超級用戶 - sa
var user = new ApplicationUser
{
UserName = "sa",
Email = "sa@mercator.asia"
};
string userPWD = "Mercator.asia";
var chkUser = userManager.Create(user, userPWD);
// 指定超級用戶的角色
if (chkUser.Succeeded)
{
var result1 = userManager.AddToRole(user.Id, "Admin");
}
}
// 創建角色 - Manager
if (!roleManager.RoleExists("Manager"))
{
var role = new IdentityRole
{
Name = "Manager"
};
roleManager.Create(role);
}
// 創建角色 - Employee
if (!roleManager.RoleExists("Employee"))
{
var role = new IdentityRole
{
Name = "Employee"
};
roleManager.Create(role);
}
}
}
}
用戶注冊時選擇角色
通過 ASP.NET Web 應用程序(.NET Framework) 模板創建的應用程序在用戶注冊時默認只能輸入郵箱和密碼,下面我們將實現在用戶注冊時選擇角色。
模板程序默認是以郵箱作為用戶名,在實現選擇角色功能時我們也會增加輸入獨立的用戶名的功能。
視圖部分
修改Register.cshtml文件,在其中添加用戶名行和角色行。
Views/Account/Register.cshtml
@model UserRoleDemo.Models.RegisterViewModel
@{
ViewBag.Title = "注冊";
}
<h2>@ViewBag.Title。</h2>
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>創建新帳戶。</h4>
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
<!--用戶名-->
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<!--角色-->
<div class="form-group">
@Html.Label("user Role", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ")
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="注冊" />
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
模型部分
修改 Models/AccountViewModel.cs 文件,在 RegisterViewModel 中添加 UserRoles 和 UserName 等兩個屬性。
Models/AccountViewModel.cs(局部)
public class RegisterViewModel
{
[Required]
[Display(Name = "所屬角色")]
public string UserRoles { get; set; }
[Required]
[Display(Name = "用戶名")]
public string UserName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "電子郵件")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "{0} 必須至少包含 {2} 個字符。", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "密碼")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "確認密碼")]
[Compare("Password", ErrorMessage = "密碼和確認密碼不匹配。")]
public string ConfirmPassword { get; set; }
}
控制器部分
修改 Controllers/AccountController.cs 文件,把除“Admin”外的所有角色名稱顯示在下拉框中,並在注冊按鈕的點擊事件中實現寫入用戶名和角色屬性的功能。
首先創建一個 ApplicationDBContext 對象。(ApplicationDBContext 是一個用於實現ASP.NET Identity 數據庫讀寫功能的類,例如創建用戶、角色等)
為AccountController類添加一個私有成員:
Controllers/AccountController.cs(局部)
private readonly ApplicationDbContext context;
修改AccountController的構造函數以初始化context對象:
Controllers/AccountController.cs(局部)
public AccountController()
{
context = new ApplicationDbContext();
}
通過 ApplicationDBContext 對象我們可以獲取數據庫中的所有角色。用戶注冊時我們不允許選擇“Admin”角色,因此,在Register ActionResult 中查詢所有非“Admin”角色用於在視圖的角色下拉框中顯示。
Controllers/AccountController.cs(局部)
//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))
.ToList(), "Name", "Name");
return View();
}
在AspNetUsers數據表中默認是將Email作為用戶名來存儲的,這里我們改為直接存儲用戶輸入的用戶名。
用戶創建成功后,通過調用 UserManager.AddToRoleAsync 方法為用戶設置其選擇的角色。
Controllers/AccountController.cs(局部)
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
// 將UserName = model.Email替換為UserName = model.UserName
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// 有關如何啟用帳戶確認和密碼重置的詳細信息,請訪問 https://go.microsoft.com/fwlink/?LinkID=320771
// 發送包含此鏈接的電子郵件
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "確認你的帳戶", "請通過單擊 <a href=\"" + callbackUrl + "\">這裏</a>來確認你的帳戶");
// 設置創建的新用戶添加到其選擇的角色
await UserManager.AddToRoleAsync(user.Id, model.UserRoles);
return RedirectToAction("Index", "Home");
}
// 返回注冊頁面時列出所有非“Admin”角色
ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))
.ToList(), "Name", "Name");
AddErrors(result);
}
// 如果我們進行到這一步時某個地方出錯,則重新顯示表單
return View(model);
}
使用用戶名進行登錄
和用戶注冊時一樣,我們通過輸入用戶名來替代默認輸入Email的方式進行登錄操作。
視圖部分
修改Views/Account/Login.cshtml文件,將模型的Email屬性替換為UserName屬性。
Views/Account/Login.cshtml
@using UserRoleDemo.Models
@model LoginViewModel
@{
ViewBag.Title = "登錄";
}
<h2>@ViewBag.Title。</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>使用本地帳戶登錄。</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<!--替換Email為UserName-->
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="登錄" class="btn btn-default" />
</div>
</div>
<p>
@Html.ActionLink("注冊為新用戶", "Register")
</p>
@* 在為密碼重置功能啟用帳戶確認后啟用此項
<p>
@Html.ActionLink("忘記了密碼?", "ForgotPassword")
</p>*@
}
</section>
</div>
<div class="col-md-4">
<section id="socialLoginForm">
@Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
模型部分
和用戶注冊一樣,在 AccountViewModel 中找到 LoginViewModel 並把 Email 替換為 UserName。
Models/AccountViewModels.cs(局部)
public class LoginViewModel
{
[Required]
[Display(Name = "用戶名")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "密碼")]
public string Password { get; set; }
[Display(Name = "記住我?")]
public bool RememberMe { get; set; }
}
控制器部分
在登錄按鈕的點擊事件中我們同樣需要把Email屬性替換為 UserName來進行數據庫認證。
Controllers/AccountController.cs(局部)
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// 這不會計入到為執行帳戶鎖定而統計的登錄失敗次數中
// 若要在多次輸入錯誤密碼的情況下觸發帳戶鎖定,請更改為 shouldLockout: true
// 替換Email為UserName
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "無效的登錄嘗試。");
return View(model);
}
}
角色管理
角色模型為Microsoft.AspNet.Identity.EntityFramework.IdentityRole,本文中,我們使用ASP.NET Identity中的RoleManager對象進行角色管理。
控制器部分
首先,我們添加一個空的MVC5 控制器,命名為RoleController。
修改Controllers/RoleController.cs文件,增加Index、Create、Edit和Delete等ActionResult。
Controllers/RoleController.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using UserRoleDemo.Models;
namespace UserRoleDemo.Controllers
{
public class RoleController : Controller
{
private ApplicationDbContext context = new ApplicationDbContext();
// GET: Role
public ActionResult Index()
{
return View(context.Roles.ToList());
}
// GET: Role/Create
public ActionResult Create()
{
return View();
}
// POST: Role/Create
// 為了防止“過多發布”攻擊,請啟用要綁定到的特定屬性,有關
// 詳細信息,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name")] IdentityRole identityRole)
{
if (ModelState.IsValid)
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
roleManager.Create(identityRole);
return RedirectToAction("Index");
}
return View(identityRole);
}
// GET: Role/Edit/5
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
IdentityRole identityRole = context.Roles.Find(id);
if (identityRole == null)
{
return HttpNotFound();
}
return View(identityRole);
}
// POST: Role/Edit/5
// 為了防止“過多發布”攻擊,請啟用要綁定到的特定屬性,有關
// 詳細信息,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Name")] IdentityRole identityRole)
{
if (ModelState.IsValid)
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
roleManager.Update(identityRole);
return RedirectToAction("Index");
}
return View(identityRole);
}
// GET: Role/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
IdentityRole identityRole = context.Roles.Find(id);
if (identityRole == null)
{
return HttpNotFound();
}
return View(identityRole);
}
// POST: Role/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
IdentityRole identityRole = context.Roles.Find(id);
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
roleManager.Delete(identityRole);
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
context.Dispose();
}
base.Dispose(disposing);
}
}
}
視圖部分
分別在RoleController的ActionResult Index、Create、Edit、Delete上點擊右鍵,選擇 添加視圖。
操作完成后,Views目錄中應該會多出一個Role文件夾,其中包含Index.cshtml、Create.cshtml、Edit.cshtml和Delete.cshtml等4個視圖文件。
Index
修改Views/Role/Index.cshtml,用於列出所有角色。
Views/Role/Index.cshtml
@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</table>
Create
Views/Role/Create.cshtml
@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>ApplicationUser</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Edit
Views/Role/Edit.cshtml
@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>ApplicationUser</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Delete
Views/Role/Delete.cshtml
@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>ApplicationUser</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
</dl>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" /> |
@Html.ActionLink("Back to List", "Index")
</div>
}
</div>
擴展用戶屬性
啟用 Entity Framework 合並
ASP.NET Identity 使用 Entity Framework Code First 作為基礎框架,擴展用戶屬性就意味着我們需要修改Code First模型,因此,我們需要啟用 Entity Framework 合並。
打開 程序包管理器控制台,在控制台窗口中輸入 Enable-Migrations 並回車。
工具(T) - NuGet 包管理器(N) - 程序包管理器控制台(O)
添加擴展屬性
在本文示例中我們為用戶類新增一個 BirthDate 屬性。
修改 Models\IdentityModels.cs 文件,在ApplicationUser類定義中增加BirthDate屬性。
Models\IdentityModels.cs(局部)
public class ApplicationUser : IdentityUser
{
[Display(Name = "生日")]
public DateTime BirthDate { get; set; }
使用 Add-Migrations 命令修改數據庫
由於我們為用戶類添加了一個新屬性,因此我們需要更新數據庫來反映這個變化。
這也是EF 合並的真正用處所在。
還是在 程序包管理器控制台 中進行操作,
輸入 Add-Migration "Birthdate"
該指令執行后將在項目中添加一個合並文件。
輸入 Update-Database
該指令將運行所有合並文件並更新數據庫以添加一個BirthDate 列
模型部分
修改Models\AccountViewModels.cs 文件,將 BirthDate 添加到 RegisterViewModel
Models\AccountViewModels.cs
public class RegisterViewModel
{
[Required]
[Display(Name = "所屬角色")]
public string UserRoles { get; set; }
[Required]
[Display(Name = "用戶名")]
public string UserName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "電子郵件")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "{0} 必須至少包含 {2} 個字符。", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "密碼")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "確認密碼")]
[Compare("Password", ErrorMessage = "密碼和確認密碼不匹配。")]
public string ConfirmPassword { get; set; }
[Display(Name = "生日")]
public DateTime BirthDate { get; set; }
}
視圖部分
更新 Views\Account\Register.cshtml 文件
Views\Account\Register.cshtml
@model UserRoleDemo.Models.RegisterViewModel
@{
ViewBag.Title = "注冊";
}
<h2>@ViewBag.Title。</h2>
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>創建新帳戶。</h4>
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
<!--用戶名-->
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<!--角色-->
<div class="form-group">
@Html.Label("user Role", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ")
</div>
</div>
<!--生日-->
<div class="form-group">
@Html.LabelFor(m => m.BirthDate, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.BirthDate, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="注冊" />
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
控制器部分
更新Controllers\AccountController.cs 文件中的Register Action
Controllers\AccountController.cs(局部)
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, BirthDate = model.BirthDate };
運行程序,再次注冊用戶時就可以看到BirthDate字段的應用。
針對Controller或Action的授權
ASP.NET Identity使用Authorize特性實現了針對Controller或Action的授權功能,實際上這個特性是MVC功能的一部分,被稱為過濾器(Filter)。
過濾器(Filter)
ASP.NET MVC中把過濾器分為以下幾類:
身份驗證過濾器(IAuthenticationFilter)
這個過濾器是在MVC5中加入的,它是所有過濾器中優先級最高的,使用身份驗證過濾器可以為Action、Controller或者所有的Controller添加身份驗證邏輯。
授權過濾器(IAuthorizationFilter)
授權過濾器用來處理Controller以及Action的訪問限制。
Action方法過濾器(IActionFilter)
Action過濾器可用於在Action方法執行前和執行后添加邏輯。
結果過濾器(IResultFilter)
結果過濾器可以在結果執行前和執行后添加邏輯。
ASP.NET MVC中的Action返回結果為ActionResult類型,該抽象類型定義了一個執行方法ExecuteResult,結果的執行實際上是對返回結果的處理
異常過濾器(IExceptionFilter)
異常過濾器就是Action方法在執行的過程中拋出異常時,用來添加異常處理邏輯的過濾器。
為RoleController設置過濾器
如果我們需要設置RoleController只允許角色為“Admin”的用戶訪問,則需要修改Controller/RoleController.cs文件,為RoleController設置過濾器。
Controller/RoleController.cs(局部)
[Authorize(Order = 0, Roles = "Admin")]
public class RoleController : Controller
為RoleController中的Create Action設置過濾器
只允許角色為“Admin”且用戶名為“admin”的用戶訪問。
Controller/RoleController.cs(局部)
// GET: Role/Create
[Authorize(Order =1,Roles ="Admin",Users ="admin")]
public ActionResult Create()
{
return View();
}
結束語
本文僅就 ASP.NET Identity 的一些最為常用的功能進行了介紹,后續將逐步為大家介紹郵箱認證、短信認證、找回密碼、第三方賬號登錄等功能,敬請期待。