پیاده سازی یک سیستم دسترسی Role Based در Web API و AngularJs - بخش دوم
نویسنده: مهرداد کاهه
تاریخ: ۱۳۹۵/۰۱/۱۷ ۲۱:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public class Permission
{
[Key]
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Area { get; set; }
public string Control { get; set; }
public virtual ICollection<Role> Roles { get; set; }
} | Control | Area |
| view | products |
| add | products |
| edit | products |
| delete | products |
با توجه به جدول فوق همانطور که مشاهده میکنید تمامی آنچه که برای دسترسی Products مورد نیاز است در یک حوزه و 4 کنترل گنجانده میشود. البته توجه داشته باشید سناریویی که مطرح کردیم برای روشن سازی مفهوم ناحیه یا حوزه و کنترل بود. همانطور که میدانیم در AngularJS تمامی اطلاعات توسط APIها فراخوانی میگردند. از این رو یک موهبت دیگر این روش، خوانایی مفهوم حوزه و کنترل نسبت به نام کنترلر و متد است.
مدل Roles را ما به صورت زیر توسعه دادهایم:
public class Role
{
[Key]
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public virtual ICollection<Permission> Permissions { get; set; }
public virtual ICollection<User> Users { get; set; }
} در مدل فوق میبینید که دو رابطه چند به چند وجود دارد. رابطه اول که همان Permissions است و در مدل پیشین تشریح شد. رابطهی دوم رابطه چند به چند بین کاربر و نقش است. چند کاربر قادرند یک نقش در سیستم داشته باشند و همینطور چندین نقش میتواند به یک کاربر انتساب داده شود.
ما در این سیستم از ASP.NET Identity 2.1 استفاده و کلاس IdentityUser را override کردهایم. در مدل override شده، برخی اطلاعات جدید کاربر، به جدول کاربر اضافه شدهاند. این اطلاعات شامل نام، نام خانوادگی، شماره تماس و ... میباشد.
public class ApplicationUser : IdentityUser
{
[MaxLength(100)]
public string FirstName { get; set; }
[MaxLength(100)]
public string LastName { get; set; }
public bool IsSysAdmin { get; set; }
public DateTime JoinDate { get; set; }
public virtual ICollection<Role> Roles { get; set; }
} در نهایت تمامی این مدلها به وسیله EF Code First پایگاه داده سیستم ما را تشکیل خواهند داد.
public class RBACAttribute : AuthorizeAttribute
{
public string Area { get; set; }
public string Control { get; set; }
AccessControlService _AccessControl = new AccessControlService();
public override void OnAuthorization(HttpActionContext actionContext)
{
var userId = HttpContext.Current.User.Identity.GetCurrentUserId();
// If User Ticket is Not Expired
if (userId == null || !_AccessControl.HasPermission(userId, this.Area, this.Control))
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
}
} [HttpPost]
[Route("ChangeProductStatus")]
[RBAC(Area = "products", Control = "edit")]
public async Task<HttpResponseMessage> ChangeProductStatus(StatusCodeBindingModel model)
{
// Method Body
}