此时,任何人都可以进入电话簿页面,因为没有进行权限验证。我们将定义两个权限:
- 进入电话薄页面的权限
- 新建用户的权限
查看权限
定义权限
在AppAuthorizationProvider 类里面添加一个新的权限:
pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
权限需要一个唯一的名字,我们在AppPermissions 定义权限名字常量。
public const string Pages_Tenant_PhoneBook = "Pages.Tenant.PhoneBook";
权限的名字叫Pages.Tenant.PhoneBook。虽然可以设置任何字符串(只要它是唯一的),但建议使用该命名规范。权限可以有一个本地化显示名称,这里叫PhoneBook。最后我们设置该权限是租户级别。
添加 ABPAUTHORIZE 特性
AbpAuthorize 特性可以使用在类或方法上,以此来保护应用服务或服务的方法不会被非法用户访问。因为所有的服务端代码都位于PersonAppService类里,我们可以像下面那样设置类的特性:
[AbpAuthorize(AppPermissions.Pages_Tenant_PhoneBook)]
public class PersonAppService : PhoneBookAppServiceBase, IPersonAppService
{
//...
}
现在,我们尝试通过点击菜单进入电话薄页面:
我们会得到一个错误,当没有所需的权限,然后调用PersonAppService 的任何方法都会抛出异常。
隐藏没有授权的菜单
我们需要隐藏电话簿的菜单项,非常简单,打开MpaNavigationProvider 并且添加requiredPermissionName,如下所示:
).AddItem(new MenuItemDefinition(
PageNames.App.Tenant.PhoneBook,
L("PhoneBook"),
url: "Mpa/PhoneBook",
icon: "glyphicon glyphicon-book",
requiredPermissionName: AppPermissions.Pages_Tenant_PhoneBook
)
授权
所以,现在我们怎样该进入电话薄页面?简单,在权限管理页面编辑admin角色的权限
我们可以看到在权限里面多了一个叫电话薄的权限。所以,我们可以选中后保存设置。保存后,我们需要刷新整个页面来更新当前用户的权限。我们还可以为特定用户授予此权限。
现在,我们可以进入电话薄页面了。
新建用户权限
虽然页面权限很有用并且总是需要,但是我们可能也需要定义额外的权限来在页面上执行一些特定的操作,比如创建一个新的用户。
定义权限
同样的方式定义权限
var phoneBook = pages.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook, L("PhoneBook"), multiTenancySides: MultiTenancySides.Tenant);
phoneBook.CreateChildPermission(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson, L("CreateNewPerson"), multiTenancySides: MultiTenancySides.Tenant);
第一个权限我们前面已经定义,第二行代码,我们为第一个权限定义了一个子权限。
添加 ABPAUTHORIZE 特性
这次,我们为 CreatePerson 方法添加 AbpAuthorize 特性
[AbpAuthorize(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson)]
public async Task CreatePerson(CreatePersonInput input)
{
var person = input.MapTo<Entities.Person>();
await this._personRepository.InsertAsync(person);
}
隐藏没有授权的按钮
如果我们运行程序并尝试添加用户,当我们点击保存按钮后会返回一个错误。但是,最好的方式是当我们没有这个权限,我们需要将添加用户的按钮隐藏。非常简单:
打开 index.cshtml 视图使用 IsGranted 方法:
@if (IsGranted(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson))
{
<button id="CreateNewPersonButton" class="btn btn-primary blue">
<i class="fa fa-plus"></i>@L("CreateNewPerson")
</button>
}
加完代码后,“添加用户”按钮将不会被渲染,用户也不能看见它。
授权
为了看见这个按钮,我们同样需要在权限设置页面进行配置:
如上图所示,添加人员权限是电话簿的子权限
MVC Controller 授权
我们为 PersonAppService 添加授权特性,这可以防止未经授权就调用该服务。但未经授权的用户还可以直接调用PhoneBookController 的 action,又由于PhoneBookController 调用 personappservice,他们将会得到授权的异常并且不能使用服务。我们同样也可以保护MVC Controller,这是因为某些MVC action 可能不会使用应用服务。另外,最好在一开始就规避这种未经授权的尝试。
我们为MVC Controller使用AbpMvcAuthorize 特性,如下所示:
[AbpMvcAuthorize(AppPermissions.Pages_Tenant_PhoneBook)]
public class PhoneBookController : AbpZeroTemplateControllerBase
{
private readonly IPersonAppService _personAppService;
public PhoneBookController(IPersonAppService personAppService)
{
this._personAppService = personAppService;
}
// GET: Mpa/PhoneBook
public ActionResult Index(GetPeopleInput input)
{
var output = this._personAppService.GetPeople(input);
var model = new IndexViewModel(output);
return View(model);
}
[AbpMvcAuthorize(AppPermissions.Pages_Tenant_PhoneBook_CreatePerson)]
public PartialViewResult CreatePersonModal()
{
return PartialView("_CreatePersonModal");
}
}