EF Code First #12
- بله. دسترسی به خاصیت Local داخل لایه سرویس صورت گرفته و کپسوله شده. به همین جهت امضای متدی که ارائه شده به هر ORM دیگری نیز قابل انتقال است. فقط در آنجا یک تبدیل لیست به ObservableCollection را در پیاده سازی داخلی لایه سرویس خود خواهید داشت. اما استفاده کننده نهایی فقط با اینترفیس و قراردادهای تعریف شده در آن هست که کار میکند و کاری به جزئیات پیاده سازی لایه سرویس شما ندارد.
به همین جهت است که در اینجا کار با اینترفیسها و قراردادها ترویج شده؛ تا جزئیات پیاده سازی لایه سرویس از دید استفاده کننده مخفی باقی بماند.
EF Code First #12
- ذکر یک متد در اینترفیس (یک قرار داد) به جهت امکان استفاده از آن است. شما نهایتا با متدهای تعریف شده در طراحی IUnitOfWork در لایه سرویس قرار است کار کنید نه مستقیما با کلاس مشتق شده از DbContext.
زمانیکه مینویسید:
public class MyContext : DbContext, IUnitOfWork
MyContext به صورت خودکار امکان دسترسی به متد SaveChanges موجود در DbContext را پیدا میکند. کتابخانه StructureMap میتونه زمانیکه نیازی به یک وهله پیاده ساز IUnitOfWork بود، از MyContext استفاده کنه. همچنین چون الان SaveChanges با امضایی که در اینترفیس IUnitOfWork وجود دارد در کلاس MyContext هم قابل دسترسی است، نیازی به پیاده سازی مجدد آن نیست.
روش سوم: DTO (Data transfer objects)
در قسمتهای قبلی دو روش از روشهای موجود جهت تبادل دادهها بین لایهها، ذکر گردید و علاوه بر این، مزایا و معایب هر کدام از آنها نیز ذکر شد. در این قسمت دو روش دیگر، به همراه مزایا و معایب آنها برشمرده میشود. لازم به ذکر است هر کدام از این روشها میتواند با توجه به شرایط موجود و نظر طراح نرم افزار، دارای تغییراتی جهت رسیدن به یکسری اهداف و فاکتورها در نرم افزار باشد.
در این روش ما سعی میکنیم طراحی کلاسها را به اصطلاح مسطح ( flatten) کنیم تا بر مشکل double loop که در قسمت قبل بحث کردیم غلبه کنیم. در کد ذیل مشاهده میکنید که چگونه کلاس CusomerDTO از CustomerEntity ، مشتق میشود و کلاس Address را با CustomerEntity ادغام میکند؛ تا برای افزایش سرعت لود و نمایش دادهها، یک کلاس de-normalized شده ایجاد نماید.
public class CustomerDTO : CustomerEntity { public AddressEntity _Address = new AddressEntity(); }
در کد ذیل میتوانید مشاهده کنید که چگونه با استفاده از فقط یک loop یک کلاس de-normalized شده را پر میکنیم.
foreach (DataRow o1 in oCustomers.Tables[0].Rows) { CustomerDTO o = new CustomerDTO(); o.CustomerCode = o1[0].ToString(); o.CustomerName = o1[1].ToString(); o._Address.Address1 = o1[2].ToString(); o._Address.Address2 = o1[3].ToString(); obj.Add(o); }
UI هم به راحتی میتواند DTO را فراخوانی کرده و دیتا را دریافت کند.
مزایا و معایب روش DTO
یکی از
بزرگترین مزایای این روش سرعت زیاد در بارگذاری اطلاعات، به دلیل استفاده کردن از ساختار de-normalized میباشد. اما همین مسئله خود یک عیب محسوب میشود؛ به این دلیل که اصول شئ گرایی را نقض میکند.
روش چهارم: Hybrid approach (Entity + DTO)
از یک طرف کلاسهای Entity که دنیای واقعی را مدل خواهند کرد و همچنین اصول شئ گرایی را رعایت میکنند و از یک طرف دیگر DTO نیز یک ساختار flatten را برای رسیدن به اهداف کارآیی دنبال خواهند کرد. خوب، به نظر میرسد که بهترین کار استفاده از هر دو روش و مزایای آن روشها باشد.
زمانیکه سیستم، اهدافی مانند انجام اعمال CRUD را دنبال میکند و شما میخواهید مطمئن شوید که اطلاعات، دارای integrity میباشند و یا اینکه میخواهید این ساختار را مستقیما به کاربر نهایی ارائه دهید، استفاده کردن از روش (Entity) به عنوان یک روش normalized میتواند بهترین روش باشد. اما اگر میخواهید حجم بزرگی از دیتا را نمایش دهید، مانند گزارشات طولانی، بنابراین استفاده از روش DTO با توجه به اینکه یک روش de-normalized به شمار میرود بهترین روش میباشد.
کدام روش بهتر است؟
Non-uniform : این روش برای حالتی است که متدهای مربوط به data access تغییرات زیادی را تجربه نخواهند کرد. به عبارت دیگر، اگر پروژهی شما در آینده دیتابیسهای مختلفی را مبتنی بر تکنولوژیهای متفاوت، لازم نیست پشتیبانی کند، این روش میتواند بهترین روش باشد.Uniform : Entity, DTO, or hybrid : اگر امکان دارد که پروژهی شما با انواع مختلف دیتابیسها مانند Oracle و Postgres ارتباط برقرار کند، استفاده کردن از این روش پیشنهاد میشود.
نمونهی این نکته را پیشتر با Structure Map ملاحظه کرده بودید. پیاده سازی آن با امکانات توکار تزریق وابستگیهای NET Core. یا بر اساس روش Factory است که در نکتهی قبل ملاحظه میکنید و یا اگر از یک اینترفیس چندین پیاده سازی در برنامه وجود داشته باشند و ارتباطات آنها در ابتدای کار برنامه به سیستم توکار تزریق وابستگیهای NET Core. معرفی شده باشند، فقط کافی است یک <IEnumerable<IMultiple را به سازندهی کلاس سرویس استفاده کننده تزریق کنیم:
private readonly IEnumerable<IMultiple> _services; public HomeController (IEnumerable<IMultiple> services) { _services = services; }
مرحلهی بعد، تشخیص و یا انتخاب یک پیاده سازی خاص است. الان لیستی از وهلههای تزریق شده را در اختیار داریم؛ اما میخواهیم فقط از یکی از آنها استفاده کنیم:
الف) انتخاب سرویس مدنظر بر اساس نوع کلاسی خاص
var serviceA = services.First(o => o.GetType() == typeof(ImplementationOne));
این روشی است که برای مثال در Structure Map هم استفاده میشود (تحت عنوان named instances). یک خاصیت Name را به اینترفیسی که چندین پیاده سازی دارد، اضافه کنید. سپس بر اساس این Name کوئری بگیرید:
var serviceB = services.First(o => o.Name.Equals("MyClassName"));
چرا LINQ؟
اجزای سازندهی LINQ
- Elements عناصر
- Sequences توالیها
int[] fibonacci = {0, 1, 1, 2, 3, 5};
int[] fibonacci = { 0, 1, 1, 2, 3, 5 }; int numberOfElements = fibonacci.Count(); Console.WriteLine($"{numberOfElements}"); IEnumerable<int> distinictNumbers = fibonacci.Distinct(); Console.WriteLine("Elements in output sequence:"); foreach (var number in distinictNumbers) { Console.WriteLine(number); }
6 Elements in output sequence: 0 1 2 3 5
مفهوم Deffer Execution ( اجرای به تاخیر افتاده )
int[] fibonacci = { 0, 1, 1, 2, 3, 5 }; // ایجاد پرس و جو IEnumerable<int> numbersGreaterThanTwoQuery = fibonacci.Where(x => x > 2); // در این مرحله پرس و جو ایجاد شده ولی هنوز اجرا نشده است // تغییر عنصر اول توالی fibonacci[0] = 99; // حرکت بر روی عناصر توالی باعث اجرای پرس و جو میشود foreach (var number in numbersGreaterThanTwoQuery) { Console.WriteLine(number); }
99 3 5
int[] fibonacci = { 0, 1, 1, 2, 3, 5 }; // ساخت پرس و جو IEnumerable<int> numbersGreaterThanTwoQuery = fibonacci.Where(x => x > 2) .ToArray(); // در این مرحله به خاطر عملگر استفاده شده پرس و جو اجرا میشود // تغییر اولین عنصر توالی fibonacci[0] = 99; // حرکت بر روی نتیجه foreach (var number in numbersGreaterThanTwoQuery) { Console.WriteLine(number); }
3 5
مروری بر کاربردهای Action و Func - قسمت اول
یک نمونه از طراحیهای اخیر تیم دات نت رو میشه در WebGrid دید. در این طراحی برای نمونه جهت دریافت فرمول فرمت کردن مقدار یک cell، از Func استفاده کردن. میشد این رو با اینترفیس هم نوشت (چون قرار است کاری به خارج از کلاس محول شود و هر بار اطلاعاتی به آن ارسال و نتیجهای جدید اخذ گردد؛ پیاده سازی آن با شما، نتیجه را فقط در اختیار WebGrid ما قرار دهید). اما جدا استفاده از آن تبدیل میشد به عذاب برای کاربر که به نحو زیبایی با Func و امکانات جدید زبان حل شده.
مدیریت سفارشی سطوح دسترسی کاربران در MVC
آشنایی با NHibernate - قسمت هشتم
روش صحیح پیاده سازی مورد نظر شما استفاده از الگوی unit of work است
این الگو یک سطح بالاتر از الگوی مخزن قرار میگیرد
اگر میخواهید با نحوهی پیاده سازی آن آشنا شوید به این پروژه مراجعه کنید
http://efrepository.codeplex.com/
هر چند برای EF نوشته شده ولی از دیدگاه طراحی اینترفیس و روابط نهایی برای تمام ORM های دیگر هم صادق است و فرقی نمیکند
واژه XSS مخفف Cross-site scripting، نوعی از آسیب پذیریست که در برنامههای تحت وب نمود پیدا میکند. به طور کلی و خلاصه، این آسیب پذیری به فرد نفوذ کننده اجازه تزریق اسکریپتهایی را به صفحات وب، میدهد که در سمت کاربر اجرا میشوند ( Client Side scripts ) . در نهایت این اسکریپتها توسط سایر افرادی که از صفحات مورد هدف قرار گرفته بازدید میکنند اجرا خواهد شد.
هدف از این نوع حمله :
بدست آوردن اطلاعات کوکیها و سشنهای کاربران ( مرتبط با آدرسی که صفحه آلوده شده در آن قرار دارد ) است. سپس فرد نفوذ کننده متناسب با اطلاعات بدست آمده میتواند به اکانت شخصی کاربران مورد هدف قرار گرفته، نفوذ کرده و از اطلاعات شخصی آنها سوء استفاده کند .
به صورت کلی دو طبقه بندی برای انواع حملات Cross-site scripting وجود دارند.
حملات XSS ذخیره سازی شده ( Stored XSS Attacks ) :
در این نوع ، کدهای مخرب تزریق شده، در سرور سایت قربانی ذخیره میشوند. محل ذخیره سازی میتواند دیتابیس سایت یا هر جای دیگری که دادهها توسط سایت یا برنامه تحت وب بازیابی میشوند و نمایش داده میشوند باشد. اما اینکه چگونه کدهای مخرب در منابع یاد شده ذخیره میشوند؟
فرض کنید در سایت جاری آسیب پذیری مذکور وجود دارد. راههای ارسال دادهها به این سایت چیست؟ نویسندگان میتوانند مطلب ارسال کنند و کاربران میتوانند نظر دهند. حال اگر در یکی از این دو بخش بررسیهای لازم جهت مقابله با این آسیب پذیری وجود نداشته باشد و نوشتههای کاربران که میتواند شامل کدهای مخرب باشد مستقیما در دیتابیس ذخیره شده و بدون هیچ اعتبار سنجی نمایش داده شود چه اتفاقی رخ خواهد داد؟ مسلما با بازدید صفحه آلوده شده، کدهای مخرب بر روی مرورگر شما اجرا و کوکیهای سایت جاری که متعلق به شما هستند برای هکر ارسال میشود و ...
حملات XSS منعکس شده ( Reflected XSS Attacks ) :
در این نوع از حمله، هیچ نوع کد مخربی در منابع ذخیره سازی وبسایت یا اپلیکیشن تحت وب توسط فرد مهاجم ذخیره نمیشود ! بلکه از ضعف امنیتی بخشهایی همچون بخش جستجو وب سایت، بخشهای نمایش پیغام خطا و ... استفاده میشود ... اما به چه صورت؟
در بسیاری از سایتها، انجمنها و سیستمهای سازمانی تحت وب، مشاهده میشود که مثلا در بخش جستجو، یک فیلد برای وارد کردن عبارت جستجو وجود دارد. پس از وارد کردن عبارت جستجو و submit فرم، علاوه بر نمایش نتایج جستجو، عبارت جستجو شده نیز به نمایش گذاشته میشود و بعضا در بسیاری از سیستمها این عبارت قبل از نمایش اعتبار سنجی نمیشود که آیا شامل کدهای مخرب میباشد یا خیر. همین امر سبب میشود تا اگر عبارت جستجو شامل کدهای مخرب باشد، آنها به همراه نتیجهی جستجو اجرا شوند.
اما این موضوع چگونه مورد سوء استفاده قرار خواهد گرفت؟ مگر نه اینکه این عبارت ذخیره نمیشود پس با توضیحات فوق، کد فقط بر روی سیستم مهاجم که کد جستجو را ایجاد میکند اجرا میشود، درست است؟ بله درست است ولی به نقطه ضعف زیر توجه کنید ؟
www.test.com/search?q=PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpOzwvc2NyaXB0Pg==
این آدرس حاصل submit شدن فرم جستجو وبسایت test (نام وبسایت واقعی نیست و برای مثال است ) و ارجاع به صفحه نتایج جستجو میباشد. در واقع این لینک برای جستجوی یک کلمه یا عبارت توسط این وبسایت تولید شده و از هر کجا به این لینک مراجعه کنید عبارت مورد نظر مورد جستجو واقع خواهد شد. در واقع عبارت جستجو به صورت Base64 به عنوان یک query String به وبسایت ارسال میشود؛ علاوه بر نمایش نتایج، عبارت جستجو شده نیز به کاربر نشان داده شده و اگر آسیب پذیری مورد بحث وجود داشته باشد و عبارت شامل کدهای مخرب باشد، کدهای مخرب بر روی مرورگر فردی که این لینک را باز کرده اجرا خواهد شد!
در این صورت کافیست فرد مهاجم لینک مخرب را به هر شکلی به فرد مورد هدف بدهد ( مثلا ایمیل و ... ). حال در صورتیکه فرد لینک را باز کند (با توجه به اینکه لینک مربوط به یک سایت معروف است و عدم آگاهی کاربر از آسیب پذیری موجود در لینک، باعث باز کردن لینک توسط کاربر میشود)، کدها بر روی مرورگرش اجرا شده و کوکیهای سایت مذکور برای مهاجم ارسال خواهد شد ... به این نوع حمله XSS ، نوع انعکاسی میگویند که کاملا از توضیحات فوق الذکر، دلیل این نامگذاری مشخص میباشد.
اهمیت مقابله با این حمله :
برای نمونه این نوع باگ حتی تا سال گذشته در سرویس ایمیل یاهو وجود داشت. به شکلی که یکی از افراد انجمن hackforums به صورت Private این باگ را به عنوان Yahoo 0-Day XSS Exploit در محیط زیر زمینی و بازار سیاه هکرها به مبلغ چند صد هزار دلار به فروش میرساند. کاربران مورد هدف کافی بود تا فقط یک ایمیل دریافتی از هکر را باز کنند تا کوکیهای سایت یاهو برای هکر ارسال شده و دسترسی ایمیلهای فرد قربانی برای هکر فراهم شود ... ( در حال حاظر این باگ در یاهو وجو ندارد ).
چگونگی جلوگیری از این آسیب پذیری
در این سری از مقالات کدهای پیرامون سرفصلها و مثالها با ASP.net تحت فریم ورک MVC و به زبان C# خواهند بود. هر چند کلیات مقابله با آسیب پذیری هایی از این دست در تمامی زبانها و تکنولوژیهای تحت وب یکسان میباشند.
خوشبختانه کتابخانهای قدرتمند برای مقابله با حمله مورد بحث وجود دارد با نام AntiXSS که میتوانید آخرین نسخه آن را با فرمان زیر از طریق nugget به پروژه خود اضافه کنید. البته ذکر این نکته حائز اهمیت است که Asp.net و فریم ورک MVC به صورت توکار تا حدودی از بروز این حملات جلوگیری میکند. برای مثال به این صورت که در View ها شما تا زمانی که از MvcHtmlString استفاده نکنید تمامی محتوای مورد نظر برای نمایش به صورت Encode شده رندر میشوند. این داستان برای Url ها هم که به صورت پیش فرض encode میشوند صدق میکند. ولی گاها وقتی شما برای ورود اطلاعات مثلا از یک ادیتور WYSWYG استفاده میکنید و نیاز دارید دادهها را بدون encoding رندر کنید. آنگاه به ناچار مجاب بر اعمال یک سری سیاستهای خاصتر بر روی داده مورد نظر برای رندر میشوید و نمیتوانید از encoding توکار فوق الذکر استفاده کنید. آنگاه این کتابخانه در اعمال سیاستهای جلوگیری از بروز این آسیب پذیری میتواند برای شما مفید واقع شود.
PM> Install-Package AntiXSS
… var reviewContent = model.UserReview; reviewContent = Microsoft.Security.Application.Encoder.HtmlEncode(review); …
امیدوارم در اولین بخش از این سری مقالات، به صورت خلاصه مطالب مهمی که باعث ایجاد فهم کلی در رابطه با حملات Xss وجود دارد، برای دوستان روشن شده و پیش زمینه فکری برای مقابله با این دست از حملات برایتان به وجود آمده باشد.