آموزش اعتبار سنجی در Windows Communication Foundation

اعتبار سنجی

بعد از اعتبار سنجی هایی که در MVC سی شارپ  WPF   PHP انجام دادیم این بار به سراغ WCF و یا همان Windows Communication Foundation  رفتیم ، اعتبار سنجی در WCF کاملا متفاوت است ابتدا باید از طریق آموزش ساخت WCF یک پروژه جدید ایجاد کنید تا بتوانیم اعتبار سنجی را روی آن پیاده سازی کنیم.دقت داشته باشید اگر اعتبار سنجی برای این سرویس‌ها در نظر گرفته نشود به راحتی می‌توان با در اختیار داشتن آدرس مورد نظر تمام سرویس های  برنامه را فراخوانی کرد و اگر رمزگذاری اطلاعات بر روی سرویس‌ها فعال نشده باشد می‌توان تمام اطلاعات این سرویس‌ها را به راحتی به دست آورد. کمترین تلاش در این مرحله برای پیاده سازی امنیت این است که برای فراخوانی هر سرویس حداقل یک شناسه و رمز عبور چک شود و فقط در صورتی که فراخوانی سرویس همراه با شناسه و رمز عبور درست بود اطلاعات در اختیار کلاینت قرار گیرد. قصد داریم طی یک مثال این مورد را بررسی کنیم.

ابتدا یک پروژه با دو Console Application  با نام های  Service و Client ایجاد کنید. سپس در پروژه Service یک سرویس به نام BookService ایجاد کنید و کد‌های زیر را در آن کپی نمایید:
Contract مربوطه به صورت زیر است:


[ServiceContract]
public interface IBookService
    {
        [OperationContract]
        int GetCountOfBook();
    }

 

کد‌های مربوط به سرویس:


