مقدمه ای بر مکانیزم های امنیتی در NET Framework

مسئله فراهم کردن امنیت سیستم‌های نرم‌افزاری، همواره یکی از مسایل مهم و پیچیده تولیدکنندگان نرم‌افزار بوده و هست و سیستم‌های بسیار متنوعی برای این منظور ایجاد شده‌اند که در این مقاله یکی از جدیدترین آن‌ها یعنی ساختار امنیتی را که مایکروسافت در قالب NET. ارایه کرده است به صورت اجمالی بررسی می‌کنیم. شاید بتوان گفت که با توجه به مفاهیم جدیدی که مایکروسافت در NET. مطرح کرده است، ساختار امنیتی NET. در نوع خود بی‌نظیر است و این اولین‌بار است که مایکروسافت چنین سیستمی را ارایه کرده است. در اینجا قصد ارزیابی قدرت امنیتی NET. را نداریم و فقط به صورت اجمالی مفاهیم و قابلیت‌های آن را توضیح خواهیم داد.
قبل از پرداختن به موضوع امنیت در NET. آشنایی با دو مفهوم ضروری‌است که مختصراً هریک را تعریف می‌کنیم.
CLR) Common language runtime):
محیط زمان اجرای NET. است که به عنوان موتوری جهت مدیریت و اجرای کدها می‌باشد و کدهایی که تحت آن اجرا‌ می‌شوند، اصطلاحاً managed code نامیده می‌شوند. مهم‌ترین وظیفهCLR ، کامپایل زمان اجرا (SIT) می‌باشد که در طی آن managed code که به زبان MSIL می‌باشد، را به کدهای اجرایی سیستم تبدیل می‌کند.
Type safe code: این نوع کدها فقط می‌توانند به حافظه‌ای که به ‌آن‌ها اختصاص داده شده است دسترسی پیدا کنند. به عبارت دیگر، CLR دسترسی به حافظه توسط این کدها را کنترل می‌کند و چنانچه حافظه موردنظر در اختیار این کد باشد CLR، مجوز دسترسی به حافظه را می‌دهد. فرآیندی اختیاری تحت عنوان verification process وجود دارد که CLR آن را هنگام لود شدن برنامه انجام می‌دهد. CLR درطی این فرآیند با استفاده از کدهای MSIL مشخص می‌کند که کد Type safe است یا نه. چنانچه کدی Type safe باشد CLR طی اجرای کد، دسترسی آن به تمام منابع حیاتی را کنترل خواهد کرد و در صورت لزوم اجازه دسترسی را نخواهد داد.
با معرفی این دو مفهوم، مشخص می‌شود که کد نوشته شده در NET. باید از نوع managed code باشد تا بتواند از قابلیت‌های امنیتی موجود در NET. استفاده کند. در NET Framework. کلاس‌های زیادی جهت فراهم نمودن سرویس‌های امنیتی وجود دارد که هر یک به طریقی سرویس خاصی را فراهم‌می‌کند. در ادامه دو مکانیزم امنیتی جدید را که در NET Framework. وجود دارد مورد بررسی قرار می‌دهیم. 1- Code Access Security
وقتی که یک فایل اجرایی را اجرا می‌کنید، این فایل با دسترسی کاربری که آن را اجرا می‌کند، اجرا خواهد شد. در وقتی که با عنوان administrator وارد سیستم می‌شوید، چنانچه کدی را اجرا کنید، این کد به همراه قابلیت دسترسی administrator اجرا خواهد شد. با استفاده از مکانیزم Code Access Security، کد با دسترسی که خودش تعریف می‌کند، اجرا خواهد شد. به عبارت دیگر، علاوه بر دسترسی کاربری که کد را اجرا می‌کند، خود کد هم دارای هویت و دسترسی خواهد شد. تمام کدهایی که به صورت managed هستند، ازCode Access Security استفاده می‌کنند، که این استفاده می‌تواند به صورت صریح توسط نویسنده کد عنوان شود و یا NET. به صورت پیش‌فرض، تنظیمات پیش‌فرض را برای آن اعمال ‌کند. به‌طور کلی کارهایی که با Code Access Security می‌توان انجام‌داد عبارتند از:
1- تعریف مجوزهای دسترسی (Permission)
2- تعریف و تنظیم سیاست‌های امنیتی (Security Policy)
3- درخواست مجوز (Permission) توسط کد برای خودش جهت اجرای صحیح برنامه
4- امکان درخواست مجوز توسط کد برای فراخوانی کد. به عبارت دیگر برنامه از اجراکننده خود درخواست می‌کند
حتماً مجوز خاصی داشته باشد.
5- درخواست امضای دیجیتال توسط کد برای اجراکننده کد. به عبارت دیگر کد از اجراکننده خود می‌خواهد حتماً امضای CA خاصی را داشته باشد.

