رابطه-استفاده-از-UserName-و-PassWord-با-SSL-و-Certificate-در-WCF-Reviewed by کارشناسان.نت on April 22Rating:5

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

1 - کاربران عضو شبکه محلی شما که عضو Domain شبکه شما می باشند و اطلاعات انها در ActiveDirectory ذخیره شده است .

نمونه کد عملیات Authenticate به صورت زیر می باشد :

var nc = new NetworkCredential(UserName, PassWord, Domain);

var client = new AppsService.SrvTestClient();

client.ChannelFactory.Credentials.Windows.ClientCredential = nc;

client.DoWork();

  2 - کاربران سیستمی , که به شبکه محلی شما دسترسی ندارند و تنها از طریق اینترنت می توانند از وبسرویس شما استفاده کنند , اطلاعات این نوع کاربران معمولا در یک دیتابیس مثلا از نوع Sql ذخیره می باشد .

نمونه کد عملیات Authenticate به صورت زیر می باشد :

var client = new myService.SrvTestClient();

 client.ClientCredentials.UserName.UserName = "UserName";

 client.ClientCredentials.UserName.Password = "PassWord";

client.DoWork();

 در هر دو صورت , سیاست WCF بر ارسال نام کاربری و رمز عبور از Client به سرور به صورت رمز شده می باشد , این رمز شدن نیازمندی هایی دارد :

برای کاربران نوع اول , که عضو ActiveDirectory شبکه محلی شما می باشند , دست شما بسیار باز است , در حالت اول شما می توانید از SSL برای رمز کردن نام کاربری و رمز عبور استفاده کنید.  برای استفاده از SSL , اجباری به خرید SSL معتبر نیست و خودتان می توانید از طریق IIS سرورتان یک SSL ایجاد کنید .

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

شما می توانید خودتان با ابزار ویژوال استدیو , Self Signed Certificate بسازید برای توضیحات بیشتر می توانید به مقالات

 A simple WCF service with username password authentication: the things they don’t tell you

و

Securing a WCF service with Username and Password using Message security and the Channel Factory pattern

 مراجعه بفرمایید , اما برخلاف SSL , شما باید بر روی تک تک Client ها , Certificate را نصب کنید .

و بالاخره در حالت سوم اگر SSL و Certificate در اختیار شما نیست یا به هر علتی تمایل به ارسال رمز شده نام کاربری و رمز عبور ندارید , شما می توانید از طریق تنظیمات WebConfig به شکل زیر , عملیات Authenticate را بدون SSL و Certificate انجام دهید .

هرچند باید متوجه باشید که این بر خلاف سیاست WCF می باشد  و توصیه شده مایکروسافت نمی باشد .

<security mode="TransportCredentialOnly">

 <transport clientCredentialType="Ntlm"/>

 </security>

 در تکه تنظیمات بالا , اگر ورژن جدید تر ActiveDirectory را دارید , می توانید به جای NTLM از Windows استفاده کنید , همچین اگر مایل به امنیت بیشتر می باشید می توانید با تکه تنظیم زیر , نام کاربری و رمز عبور را پیش از ارسال به سرور Hash نمایید .

<system.webServer>

 <security>

 <authentication>

 <anonymousAuthentication enabled="false" />

 <digestAuthentication enabled="true"/>

 </authentication>

 </security>

 </system.webServer>

اما در کاربران نوع دوم یعنی کاربران سیستمی , که به شبکه محلی شما دسترسی ندارند و تنها از طریق اینترنت می توانند از وبسرویس شما استفاده کنند , شرایط مقداری متفاوت می باشد. در این نوع کاربران شما برای ارسال نام کاربری و رمز عبور به سرور حتما" باید انها را رمز کنید .

بنابراین شما حتما" باید از SSL یا Certificate استفاده نمایید . در این نوع کاربران , این یک سیاست نیست , بلکه اجبار می باشد .

اما با این وجود باز هم راه هایی برای فرار از این محدودیت (هر چند ارسال نام کاربری و رمز عبور بدون رمز شدن و به صورت متن شفاف , از لحاظ امنیت یک اشتباه به تمام معنا است , اما گاهی شما بنابر دلایل شخصی و محدودیت های فنی نیاز به این عمل دارید) وجود دارد , در ادامه تعدادی از این راه ها را توضیح خواهم داد :

 راه حل اول: استفاده از ClearUsernameBinding 

در این روش یک Binding جدید ایجاد شده است که نیازی به رمز شدن با SSL یا Certificate ندارد.

مزیت این روش :

1 - سادگی 

مشکل این روش :

1 -  نیاز به استفاده از ClearUsernameBinding به صورت یک DLL در Client , در نتیجه کاربران شما به کاربران دات نت محدود می شوند و اگر نیاز به استفاده از سرویس شما در یک پلتفرم دیگر مثل جاوا باشد , سرویس شما بدون ان DLL دات نتی اجرا نخواهد شد .

راه حل دوم : Portable Certificate

در این روش , نیازی به نصب Certificate بر روی سرور و Client ها نمی باشد , بلکه تنها نیاز است تا Certificate در سرور بر روی دیسک کپی شود و در سمت client نیز در کنار برنامه کاربر کپی شود و یا در مسیر خاصی قرار گیرد .

مزایای این روش :

1 - امن بودن نسبت به روش اول , چون حداقل نام کاربری و رمز عبور به صورت تکست شفاف روی سیم قرار نمی گیرند .

2 -  عدم نیاز به نصب Certificate بر روی سرور و Client و در نتیجه عدم نیاز به دسترسی  Admin .

مشکلات این روش :

1 -  امنیت پایین , چون اگر Certificate در محل ناامنی قرار گیرد , می تواند مورد دستبرد هکرها قرار گیرد .

2 - نیاز به یک DLL دات نتی در سمت Client ها , در نتیجه کاربران شما به کاربران دات نت محدود می شوند و اگر نیاز به استفاده از سرویس شما در یک پلتفرم دیگر مثل جاوا باشد , سرویس شما بدون ان DLL دات نتی اجرا نخواهد شد .

راه حل سوم :

در تمام روش های بالا نیاز به یک dll در سمت Client می باشد , حال انکه شما می توانید برای متد های وبسرویس خود یک پارامتر جدید مثلا به اسم Key تعریف کنید که شامل یک PassWord بعلاوه Time می باشد و زمان انقضا هر Request مثلا 10 ثانیه می باشد, به ازای هر درخواست این پارامتر ثابت به سرور ارسال می شود و این PassWord + Time را با یک الگورتیم توافقی با Client رمز کنید و به جای استفاده از Dll در Client ها از این الگوریتم در پلتفرم های مختلف در سمت Client استفاده کنید .

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

در پایان مجددا تاکید می کنم در مقایسه با SSL و Certificate هیچکدام از این روش ها امن نیستند .