[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
   public class BookService : IBookService
   {
       public int GetCountOfBook()
       {
           return 10;
       }
   }

 

فایل Program در پروژه Service را باز نمایید و کد‌های زیر را که مربوط به hosting سرویس مورد نظر است در آن کپی کنید:


class Program
   {
       static void Main(string[] args)
       {
           ServiceHost host = new ServiceHost(typeof(BookService));
 
           var binding = new BasicHttpBinding();
            
           host.AddServiceEndpoint(typeof(IBookService), binding, "http://localhost/BookService");
           host.Open();
 
           Console.Write("BookService host");
 
           Console.ReadKey();
       }
   }

 

بر اساس کد‌های بالا، سرویس BookService در آدرس http://localhost/BookService هاست می‌شود.  نوع Binding نیز BasicHttpBinding انتخاب شده است.
حال نوبت به پیاده سازی سمت کلاینت می‌رسد. فایل Program سمت کلاینت را باز کرده و کد‌های زیر را نیز در آن کپی نمایید:


static void Main(string[] args)
{
    Thread.Sleep(2000);
    BasicHttpBinding binding = new BasicHttpBinding();
 
    ChannelFactory<IBookService> channel = new ChannelFactory<IBookService>(binding, new EndpointAddress("http://localhost/BookService"));
 
    Console.WriteLine("Count of book: {0}", channel.CreateChannel().GetCountOfBook());
 
    Console.ReadKey();
}

 

در کد‌های عملیات ساخت ChannelFactory برای برقراری اطلاعات با سرویس مورد نظر انجام شده است. پروژه را Build نمایید و سپس آن را اجرا کنید.
خروجی زیر مشاهده می‌شود:

اعتبار سنجی

تا اینجا هیچ گونه اعتبار سنجی انجام نشد. برای پیاده سازی اعتبار سنجی باید یک سری تنظیمات بر روی Binding و Hosting  سمت سرور و البته کلاینت بر قرار شود. فایل Program پروزه Service را باز نمایید و محتویات آن را به صورت زیر تغییر دهید:


static void Main(string[] args)
       {
           ServiceHost host = new ServiceHost(typeof(BookService));
 
           var binding = new BasicHttpBinding();
           binding.Security = new BasicHttpSecurity();
           binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
           binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
 
           host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
 
           host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNamePasswordValidator();               
 
           host.AddServiceEndpoint(typeof(IBookService), binding, "http://localhost/BookService");
           host.Open();
 
 
           Console.Write("BookService host");
 
           Console.ReadKey();
       }

 

تغییرات اعمال شده:
ابتدا نوع Security در Binding را به حالت TransportCredentialOnly تنظیم کردیم. در یک جمله هیچ گونه تضمینی برای صحت اطلاعات انتقالی در این حالت وجود ندارد و فقط یک اعتبار سنجی اولیه انجام خواهد شد. در نتیجه هنگام استفاده از این حالت باید با دقت عمل نمود و نباید فقط به پیاده سازی این حالت اکتفا کرد.( Encryption اطلاعات سرویس‌ها مورد بحث این پست نیست)
ClientCredentialType نیز باید به حالت Basic تنظیم شود. در WCF اعتبار سنجی به صورت پیش فرض در حالت Windows است (بعنی UserNamePasswordValidationMode برابر مقدار Windows است و اعتبار سنجی بر اساس کاربر انجام می‌شود) . این مورد باید به مقدار Custom تغییر یابد. در انتها نیز باید مدل اعتبار سنجی دلخواه خود را به صورت زیر پیاده سازی کنیم:
در پروژه سرویس یک کلاس به نام CustomUserNamePasswordValidator بسازید و کد‌های زیر را در آن کپی کنید:


public class CustomUserNamePasswordValidator : UserNamePasswordValidator
   {
       public override void Validate(string userName, string password)
       {
           if (userName != "Masoud" || password != "Pakdel")
               throw new SecurityException("Incorrect userName or password");
       }
   }

 

Validator مورد نظر از کلاسی abstract به نام UserNamePasswordValidator  ارث می‌برد، در نتیجه باید متد abstract به نام Validate را override نماید. در بدنه این متد شناسه و رمز عبور با یک مقدار پیش فرض چک می‌شوند و در صورت عدم درستی این پارارمترها یک استثنا پرتاب خواهد شد.

تغییرات مورد نیاز سمت کلاینت:
اگر در این حالت پروژه را اجرا نمایید از آن جا که از این به بعد، درخواست‌ها سمت سرور اعتبار سنجی می‌شوند در نتیجه با خطای زیر روبرو خواهید شد:

اعتبار سنجی

این خطا از آن جا ناشی می‌شود که تنظیمات کلاینت و سرور از نظر امنیتی با هم تناسب ندارد. در نتیجه باید تنظیمات Binding کلاینت و سرور یکی شود. برای این کار کد زیر را به فایل Program سمت کلاینت اضافه می‌کنیم:

 


static void Main(string[] args)
{
Thread.Sleep(2000);
BasicHttpBinding binding = new BasicHttpBinding();

binding.Security = new BasicHttpSecurity();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

ChannelFactory<IBookService> channel = new ChannelFactory<IBookService>(binding, new EndpointAddress("http://localhost/BookService"));

channel.Credentials.UserName.UserName = "WrongUserName";
channel.Credentials.UserName.Password = "WrongPassword";

Console.WriteLine("Count of book: {0}", channel.CreateChannel().GetCountOfBook());

Console.ReadKey();
}

توسط دستور زیر، مقدار شناسه و رمز عبور به درخواست اضافه می‌شود.


channel.Credentials.UserName.UserName = "WrongUserName";
channel.Credentials.UserName.Password = "WrongPassword";

در اینجا UserName و Password اشتباه مقدار دهی شده اند تا روش کار Validator مورد بررسی قرار گیرد. حال اگر پروژه را اجرا نمایید خواهید دید که در Validator مورد نظر، عملیات اعتبار سنجی به درستی انجام می‌شود:

اعتبار سنجی

 

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

مسعود شریفی پور

از سال 88 که با برنامه نویسی آشنا شدم خیلی علاقه مند بودم یک بستر آموزشی بسازم در فضای وب و به انتشار آموزش های در این زمینه بپردازم.حالا یک تیم داریم و با قدرت رو به جلو حرکت میکنیم.

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

    MeysamVB پاسخ

    سلام آقای شریفی.
    من بتازگی با وبسایت شما آشنا شدم.
    اگر بخوام پروژه هامو در سایتتون به فروش برسونم باید چیکار کنم؟آیا چنین امکانی وجود داره؟؟؟

      مسعود شریفی پاسخ

      Market.mspsoft.com

جشنواره فروش ویژه عید تا عید با تخفیف های باورنکردنی در ام اس پی سافتبزن بریم
+