جهت استفاده از این مکانیزم امنیتی چند مورد را باید رعایت کنید:
اول: باید managed code تولید کنید و کد نوشته‌شده توسط شما type safe باشد (فقط ++VC قادر به تولیدunmanaged code می‌باشد. لذا حالت‌های پیچیده متعددی را می‌تواند تولید کند که فراتر از موضوع این مقاله می‌باشد. در C هم چنانچه از کلمه کلیدی unsafe استفاده نکنید کد شما type safe خواهد بود.)
دوم: از یکی از دو روشی که Code Access Security را وارد برنامه شما می‌کند، استفاده کنید که در ادامه توضیح داده می‌شود.
سوم: که از همه مهمتر می‌باشد، ضروری ‌است هنگام طراحی و تحلیل برنامه، تحلیلی امنیتی نیز روی کلاس‌های خود داشته باشید و بدین ترتیب مجوزهای مختلفی را که یک کلاس و یا متد در شرایط مختلف لازم دارد را پیدا کنید و تدابیر لازم جهت پیاده‌سازی را بیندیشید.
همان‌طور که اشاره شد،Code Access Security به دو شیوه می‌تواند در کدهای شما پیاده‌سازی شود که هر یک قابلیت‌های خاصی را در اختیار شما قرار می‌دهد:
imerative security syntax
در این مدل از یک سری کلاس‌هایی که سرویس‌های امنیتی را فراهم می‌کنند، اشیائی گرفته و مکانیزم
code Access را پیاده‌سازی می‌کنند. از این مدل زمانی استفاده می‌شود که تصمیمات امنیتی باید به صورت runtime گرفته شوند و تمام مسایل و تصمیمات در هنگام طراحی برنامه روشن و واضح نیستند. جهت روشن‌تر شدن موضوع به مثال زیر توجه کنید:

</FONT>

public Class MyClassPublic sub NewEnd SubPublic Sub MyMethod1()‘using imperative security syntax to demand FileIOPermissionDim MyFileIOPermAsNew FileIOPermission() MyFileIOPerm.Demand()End SubEnd Class
در اینجا با استفاده از کلاس FileIOPermission مشخص کرده‌ایم که فراخواننده این کد باید اجازه دسترسی، خواندن و نوشتن فایل‌ها را داشته باشد. نکته قابل توجه این است که فراخواننده فقط جهت اجرای تابع 1 My Method این دسترسی را لازم دارد و چنانچه در حین استفاده از برنامه سراغ این تابع نرود، به این دسترسی هم نیازی نخواهد داشت. کلاس‌های زیادی وجود دارند که همانند FileIOPermission دسترسی امنیتی خاصی را تعریف می‌کنند و تقریباً تمام این کلاس‌ها غیرقابل ارث‌بری می‌باشند. شما می‌توانید با توجه به نیاز خاصی که در یک تابع و یا کلاس خود دارید، از این کلاس‌ها استفاده کنید. در اینجا برخی از پرکاربردترین این کلاس‌ها را نام می‌بریم:
Registry Permission،Web Permission ،Environment Permission ،Printing Permission ،Security Permission
Declarative Security Syntax
در این شیوه با استفاده از attributeها، مکانیزم code Access security در برنامه پیاده‌سازی می‌شود. بدیهی است با توجه به این‌که از attributeها جهت تعیین و یا درخواست سطح دسترسی استفاده می‌کنیم، مجوزهای کلاس‌ها و یا توابع باید به صورت ثابت در حین طراحی برنامه مشخص شوند. از این رو انعطاف‌پذیری مدل قبلی جهت تصمیم‌گیری در زمان اجرا را در این حالت نخواهیم داشت. در واقع چنانچه در حین طراحی برنامه وجود مجوز خاصی را جهت اجرای برنامه به صورت دائم ضروری می‌دانید، استفاده از این روش مناسب می‌باشد و با استفاده از آن می‌توانید در هنگام لودشدن برنامه، مجوزهای خاصی را درخواست کنید و در صورتی که مجوز موردنظر داده نشود، از لود شدن برنامه جلوگیری کنید. به عنوان مثال به کد زیر توجه کنید:

