PDA

View Full Version : حرفه ای: ایجاد سطح دسترسی داینامیک توسط مدیر سیستم



Maryam_1368
دوشنبه 31 خرداد 1395, 08:54 صبح
با سلام و خسته نباشید خدمت دوستان
فرض کنید یه نرم افزار نوشتیم که دارای کنترلر و اکشن متدهای مختلفی هستش.
حالا چجوری مدیر سیستم بتونه جوری یوزر تعریف بکنه که بتونه به هر یوزر سطح دسترسی داینامیک بده
مثلا ما 10 تا کنترلر داریم ، زمان تعریف یوزر، اون 10 کنترلر برای مدیر سایت لیست بشه و بتونه با تیک زدن هر کدوم سطح دسترسی دلخواه رو به کاربری که تعریف میکنه بده.
چجوری این مورد رو پیاده سازی کنم؟
اگر فیلم آموزشی و یا مقاله ای در این زمینه دارید ممنون میشم معرفی کنید.
البته زبان اصلی هم بود مشکلی نیست.فقط این مواردی رو که گفتم پوشش بده
پیشاپیش تشکر:لبخندساده:

hakim22
دوشنبه 31 خرداد 1395, 09:23 صبح
برای انجام این کار شما باید از سمت ها استفاده کنید. برای هر کنترلر یک سمت تعریف کنید . مثلا برای کنترلر مدیریت کاربرها از


Authorize(roles="userAdmin")

استفاده کنید. بعد فقط کافیه به کاربری که میخواد اجازه ی دسترسی به مدیریت کاربرها رو داشته باشه سمت userAdmin رو اضافه کنید. این کار با Identity خیلی ساده هست.

شما میتوانید صدها سمت تعریف کنید. برای هر اکشن یک سمت خاص تعریف کنید و با اضافه کردن اون سمت به کاربر دسترسی رو به اون اکشن کنترل کنید.

مثلا شما یک اکشن برای ویرایش یک پست وبلاگ دارید



[Authorize(Roles="BlogPostEdit"))]
public virtual ActionResult Edit(int id)
{
// Edit Post action here
return View();
}


در Identity اضافه کردن سمت با استفاده از


_userManager.AddToRoles(userId, roleName);


انجام میشه.

Maryam_1368
دوشنبه 31 خرداد 1395, 10:06 صبح
ممنونم دوست عزیز..
اما این روش به صورت استاتیک میشه درسته؟
الان این مدل کد نویسی که شما انجام دادین یعنی:

Authorize(roles="userAdmin")



دارین به صورت دستی Role تعریف میکنید..

البته شایدم من اشتباه میکنم..
ولی منظور من اینه لیست تمام اکشن متدها و کنترلر ها برای کاربر به صورت درختی نمایش داده بشه و اینا به صورت Check list باشن
حالا خود مدیر میخاد یه کاربر مثلا با نام کاربری Maryam تعریف بکنه اونجا بتونه بگه این Maryam به چه صفحاتی دسترسی داره..
حالا این

Authorize(roles="userAdmin")


که بالای کنترلر ها میاد هم باید به صورت داینامیک تولید بشه..درسته؟

امیدوارم تونسته باشم منظورم رو برسونم..
آیا این توضیحاتی که دادم با مواردی که شما گفتین قابل پیاده سازی هست؟

parsdarab
دوشنبه 31 خرداد 1395, 11:11 صبح
سلام
یه کار دیگه هم میشه انجام داد
موقعی که سایت لود میشه در قسمت متد Initialize بخش DbMigrationsConfiguration بیای تمام کنترلرها و اکشنها رو لیست کنی و بریزی داخل دیتابیس و در یه قسمتی دیگر از برنامه این رکوردها رو لیست کنی و به کاربران مجوز بدی

hakim22
دوشنبه 31 خرداد 1395, 14:37 عصر
ممنونم دوست عزیز..
اما این روش به صورت استاتیک میشه درسته؟
الان این مدل کد نویسی که شما انجام دادین یعنی:

Authorize(roles="userAdmin")



دارین به صورت دستی Role تعریف میکنید..

البته شایدم من اشتباه میکنم..
ولی منظور من اینه لیست تمام اکشن متدها و کنترلر ها برای کاربر به صورت درختی نمایش داده بشه و اینا به صورت Check list باشن
حالا خود مدیر میخاد یه کاربر مثلا با نام کاربری Maryam تعریف بکنه اونجا بتونه بگه این Maryam به چه صفحاتی دسترسی داره..
حالا این

