ASP.NET Core 授权属性
在本章中,我们将讨论授权属性。到目前为止,我们的应用程序允许匿名用户做任何事情。他们可以编辑员工详细信息和查看详细信息,但我们没有创建新员工的功能。让我们先添加创建功能,然后使用 Authorize 授权属性限制用户访问。
我们需要首先在 Views → Home 文件夹下创建一个新的 MVC 视图页面,并将其称为 Create.cshtml,然后添加以下代码。
@model MyFirstCoreWebApp.Models.Employee
@{
ViewBag.Title = "Create";
}
<h1>Create</h1>
@using (Html.BeginForm())
{
<div>
<label>员工名称</label>
@Html.EditorFor(m => m.EmployeeName)
@Html.ValidationMessageFor(m => m.EmployeeName)
</div>
<div>
<input type="submit" value="保存" />
</div>
}
现在,我们将在 HomeController
中为 POST 和 GET 添加 action
方法,如下所示。
[HttpGet]
public ViewResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(EmployeeEditViewModel model)
{
if (ModelState.IsValid)
{
var employee = new Employee();
employee.EmployeeName = model.EmployeeName;
employee.EntryDate = System.DateTime.Now;
_context.Employees.Add(employee);
_context.SaveChanges();
return RedirectToAction("Details", new { id = employee.ID });
}
return View();
}
让我们在 Index.chtml 文件中添加一个到创建视图的链接,如下所示。
@model HomePageViewModel
@{
ViewBag.Title = "Home";
}
<h1>Welcome!</h1>
<table>
@foreach (var employee in Model.Employee)
{
<tr>
<td>@employee.EmployeeName</td>
<td>
<a asp-controller="Home" asp-action="Details"
asp-route-id="@employee.ID">Details</a>
<a asp-controller="Home" asp-action="Edit"
asp-route-id="@employee.ID">Edit</a>
</td>
</tr>
}
</table>
<div>
<a asp-action="Create">Create</a>
</div>
然后运行程序,结果如下:
点击 Create 按钮,在添加页面输入新员工名称,"李木"。
保存后,跳转到详情页面。
然后返回首页,数据也更新了。
在这个应用程序中,每个用户都可以创建、编辑员工,每个人都可以看到详细视图。我们希望更改此行为,以便将来匿名用户只能在主页上看到员工列表,但其他任何操作都需要用户标识自己并登录。我们可以使用 授权 属性执行此操作。
您可以将 授权 属性放置在控制器上或控制器内的单个操作上。
[Authorize]
public class HomeController : Controller {
//....
}
- 当我们将
Authorize
属性放置在控制器本身上时,Authorize
属性将应用于内部的所有操作。 - 除非用户通过授权检查,否则 MVC 框架将不允许请求到达受此属性保护的操作。
- 默认情况下,如果不使用其他参数,
Authorize
属性将进行的唯一检查是确保用户已登录,以便我们知道他们的身份。 - 但是您可以使用参数来指定任何您喜欢的自定义授权策略。
- 还有一个
AllowAnonymous
属性。当您希望在控制器上使用Authorize
属性来保护内部的所有操作时,此属性非常有用,但是您希望取消保护此单个操作或一个或两个操作,并允许匿名用户访问该特定操作。
[AllowAnonymous]
public ViewResult Index()
{
HomePageViewModel employees = new HomePageViewModel();
employees.Employee = _context.Employees.ToList<Employee>();
return View(employees);
}
让我们在应用程序中尝试这些属性。在运行的应用程序中,匿名用户可以编辑员工。
我们希望强制用户登录并标识身份,然后才能编辑员工。现在让我们进入 HomeController。我们将在此处限制对一个或两个操作的访问。我们总是可以将 Authorize
属性放在我们想要保护的特定操作上。我们还可以将 Authorize
属性放置在控制器本身上。在这之前,需要先添加 Microsoft.AspNet.Authorization 命名空间。
现在,我们将使用 Authorize
属性,强制用户标识自己以进入该控制器,但主页除外,如下所示。
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MyFirstCoreWebApp.Models;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace MyFirstCoreWebApp.Controllers
{
[Authorize]
public class HomeController : Controller
{
private readonly MyFirstCoreWebAppDbContext _context;
public HomeController(MyFirstCoreWebAppDbContext context)
{
//通过构造函数注入数据库上下文
_context = context;
}
[AllowAnonymous]
public ViewResult Index()
{
HomePageViewModel employees = new HomePageViewModel();
employees.Employee = _context.Employees.ToList<Employee>();
return View(employees);
}
public IActionResult Details(int id)
{
var model = _context.Employees.Find(id);
if (model == null)
{
return RedirectToAction("Index");
}
return View(model);
}
[HttpGet]
public IActionResult Edit(int id)
{
var model = _context.Employees.Find(id);
if (model == null)
{
return RedirectToAction("Index");
}
return View(model);
}
[HttpPost]
public IActionResult Edit(int id, EmployeeEditViewModel input)
{
var employee = _context.Employees.Find(id);
if (employee != null && ModelState.IsValid)
{
employee.EmployeeName = input.EmployeeName;
_context.SaveChanges();
return RedirectToAction("Details", new { id = employee.ID });
}
return View(employee);
}
public class EmployeeEditViewModel
{
[Required, MaxLength(80)]
public string EmployeeName { get; set; }
}
[HttpGet]
public ViewResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(EmployeeEditViewModel model)
{
if (ModelState.IsValid)
{
var employee = new Employee();
employee.EmployeeName = model.EmployeeName;
employee.EntryDate = System.DateTime.Now;
_context.Employees.Add(employee);
_context.SaveChanges();
return RedirectToAction("Details", new { id = employee.ID });
}
return View();
}
}
}
显示员工列表的主页或 Index.chtml 文件具有 AllowAnonymous
属性,因此可以直接访问。
如果我们点击其他页面,则会出现报错了。