• بررسی چگونگی کنترل دسترسی کاربر به صورت Dynamic در پروژه های ASP.NET MVC
بررسی چگونگی کنترل دسترسی کاربر به صورت Dynamic در پروژه های ASP.NET MVC
1395/03/05 - 13:04:32 // MVC 5 & 6 // 3 نظر // 6645 بازدید

همانطور که می دانید ، یکی از مهمترین بخشهای یک سیستم کنترل Login بودن یا نبودن کاربر و پس از آن کنترل دسترسی کاربر به یک بخش خاص از نرم افزار میباشد . در گذشته تکنولوژی WebForm هم امکاناتی فراهم نموده بود ، لاکن اکثر برنامه نویسان ترجیح میداند با ایجاد چندین جدول User ، Roles و اتصال آنها در جدولی دیگر به همدیگر ، دسترسی کاربر لاگین نموده را در هر تراکنش یا صدا زدن یک Module کنترل میکردند و در صورت عدم دسترسی کاربر ، با نمایش پیام یا .... از دسترسی کاربر به آن قسمت جلوگیری می نمودند .

بسمه تعالی

بررسی چگونگی کنترل دسترسی کاربر به صورت Dynamic در پروژه های ASP.NET MVC

همانطور که می دانید ، یکی از مهمترین بخشهای یک سیستم کنترل Login بودن یا نبودن کاربر و پس از آن کنترل دسترسی کاربر به یک بخش خاص از نرم افزار میباشد . در گذشته تکنولوژی WebForm هم امکاناتی فراهم نموده بود ، لاکن اکثر برنامه نویسان ترجیح میداند با ایجاد چندین جدول User ، Roles و اتصال آنها در جدولی دیگر به همدیگر ، دسترسی کاربر لاگین نموده را در هر تراکنش یا صدا زدن یک Module کنترل میکردند و در صورت عدم دسترسی کاربر ، با نمایش پیام یا .... از دسترسی کاربر به آن قسمت جلوگیری می نمودند .

پس از پیدایش ASP.NET MVC و Stable شدن آن در نسخه های بالای 4 و بخصوص MVC 5 ، این امکان به کاربران داده شد تا با استفاده از امکانات Identity و با استفاده از Authorize Attribute ، لاگین بودن کاربر را کنترل و در صورت عدم احراز هویت ، کاربر را به صفحه لاگین منتقل نمایند .

مسئله ای که پس از احراز هویت مطرح است ، کنترل دسترسی کاربر در ASP.NET MVC می باشد که این امر هم با استفاده از HardCode کردن User Role در Authorize Attribute و افزودن Role به جداول ایجاد شده امکان پذیر است . برای انجام این کار وضعیتی مشابه زیر بوجود خواهد آمد .

همانطور که مشاهده میکنید ، برای ایجاد دسترسی به چند Role مختلف هم می توان به شکل زیر عمل نمود .

خوب ظاهرا همه مشکلات به صورت پیش فرض توسط MVC حل شده و شما میتوانید به تعداد نامحدود Role تعریف کرده و در Controller ها با ایجاد محدودیت برای Action Method ها از آنها استفاده کنید .

حال باید دید مشکل کجاست ؟. در عمل هیچ ایرادی وجود ندارد و پروژه های کوچک و در سطح معرفی توانمندیهای MVC و ... بسیار جالب و راضی کننده به نظر می رسند ، حال اگر در یک Enterprise System قرار شد به دلایلی این سطوح دسترسی Dynamic شده و اصلن توسط خود استفاده کنندگان سیستم عملیات تعریف و Assign کردن نقش و Role انجام شود ، چه باید کرد ؟ اینجاست که برنامه نویسی که همین کار را در WebForm با نهایتا یک روز کاری انجام داده است ، به مشکل بر میخورد و گرفتار میشود . آیا میتوان روزانه Source Code پروژه را تغییر داد و مثلا چند نقش جدید ایجاد و بعد به سراغ یک به یک Controller ها که تازه معلوم نیست چه تعداد Action Method درون خود دارند رفته و Authorize Attribute را برای هریک جداگانه تغییر داد؟.

بر اساس مشاهدات بنده ، دوستان برنامه نویس زیادی با توجیهات خاص و قانع کردن مشتری به اینکه باید سیستم دارای Role ها مشخص باشد و فلسفه بافی و ... سعی نموده اند از این مشکل خلاصی یابند ، ولی حداقل خودشان میداند که توجیهاتشان قانع کننده نیست و نمی توان به آن استناد نمود .

در این مبحث خیلی کوتاه قصد دارم 80% این مشکل را برطرف نمایم . 20 درصد دیگر مربوط به این مشکل است که اکثر کاربران علاقه دارند در صورت عدم وجود دسترسی ، کاربر در همان صفحه در حال کار بماند و فقط یک پیام زیبا مبنی بر عدم دسترسی مشاهده نماید . این کار نیاز به گذاشتن زمان بیشتری دارد که در مبحث فعلی ما خارج است .