public Class MyClass
Public sub New
‘Constructor is protected by the security call
End Sub
Public Sub MyMethod1()
‘Method is protected by the security call
End Sub
End Class
همان‌طور که ملاحظه می‌کنید در سطح کلاس My Class یک attribute قرار گرفته که مشخص می‌کند استفاده‌کننده این کلاس (فراخواننده برنامه) باید دارای مجوز FileIOPermission باشد. توجه کنید که attribute می‌تواند در سطح کلاس، یک متد خاص و یا حتی اسمبلی باشد، و ضمناً با استفاده از ساختار Security Action مشخص می‌کنیم که مجوز باید به چه نحو در برنامه وارد شود. به این معنی که آیا خود برنامه لازم دارد که این مجوز به آن داده شود یا این‌که فراخواننده باید این مجوز را داشته باشد، که در مثال، مقدار Demand مشخص کننده این است که فراخواننده برنامه باید این مجوز را داشته باشد.
غالباً در برنامه‌هایی که در NET. پیاده‌سازی می‌شوند، نیازهای امنیتی موردتوجه قرار نمی‌گیرند. با این وجود توجه داشته باشید که با استفاده از مکانیزم Code Access Security، قابلیت اطمینان برنامه را افزایش می‌دهید و اهداف زیر تأمین می‌شوند:‌
الف- مطلع کردن CLR از مجوزهای امنیتی‌ که برنامه شما نیاز دارد.
ب- بدون توجه به دسترسی‌های کاربری که برنامه را اجرا کرده است، فقط مجوزهای موردنیاز به برنامه شما داده خواهد شد و لذا چنانچه به هر نحوی کدهای مخرب دیگری از برنامه شما جهت نفوذ و اجرا استفاده کنند، فقط دسترسی‌های داده شده به برنامه شما را خواهند داشت و لذا میزان تخریب کم‌تر خواهد شد.
پ- احتمال بروز خطاهای زمان اجرای مربوط به مسایل امنیتی در برنامه کاهش می‌یابد.
ت- مدیر سیستم با استفاده از ابزاری با نام Perview.exe که در NET. موجود است می‌تواند مجوزهای موردنیاز برنامه شما را ببیند و لذا سیاست‌های امنیتی سیستم و حتی شبکه را به نحو مطلوبی تعیین کند. 2- Role Based Security
این مکانیزم امنیتی بسیار شبیه به مکانیزم گروه‌ها و کاربران در اکتیودایرکتوری می‌باشد. با استفاده از این مکانیزم، نقش‌هایی را که با برنامه شما در تماس خواهند بود تعریف کرده و به هر کدام مجوزهای خاصی را می‌دهید و لذا هنگام اجرا با تعیین این‌که چه کسی وارد برنامه می‌شود، نقش خاصی را به وی نسبت می‌دهید که مجوزهای خاصی دارد. در واقع با استفاده از Code Access Security بدون توجه به فرد اجراکننده کد، به کد برنامه مجوزهای خاصی را می‌دهید و یا از آن می‌گیرید و به‌طور کلی با کدها و برنامه‌ها سروکار دارید و با استفاده از Role Based Security به شخص اجراکننده کد مجوز خاصی می‌دهید.
Role Based Security غالباً در برنامه‌های تحت‌وب موردنیاز است که در آن‌ها افراد مختلفی با سیستم سروکار دارند. لذا ضروری‌ است هنگام ورود به سیستم، شناسایی شوند و نقش خاصی به فرد اختصاص یابد. بدیهی است جهت استفاده از این مکانیزم لا‌زم ‌است، هنگام طراحی برنامه نقش‌هایی را که با برنامه شما در ارتباط خواهند بود شناسایی کرده و مجوز موردنیاز برای هر کدام را تعیین کنید.
پیاده‌سازی مکانیزم Role Based تا اندازه‌ای پیچیده‌تر از code Access است، در قدم اول باید از روشی جهت Authentication کاربر استفاده کنیم. برای این منظور روش‌های مختلفی وجود دارد که در اینجا وارد جزییات آن‌ها نمی‌شویم و فقط به ذکر اسامی آن‌ها اکتفا می‌کنیم:
،windows authentication ،iis authentication ،passport authentication،forms based authentication
پس از authentication قدم بعدی authorization است که طی آن دسترسی کاربری که هویت آن به اثبات رسیده است، به منابع مختلف کنترل می‌شود که آیا این کاربر اجازه دسترسی به این منابع را دارد یا نه Role Based Security . در این قسمت به‌صورت مشخص وارد برنامه می‌شود. در NET Framework. به user اصطلاحاً identity می‌گویند و group اصطلاحاً role نامیده می‌شود. در این بین چیزی تحت عنوان Principal هم وجود دارد که یک identigy و role مربوط به آن را نمایش می‌دهد. جهت پیاده‌سازی Role Based Security ضروری‌است به صورت دقیق‌تر با این دو شیء ‌آشنا شویم. این اشیاء عبارتند از: identity ،Principal