Authorize(roles="userAdmin")


که بالای کنترلر ها میاد هم باید به صورت داینامیک تولید بشه..درسته؟

امیدوارم تونسته باشم منظورم رو برسونم..
آیا این توضیحاتی که دادم با مواردی که شما گفتین قابل پیاده سازی هست؟


خیر کاملا هم دینامیک هست.

شما سمتهارو یکبار تعریف می کنید. قرار نیست سمت ها موقع اجرای برنامه تغییری داشته باشند.

ما محدودیتی که با Authorize تعریف کردیم بر اساس role بوده و نه نام یک کاربر.

نیازی نیست که لیست تمامی اکشن ها و کنترلر هارو به کاربر نمایش بدید. اینکار خیلی پیچیده است و کنترل دسترسی های کاربر به روشی که شما می گید خیلی سخت و سنگینه.
شما ممکنه 200 یا 500 اکشن داشته باشید.خیلی از اکشن های شما دوتایی با هم کار می کنند مثلا شما یک اکشن Get دارید و یک اکشن Post که برای ذخیره یک فرم استفاده میشه. هر عملیاتی که کاربر میخواد انجام بده باید با تک تک اون لیست چک بشه و این کار سایت رو هم کند میکنه. ضمن اینکه چنین امکانی به صورت پیشفرض در Identity نیست و باید خودتان یک کلاس جدید از Autorize بسازید. اینکار ممکنه و خیلی ها هم ازش استفاده می کنند ولی روش مناسبی نیست.

ولی با استفاده از سمت ها که در خود ساختار Identity تعریف شده شما برای هر عملیاتی که در سایت انجام میشه یک سمت درست می کنید. مثل (ایجاد پست، ویرایش پست ، تغییر نام پست ، حذف نظر ، ویرایش نظر و ...) بعد این رو به صورت یک ساختار درختی به کاربر نمایش میدید. معمول این هست که یک کلاس استاتیک ساخته میشه و لیست همه ی دسترسی ها به صورت یک متغیر string در اون لیست میشه تا جستجو راحت باشه. بعد سمتهارو به کاربر اضافه یا ازش حذف می کنید. نتیجه کاملا یکسانه. ولی انجامش خیلی راحت تره.

Maryam_1368
دوشنبه 31 خرداد 1395, 17:44 عصر
خیر کاملا هم دینامیک هست.

شما سمتهارو یکبار تعریف می کنید. قرار نیست سمت ها موقع اجرای برنامه تغییری داشته باشند.

ما محدودیتی که با Authorize تعریف کردیم بر اساس role بوده و نه نام یک کاربر.

نیازی نیست که لیست تمامی اکشن ها و کنترلر هارو به کاربر نمایش بدید. اینکار خیلی پیچیده است و کنترل دسترسی های کاربر به روشی که شما می گید خیلی سخت و سنگینه.
شما ممکنه 200 یا 500 اکشن داشته باشید.خیلی از اکشن های شما دوتایی با هم کار می کنند مثلا شما یک اکشن Get دارید و یک اکشن Post که برای ذخیره یک فرم استفاده میشه. هر عملیاتی که کاربر میخواد انجام بده باید با تک تک اون لیست چک بشه و این کار سایت رو هم کند میکنه. ضمن اینکه چنین امکانی به صورت پیشفرض در Identity نیست و باید خودتان یک کلاس جدید از Autorize بسازید. اینکار ممکنه و خیلی ها هم ازش استفاده می کنند ولی روش مناسبی نیست.

ولی با استفاده از سمت ها که در خود ساختار Identity تعریف شده شما برای هر عملیاتی که در سایت انجام میشه یک سمت درست می کنید. مثل (ایجاد پست، ویرایش پست ، تغییر نام پست ، حذف نظر ، ویرایش نظر و ...) بعد این رو به صورت یک ساختار درختی به کاربر نمایش میدید. معمول این هست که یک کلاس استاتیک ساخته میشه و لیست همه ی دسترسی ها به صورت یک متغیر string در اون لیست میشه تا جستجو راحت باشه. بعد سمتهارو به کاربر اضافه یا ازش حذف می کنید. نتیجه کاملا یکسانه. ولی انجامش خیلی راحت تره.