در این مقاله به شما آموزش خواهم داد که چگونه Role های Dynamic در سیستم داشته و در صورت عدم وجود دسترسی به صفحه لاگین منتقل نگردید ، بلکه به یک Custom Page با پیام عدم دسترسی منتقل شوید . مراحل زیر را دنبال کنید .

1- یک پروژه از نوع MVC به شکل زیر ایجاد کنید .

سپس نوع پروژه را مطابق زیر انتخاب کنید .

2- به سراغ WebConfing رفته و نام دیتابیس و فایل mdf را به CustomRoles تغییر دهید.

3- درون HomeController رفته و مطابق زیر برای About Action یک وضعیت نیاز به Login بودن ایجاد نمایید .

4- پروژه را Run کنید و با مراجعه به About به صفحه لاگین منتقل خواهید شد . یک کاربر بسازید و از این طریق دیتابیس برای شما ایجاد خواهد گردید .

حال خواهید دید که با هر بار مراجعه به About ابتدا Login بودن کاربر چک شده و اگر کاربر لاگین نکرده باشد ، به صفحه لاگین منتقل خواهد شد . الان وقت این است که فرض کنید جدوال Role و ... هم دارید و مشکل شما این است که باید Authorize Attribute فقط Role ها داینامیک هم بپذیرد .

برای ادامه یک کلاس به نام CustomAuthorizationAttribute به فولدر Infra اضافه کنید. بدنه کلاس در یک صفحه برای نمایش جای نخواهد گرفت ، لذا در بیش از یک تصویر درون مقاله قرار داده خواهد شد.

این کلاس باید ازAuthorizeAttribute ارث بری کند . و بدنه اولین متد به شکل زیر نوشته خواهد شد.

این متد که پس از ارث بری از AuthorizeAttribute در عمل Over Ride شده است ، وظیفه بررسی خطاهایی را دارد که در صورت عدم موفق بودن فرآیند لاگین و بررسی دسترسی و .... رخ میدهد . در صورتی که کاربر لاگین نکرده باشد ، در اولین IF به صفحه لاگین منتقل میشود و اگر لاگین بود، فعلن فرض بر این است که دسترسی لازم را نداشته است . یک Action Method به نام AccessDenied در HomeController به شکل زیر ایجاد و یک View هم به همین نام ساخته ایم . این View در صورت عدم وجود دسترسی نمایش داده خواهد شد.

View هم فقط پیغام درون ViewBag را نمایش داده و به شکل زیر است .

خوب حالا به متد بعدی درون کلاس که آن هم OverRide شده است دقت کنید.

در اینجا ابتدا Login بودن کاربر بررسی میشود . اگر کاربر لاگین کرده بود ، باید دسترسیهاش کنترل شود که این کار باید از طریق ارتباط با دیتابیس و ... انجام شود . و پس از آن مثلا بر اساس جواب دیتابیس و ... متغیر IsUserInRole مقدار دهی True یا False گردد. پس از آن باز می توان برای بازگرداندن True یا False تصمیم گرفت و بر اساس آن تصمیم گرفت . حال ببینیم در Controller چگونه میتوان از این Attribute استفاده کرد .

فقط حواستن به Infra و تعریف آن به NameSpace ها باشد .

شاید سوال کنید که برای یافتن Current Controller و Current Action Name چه باید بکنم تا بتوانم دسترسی کاربر را بر اساس آنها پیدا کنم . برای این کار هم با OverRide کردن متد OnAuthorization میتوانید این دو مقدار را مشابه زیر بدست بیاوردید.

حالا در سطح کلاس اسامی Controller و Action را داریم و میتوان به سادگی از آنها در متدهای دیگر استفاده نمود.

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

دانلود سورس پروژه

علی کلاهدوزان
معرفی نویسنده : علی کلاهدوزان

سلام بر دوستان ،
شاید رایج است به عنوان پروفایل کاربر ، چند خطی راجع به خودم بنویسم ، ولی وضعیت کاری و سوابق من با یک جستجوی ساده در گوگل مشخص خواهد شد ، لذا سرتان را با مطالب بی مورد به درد نیاورم بهتر است . اگر نکته خاصی لازم بود بدانید در قسمت "ایلیا سافت در یک نگاه" به احتمال زیاد یافت خواهد شد . جزئیات بیشتر را سوال کنید ، آدرس ایمیل Ali@Kolahdoozan.com همیشه جوابگوی شماست .امیدوارم از مطالب سایت استفاده کرده باشید . شاد و پیروز باشید .

امتیاز به مطلب
           
نظرات کاربران
  • ناشناس
    1395/03/11 - 11:35:35

    1
    1
    در صورتی که بخوایم برای درخواست های ای جکسی هم کار ریدارکت انجام بشه چه کاری میشه انجام داد؟
     
    ---
    پاسخ : بله میشه . شاید بگویم به زودی . اندکی دردسر دارد و به صورت مقاله در آوردنش هم حوصله میخواهد. 
  • ناشناس
    1395/03/11 - 11:38:05

    0
    0
    بعد صفحات عمومی سایت رو چطور میشه با این روش مدیریت کرد؟
  • بهاره
    1395/12/02 - 18:57:41

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