Identity
همان‌طور که اشاره شد، identity نشانگر یک کاربر در سیستم می‌باشد. دو کلاس Generic Identity و Windows Identity، دو نوع خاص از identity را پیاده‌سازی می‌کنند. همچنین رابطی تحت عنوان IIdentity وجود دارد که با استفاده از آن می‌توانیم identityهای خاص را که با فیلدهای خاصی موردنیاز برنامه ما می‌باشد، تعریف کنیم.
Principa
این شیء، شی‌ء اساسی مکانیزم Role Based Security می‌باشد. یک شی Principal کاربر و نقش‌های مربوط به آن را در خود دارد و همانند identity دو کلاس با نام‌های windows Principal و Generic Principal و یک رابط با نام IPrincipal جهت استفاده از شی Principal درNET. وجود دارد. نکته مهمی که باید به‌خاطر داشته باشید این است که در هر جای برنامه که شی Principal موردنیاز باشد، تابع Staticای با نام Current Principal در کلاس thread را فراخوانی کنید. با استفاده از Role Based Security قصد داریم عضویت یک کاربر در یک نقش خاص را کنترل کنیم و یا با توجه به مشخصات خاصی که یک کاربر دارد، تصمیم خاصی را بگیریم. در ادامه موضوع را با مثالی تشریح می‌کنیم. (توجه داشته باشید که Authentication انجام شده است و در مرحله Authorization می‌باشیم). برای این‌کار یک شی identity به صورت زیر درست می‌کنیم:

Dim NIdentity As WindowsIdentity = WindowsIdentity.GetCurrent()