ممنون از شما..اما یه سوال اینکه شما میگین ممکنه 500 تا اکشن باشه حرفتون کاملا صحیحه.
اما خوب وقتی تعداد کنترلر رو در نظر بگیریم خیلی تعدادش زیاد نمیشه(البته در برنامه های کوچیک)
حالا این مدلی که شما میگیم به صورت Hard Code میشه
یعنی منه برنامه نویس دارم به صورت دستی میام یه سری نقش تعریف میکنم
مثل نقش منشی سیستم، نقش حسابدار، نقش مدیر سایت و. ...
حالا وقتی میخام کاربر تعریف کنم میام میگم این کاربر نقش مدیر سایت رو داشته باشه..
خوب حالا فرض کنید مشتری علاوه بر اینکه بخواد کاربری که تعریف میکنه علاوه بر اینکه منشی باشه ، بخواد مدیر سایت هم باشه اما از کنترل پنل ادمین در قسمت مدیر سایت ، فقط و فقط بتونه خبر منتشر بکنه و به گزینه های دیگه سیستم مدیریت محتوی دسترسی نداشته باشه
راه حل اول: اینکه برنامه نویس بیا به صورت دستی این کاربر رو تعریف کنه
راه حل دوم: تمام کنترلرهای نرم افزار به صورت لیست نمایش داده بشن و مشتری خودش هر کدوم رو دوست داشت تیک بزنه و یک نقش کاملا سفارشی ایجاد بکنه
حالا من دنبال راه حل دوم میگردم که مشتری خودش بتونه نقش های مختلف تعریف کنه
حالا با توجه به حرف منطقیه شما درباره تعداد بالای اکشن متدها، اگه فقط واسه کنترلر ها این کار رو بخواد انجام بده چه راهی هست؟

parsdarab
دوشنبه 31 خرداد 1395, 17:58 عصر
شما میتونید attribute سفارشی بسازید

و بالای سر هر کنترلر و اکشن کد زیر رو بنویسید.


[CustomAuthorize(Description = "مدیریت جنسیت")]
public class GenderController : Controller

[CustomAuthorize(Roles = "_Gender_Index", Description = "صفحه اصلی")]
public ActionResult Index()

[CustomAuthorize(Roles = "_Gender_Create", Description = "ایجاد جنسیت")]
public ActionResult Create()

[HttpPost]
[ValidateAntiForgeryToken]
[CustomAuthorize(Roles = "_Gender_Create_Save", Description = "ذخیره جنسیت جدید")]
public ActionResult Create(BaseGender model)

hakim22
دوشنبه 31 خرداد 1395, 19:38 عصر
ممنون از شما..اما یه سوال اینکه شما میگین ممکنه 500 تا اکشن باشه حرفتون کاملا صحیحه.
اما خوب وقتی تعداد کنترلر رو در نظر بگیریم خیلی تعدادش زیاد نمیشه(البته در برنامه های کوچیک)
حالا این مدلی که شما میگیم به صورت Hard Code میشه
یعنی منه برنامه نویس دارم به صورت دستی میام یه سری نقش تعریف میکنم
مثل نقش منشی سیستم، نقش حسابدار، نقش مدیر سایت و. ...
حالا وقتی میخام کاربر تعریف کنم میام میگم این کاربر نقش مدیر سایت رو داشته باشه..
خوب حالا فرض کنید مشتری علاوه بر اینکه بخواد کاربری که تعریف میکنه علاوه بر اینکه منشی باشه ، بخواد مدیر سایت هم باشه اما از کنترل پنل ادمین در قسمت مدیر سایت ، فقط و فقط بتونه خبر منتشر بکنه و به گزینه های دیگه سیستم مدیریت محتوی دسترسی نداشته باشه
راه حل اول: اینکه برنامه نویس بیا به صورت دستی این کاربر رو تعریف کنه
راه حل دوم: تمام کنترلرهای نرم افزار به صورت لیست نمایش داده بشن و مشتری خودش هر کدوم رو دوست داشت تیک بزنه و یک نقش کاملا سفارشی ایجاد بکنه
حالا من دنبال راه حل دوم میگردم که مشتری خودش بتونه نقش های مختلف تعریف کنه
حالا با توجه به حرف منطقیه شما درباره تعداد بالای اکشن متدها، اگه فقط واسه کنترلر ها این کار رو بخواد انجام بده چه راهی هست؟

