CLK.AspNet.Identity
CLK.AspNet.Identity是一个基于ASP.NET Identity扩展设计的验证授权模块,这个模块提供以角色为基础的访问控制(Role-based access control, RBAC),将系统授权拆解为User(使用者)、Role(角色)、Permission(权限)。让开发人员可以在系统内,定义用户属于哪个角色、哪个角色拥有那些权限、权限可以使用哪些功能。后续使用者通过验证之后,就可以依照角色权限来使用系统功能。
开源地址:https://github.com/Clark159/CLK.AspNet.Identity
问题情景
开发人员在系统内套用CLK.AspNet.Identity后,就可以依照使用者的权限,来限制用户能够使用那些功能。当用户透过浏览器进入权限的功能页面时,就会收到HTTP的403状态代码,用来告知使用者没有权限进入该页面。
以提供更好的使用者体验角度来说,用户点击选单项目后,得到没有权限进入该页面的响应。这样的操作流程,很容易让用户失去耐心。为了提供更好的用户体验,系统应该依用户的权限来显示选单项目,只显示有权限可以进入使用的选单项目,用以减少用户操作错误的机会。
解决方案
在套用CLK.AspNet.Identity的系统里,可以使用HasPermission这个扩充方法,来提供依权限显示选单项目的功能。使用方法如下:
在系统里加入一个新的ProductController、ProductViews,并且依照下列范例程序,加入Method及对应的权限:ProductAddAccess、ProductRemoveAccess。
public class ProductController : Controller
{
[RBACAuthorize(Permission = "ProductAddAccess")]
public ActionResult Add()
{
ViewBag.Message = "Your product add page.";
return View();
}
[RBACAuthorize(Permission = "ProductRemoveAccess")]
public ActionResult Remove()
{
ViewBag.Message = "Your product remove page.";
return View();
}
}
编辑Views\Shared_Layout.cshtml,并且依照下列范例,使用HasPermission这个扩充方法,来依照用户的权限显示选单项目。
<div class="col-md-12" style="background-color:#222">
<div class="container">
@if (User.HasPermission("ProductAddAccess"))
{
@Html.ActionLink("Product add", "Add", "Product", null, new { @class = "btn btn-primary" })
}
@if (User.HasPermission("ProductRemoveAccess"))
{
@Html.ActionLink("Product remove", "Remove", "Product", null, new { @class = "btn btn-primary" })
}
</div>
</div>
完成上述程序程序开发工作之后,还需要进入系统,设定用户权力。在下面这个范例中,示范使用Permission管理页面,将权限开放给Admin群组使用。
使用预设的管理账号登入(ID:admin@example.com, PW:admin)登入后,可以看到因为admin@example.com属于Admin群组、而Admin群组拥有ProductAddAccess权限,所以系统选单中可以看到Product add这个选单项目。
更换使用预设的访客账号登入(ID:guest@example.com, PW:guest)登入后,可以看到因为guest@example.com属于Guest群组、而Guest群组没有ProductAddAccess权限,所以系统选单中看不到Product add这个选单项目。
使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC)
前言
ASP.NET Identity是微软所贡献的开源项目,用来提供ASP.NET的验证、授权机制。而在ASP.NET
Identity的功能模块中:是采用Claims-Based验证来提供验证机制、并且实作Role-Based授权来提供授权机制。开发人员在系统内套用ASP.NET
Identity后,就可以像下列范例一样定义用户属于哪个角色、哪个角色可以使用那些功能,后续用户通过验证之后,就可以依照角色授权来使用系统功能。
ASP.NET Identity授权机制,可以在系统运行中动态变更用户所属的角色,但是却不能动态变更角色可以使用的功能。这是因为在ASP.NET
Identity里,使用者属于哪个角色的设定储存于数据库可以动态变更,而角色可以使用那些功能的设定则是定义在程序代码没有办法动态变更。虽然这样的授权机制已经可以符合大部分的开发需求,但在需要动态变更角色使用那些功能的开发项目中,开发人员就没有机会使用到ASP.NET
Identity丰富的验证授权机制。
领域模型
角色可以使用那些功能
public class HomeController : Controller
{
[Authorize(Roles = "Admin")]
public ActionResult Contact() { ... }
[Authorize(Roles = "Guest")]
public ActionResult Contact() { ... }
}
使用者属于哪个角色
本篇文章介绍一个基于ASP.NET
Identity开发设计的验证授权模块:CLK.AspNet.Identity。这个验证授权模块提供以角色为基础的访问控制(Role-based access
control,
RBAC),将系统授权拆解为User(使用者)、Role(角色)、Permission(权限)。开发人员在系统内套用CLK.AspNet.Identity
后,就可以像下列范例一样定义用户属于哪个角色、哪个角色拥有那些权限、权限可以使用哪些功能,后续用户通过验证之后,就可以依照角色权限来使用系统功能。
CLK.AspNet.Identity授权机制,除了可以继续使用继承自ASP.NET
Identity的Claims-Based验证机制之外,也可以在系统运行中动态变更储存于数据库的授权设定:使用者所属的角色、角色拥有的权限,让系统的授权设定更加灵活多变,用以满足更多的用户需求。
领域模型
权限可以使用哪些功能
public class HomeController : Controller
{
[RBACAuthorize(Permission = "AboutAccess")]
public ActionResult Contact() { ... }
[RBACAuthorize(Permission = "ContactAccess")]
public ActionResult Contact() { ... }
}
权限属于哪个角色
使用者属于哪个角色
安装
首先开启Visual Studio建立一个「完全空白」的ASP.NET Web 应用程序。
接着开启NuGet管理工具,搜寻并安装:「CLK.AspNet.Identity.Mvc Template」
安装需要花费一些时间,安装完毕后即可看到必要档案都已加入至项目。
安装好CLK.AspNet.Identity之后,按下Visual Studio的执行按钮,就可以在浏览器上看到预设的首页内容。
变更角色的权限
使用预设的访客账号登入(ID:guest@example.com,
PW:guest),点击页面选单按钮:About,因为guest@example.com属于Guest群组、而Guest群组没有
AboutAccess权限,所以会收到403拒绝访问的页面内容。
使用预设的管理账号登入(ID:admin@example.com,
PW:admin),点击页面选单按钮:PermissionsAdmin进入权限管理页面,编辑AboutAccess权限,让Guest群组拥有AboutAccess权限。
更换回预设的访客账号登入(ID:guest@example.com,
PW:guest),点击页面选单按钮:About,因为现在Guest群组拥有AboutAccess权限,所以可以浏览About页面内容。
变更使用者的角色
使用预设的访客账号登入(ID:guest@example.com,
PW:guest),点击页面选单按钮:Contact,因为guest@example.com属于Guest群组、而Guest群组没有
ContactAccess权限,所以会收到403拒绝访问的页面内容。
使用预设的管理账号登入(ID:admin@example.com,
PW:admin),点击页面选单按钮:UsersAdmin进入使用者管理页面,编辑guest@example.com使用者,让guest@example.com使用者加入到Admin群组。
更换回预设的访客账号登入(ID:guest@example.com,
PW:guest),点击页面选单按钮:Contact,因为现在guest@example.com属于Admin群组,而Admin群组拥有
ContactAccess权限,所以可以浏览Contact页面内容。
新增系统的权限
回到Visual
Studio编辑新功能,首先在HomeController增加一个新功能「News」、设定NewsAccess权限可以使用这个功能,并且在Viwes里面加上对应的变更。
public class HomeController : Controller
{
[RBACAuthorize(Permission = "NewsAccess")]
public ActionResult News()
{
ViewBag.Message = "Your news page.";
return View();
}
}
按下Visual Studio的执行按钮,可以在浏览器上看到预设的首页内容,并且内容中多了一个名称为News的页面选单按钮。
使用预设的访客账号登入(ID:guest@example.com,
PW:guest),点击页面选单按钮:News,这时因为系统里没有设定NewsAccess权限,所以会收到PermissionName not
found.的错误讯息页面。
使用预设的管理账号登入(ID:admin@example.com,
PW:admin),点击页面选单按钮:PermissionsAdmin进入权限管理页面,新增NewsAccess权限,并且让Guest群组拥有NewsAccess权限。
更换回预设的访客账号登入(ID:guest@example.com,
PW:guest),点击页面选单按钮:News,因为现在Guest群组拥有NewsAccess权限,所以可以浏览News页面内容。