تابع GetCurrent اطلاعات کاربری را که در حال حاضر وارد سیستم شده است در شی NIdentity پر می‌کند. حال در این مرحله با استفاده از همین شی و propertyهایی که دارد، تصمیمات امنیتی خاصی را می‌توانیم بگیریم، ولی چنانچه بررسی عضویت در نقش‌ها مورد نیاز باشد، شی Principal به صورت زیر درست می‌کنیم:
(Dim NPrincipal As New WindowsPrincipal (NIdentity
همان‌طور که ملاحظه می‌کنید، برای ایجاد شی Principal شی‌ء identity مربوط به آن را به سازنده windows principal می‌دهیم. پس از ساختن دو شیء اشاره شده برای اعمال تصمیمات امنیتی در برنامه، چهار مدل یا روش وجود دارد که با توجه به نیاز خود می‌توانیم از یک و یا ترکیبی از آن‌ها استفاده کنیم. این روش‌ را می‌توانید در کادر ضمیمه ببینید.
طراحی ساختار امنیتی یک برنامه، نیازمند آشنایی دقیق با امکاناتی است که NET Framwork. در اختیار شما قرار می‌دهد. در اینجا فقط مختصری به دو مکانیزم جدید امنیتی که در NET. قرار داده شده، اشاره شد. لذا بدیهی است جهت طراحی ساختار امنیتی به نحو مطلوب، آشنایی با سایر امکانات امنیتی NET. ضروری‌است. روش های اعمال تصمیمات امنیتی در برنامه
1- Configurative Security Check
در این مدل از فایل‌های config. جهت اعمال تصمیمات امنیتی استفاده می‌کنیم. به عنوان مثال فرض کنید در سیستم وب‌ شما پوشه خاصی وجود دارد که فقط کاربرانی که عضو نقش Administrator و یا Developer هستند می‌توانند فایل‌های (فرم‌های) درون آن را ببینند. برای این‌کار کافی است فایلی تحت عنوان Web.config در آن پوشه درست کنید و کد زیر را در آن بنویسید:

< location path=" SampelDirectory">
<system.web>
<authorization>
<allow roles="Administrators,Developers"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
2- Programmatic Security Checks در این مدل به صورت برنامه‌نویسی تصمیمات امنیتی لازم را می‌گیریم. به عنوان مثال چنانچه کاربری که کد را اجرا می‌کند عضو نقش Manager باشد، و نام وی Jack باشد این خط کد اجرا خواهد شد. درغیراین‌صورت یک exception امنیتی در برنامه ایجاد می‌شود.
3- Declarative Security Checks
این مدل شبیه مدل Declarative در Code Access Security می‌باشد که قبلاً توضیح داده شد. تنها تفاوت موجود این است که این‌بار تصمیم امنیتی براساس نقش‌ها گرفته می‌شود. به عنوان مثال تکه کد زیر قبل از تعریف یک تابع مشخص می‌کند که فراخواننده این تابع باید دارای نقش Manager و نام Jack باشد.

جهت بررسی این که فقط کاربران عضو گروه Public به کد خاصی دسترسی پیدا کنند، کدی به صورت زیر می‌نویسیم:

if( Thread.CurrentPrincipal. IsInRole( "Public" ) )
‘Allow access
else
‘Deny access
3 Imperative Security Checks این مدل شبیه‌ مدل قبلی است. فقط تفاوت اندکی در نحوه تصمیم‌گیری دارد. جهت روشن شدن مطلب به مثال زیر توجه کنید:
Dim
UsrName As String = "Jack"
Dim UsrRole
As
String = "Manager"
Dim UsrPrincipalPermission As
New PrincipalPermission(UsrName,UsrRole)
در اینجا یک شیPrincipal Permission با نام Usr Principal Permission تعریف شده است. در ادامه هرجایی از برنامه که در محدوده این شیء قرار دارد، به صورت زیر می‌توانیم درخواست کنیم که فراخواننده کد این Permission را داشته باشد:

User Principal Permission. Demand()
منابع:
1- MSDN
2- NET Framework Security By: Surbhi Malhotra.
بر گرفته شده از ماهنامه شبکه با کمی تغییرات " – شماره 55 "

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

اجرا شده توسط: همیار وردپرس