اگه به توضیحات دقت کنید نوشته شده که برای هر عملیات یک سمت تعریف کنید یعنی
مثل (ایجاد پست، ویرایش پست ، تغییر نام پست ، حذف نظر ، ویرایش نظر ، مشاهده کاربرها ، ویرایش کاربرها و ...)
هرکدام یک سمت باشند نه اینکه شما یک سمت "Admin" برای مدیر و یک سمت دیگر برای منشی و ... بسازید. نباید سمتهای کلی مثل اینهاتعریف کنید این کلا خارج از استاندارد است.

بلکه شما یک سمت دارید مثل EditPost یا DeletePost و EditUser و DeleteUser و .... یعنی برای هر عملیاتی که در سایت انجام میشه (که ممکنه ترکیبی از چند اکشن رو در بر بگیره) یک سمت تعریف کنید

یک کاربر میتونه هرچندتا از سمتها رو که میخواد داشته باشه.
شما می توانید به هر کاربر ترکیبی از چند سمت رو بدید. مثلا میتوانید چند مدیر داشته باشید با سطوح دسترسی متفاوت.

اگه میخواهید برای هر کنترلر دسترسی رو محدود کنید که دیگه روش سمت ها بهترین راه هست. برای هر کنترلر یک سمت تعریف کنید و به هر کاربر اون سمت رو بدید یا ازش بگیرید. دیگه نیازی به روش دیگر ندارید.

بزرگترین سایتها و با پیشرفته ترین حالت مدیریت دسترسی فقط با استفاده از همین روش سمتها قابل پیاده سازی است. (به صورت کاملا دینامیک و کنترل صد در صد روی تمامی جزئیات ) فقط باید توضیحات داده شده رو بادقت بخونید.

Maryam_1368
سه شنبه 01 تیر 1395, 19:37 عصر
اگه به توضیحات دقت کنید نوشته شده که برای هر عملیات یک سمت تعریف کنید یعنی
مثل (ایجاد پست، ویرایش پست ، تغییر نام پست ، حذف نظر ، ویرایش نظر ، مشاهده کاربرها ، ویرایش کاربرها و ...)
هرکدام یک سمت باشند نه اینکه شما یک سمت "Admin" برای مدیر و یک سمت دیگر برای منشی و ... بسازید. نباید سمتهای کلی مثل اینهاتعریف کنید این کلا خارج از استاندارد است.

بلکه شما یک سمت دارید مثل EditPost یا DeletePost و EditUser و DeleteUser و .... یعنی برای هر عملیاتی که در سایت انجام میشه (که ممکنه ترکیبی از چند اکشن رو در بر بگیره) یک سمت تعریف کنید

یک کاربر میتونه هرچندتا از سمتها رو که میخواد داشته باشه.
شما می توانید به هر کاربر ترکیبی از چند سمت رو بدید. مثلا میتوانید چند مدیر داشته باشید با سطوح دسترسی متفاوت.

اگه میخواهید برای هر کنترلر دسترسی رو محدود کنید که دیگه روش سمت ها بهترین راه هست. برای هر کنترلر یک سمت تعریف کنید و به هر کاربر اون سمت رو بدید یا ازش بگیرید. دیگه نیازی به روش دیگر ندارید.

بزرگترین سایتها و با پیشرفته ترین حالت مدیریت دسترسی فقط با استفاده از همین روش سمتها قابل پیاده سازی است. (به صورت کاملا دینامیک و کنترل صد در صد روی تمامی جزئیات ) فقط باید توضیحات داده شده رو بادقت بخونید.







دست شما درد نکنه کاملا متوجه شدم به چه صورته
مشکلم این بود فکر میکردم هر یوزر میتونه فقط یه سمت داشته باشه...
البته من Identity رو مسلط نیستم...با توجه به تجربه ای که دارین منبع خوب برای آموزشش سراغ دارین که با جزییات توضیح داده باشه؟
پیشاپیش تشکر

adameh_bahal
سه شنبه 01 تیر 1395, 22:17 عصر
http://fa.mohsen.es/post/3/%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D8%AF%DB%8C%D9%86%D8%A7%D9%85%DB%8C%DA%A9-%D8%B3%D8%B7%D9%88%D8%AD-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%A7%D9%86-%D8%AF%D8%B1-asp-net-mvc