OWASP’s Top 10 Risk List is an important tool for security engineers and compliance analysts. It describes the 10 worst security problems that are found in web and mobile applications today. But, on its own, it’s not much help to developers, so OWASP has come up with a list of 10 things that you can do as a developer to make sure that your code is safe and secure.
در مورد ادامه ...
موضوع و مطلب، برای نوشتن بسیار زیاد هستند؛ اما این خوانندههای یک وبلاگ و یا یک وب سایت هستند که میتوانند نقش مهمی را در جهت گیری انتشار مطالب آن ایفاء کنند. به همین جهت ... به چه نوع مطالبی بیشتر علاقمندید، یا بیشتر مایلید که چه نوع مباحثی، در این سایت یا سایتهای مشابه مطرح شوند؟
استفاده از pdfreport برای اولین بار
داخل آن یک پوشهی Samples هست که از برنامههای وب تا EF و دسکتاپ و غیره را پوشش میدهد.
مستندات آن در گروه PdfReport سایت ارائه شده و همچنین در راهنمای آن در سایت.
- نصب پایتون 2.5 یا 2.6 یا 2.7 که فعلا در سایت آن، نسخهی 2.7 در دسترس هست. توجه داشته باشید که هنوز برای نسخهی 3 پایتون پشتیبانی صورت نگرفته است.
- آخرین نسخهی sdk را هم میتوانید از این آدرس به صورت zip و یا از این آدرس به صورت tar دانلود کنید و در صورتیکه دوست دارید به سورس آن دسترسی داشته باشید یا اینکه از سورسهای مشارکت شده یا غیر رسمی استفاده کنید، از این صفحه آن را دریافت کنید.
(C:\Users\aym\Downloads\addon-sdk-1.17) C:\Users\aym\Downloads\addon-sdk-1.17\bin>
source bin/activate
bash bin/activate
(addon-sdk)~/mozilla/addon-sdk >
آغاز به کار
mkdir fxaddon cd fxaddon cfx init
* lib directory created * data directory created * test directory created * doc directory created * README.md written * package.json written * test/test-main.js written * lib/main.js written * doc/main.md written Your sample add-on is now ready for testing: try "cfx test" and then "cfx run". Have fun!"
{ "name": "fxaddon", "title": "fxaddon", "id": "jid1-QfyqpNby9lTlcQ", "description": "a basic add-on", "author": "", "license": "MPL 2.0", "version": "0.1" }
{ "name": "dotnettips", "title": ".net Tips Updater", "id": "jid1-QfyqpNby9lTlcQ", "description": "This extension keeps you updated on current activities on dotnettips.info", "author": "yeganehaym@gmail.com", "license": "MPL 2.0", "version": "0.1" }
var button= require('sdk/ui/button/action');
buttons.ActionButton({...});
var tgbutton = require('sdk/ui/button/toggle'); var panels = require("sdk/panel"); var self = require("sdk/self"); var button = tgbutton.ToggleButton({ id: "updaterui", label: ".Net Updater", icon: { "16": "./icon-16.png", "32": "./icon-32.png", "64": "./icon-64.png" }, onChange: handleChange }); var panel = panels.Panel({ contentURL: self.data.url("./popup.html"), onHide: handleHide }); function handleChange(state) { if (state.checked) { panel.show({ position: button }); } } function handleHide() { button.state('window', {checked: false}); }
tgbutton.ToggleButton
require('sdk/ui/button/toggle').ToggleButton
Context Menus
var contextMenu = require("sdk/context-menu"); var home = contextMenu.Item({ label: "صفحه اصلی", data: "https://www.dntips.ir/" }); var postsarchive = contextMenu.Item({ label: "مطالب سایت", data: "https://www.dntips.ir/postsarchive" }); var menuItem = contextMenu.Menu({ label: "Open .Net Tips", context: contextMenu.PageContext(), items: [home, postsarchive], image: self.data.url("icon-16.png"), contentScript: 'self.on("click", function (node, data) {' + ' window.location.href = data;' + '});' });
SelectorContext("img")
SelectorContext("img,a[href]")
var tabs = require("sdk/tabs"); var menuItem = contextMenu.Menu({ label: "Open .Net Tips", context: contextMenu.PageContext(), items: [home, postsarchive], image: self.data.url("icon-16.png"), contentScript: 'self.on("click", function (node, data) {' + ' self.postMessage(data);' + '});', onMessage: function (data) { tabs.open(data); } });
var Url="https://www.dntips.ir/search?term="; var searchMenu = contextMenu.Item({ label: "search for", context: [contextMenu.PredicateContext(checkText),contextMenu.SelectionContext()], image: self.data.url("icon-16.png"), contentScript: 'self.on("click", function () {' + ' var text = window.getSelection().toString();' + ' if (text.length > 20)' + ' text = text.substr(0, 20);' + ' self.postMessage(text);'+ '})', onMessage: function (data) { tabs.open(Url+data); } }); function checkText(data) { if(data.selectionText === null) return false; console.log('selectionText: ' + data.selectionText); //handle showing or hiding of menu items based on the text content. menuItemToggle(data.selectionText); return true; }; function menuItemToggle(text){ var searchText="جست و جو برای "; searchMenu.label=searchText+text; };
در قسمت آینده موارد بیشتری را در مورد افزونه نویسی در فایرفاکس بررسی خواهیم کرد و افزونه را تکمیل خواهیم کرد
پیش نیاز ها:
»Owin چیست
»تبدیل برنامههای کنسول ویندوز به سرویس ویندوز ان تی
برای شروع یک برنامه Console Application ایجاد کرده و اقدام به نصب پکیجهای زیر نمایید:
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost Install-Package TopShelf
حال یک کلاس Startup برای پیاده سازی Configurationهای مورد نیاز ایجاد میکنیم
در این قسمت میتوانید تنظیمات زیر را پیاده سازی نمایید:
»سیستم Routing؛
»تنظیم Dependency Resolver برای تزریق وابستگی کنترلرهای Web Api؛
»تنظیمات hubهای SignalR(در حال حاضر SignalR به صورت پیش فرض نیاز به Owin برای اجرا دارد)؛
»رجیستر کردن Owin Middlewareهای نوشته شده؛
»تغییر در Asp.Net PipeLine؛
»و...
public class Startup { public void Configuration(IAppBuilder appBuilder) { HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); appBuilder.UseWebApi(config); } }
در این مرحله یک کنترلر Api به صورت زیر به پروژه اضافه نمایید:
public class ValuesController : ApiController { public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } public string Get(int id) { return "value"; } public void Post([FromBody]string value) { } public void Put(int id, [FromBody]string value) { } }
public class ServiceHost { private IDisposable webApp; public static string BaseAddress { get { return "http://localhost:8000/"; } } public void Start() { webApp = WebApp.Start<Startup>(BaseAddress); } public void Stop() { webApp.Dispose(); } }
در مرحله آخر باید شروع و توقف سرویسها را تحت کنترل کلاس HostFactory کتابخانه TopShelf در آوریم. برای این کار کافیست کلاسی به نام ServiceHostFactory ایجاد کرده و کدهای زیر را در آن کپی نمایید:
public class ServiceHostFactory { public static void Run() { HostFactory.Run( config => { config.SetServiceName( "ApiServices" ); config.SetDisplayName( "Api Services ]" ); config.SetDescription( "No Description" ); config.RunAsLocalService(); config.Service<ServiceHost>( cfg => { cfg.ConstructUsing( builder => new ServiceHost() ); cfg.WhenStarted( service => service.Start() ); cfg.WhenStopped( service => service.Stop()); } ); } ); } }
با استفاده از متد ConstructUsing عملیات وهله سازی از سرویس انجام خواهد گرفت. در پایان نیز متد Start و Stop کلاس ServiceHost، به عنوان عملیات شروع و پایان سرویس ویندوز مورد نظر تعیین شد.
حال اگر در فایل Program پروژه، دستور زیر را فراخوانی کرده و برنامه را ایجاد کنید خروجی زیر قابل مشاهده است.
ServiceHostFactory.Run();
در حالیکه سرویس مورد نظر در حال اجراست، Browser را گشوده و آدرس http://localhost:8000/api/values/get را در AddressBar وارد کنید. خروجی زیر را مشاهده خواهید کرد:
آزمون واحد در دات نت
آشنایی با آزمایش واحد (unit testing) در دات نت قسمت دوم
آشنایی با آزمایش واحد (unit testing) در دات نت قسمت سوم
آشنایی با آزمایش واحد (unit testing) در دات نت قسمت چهارم
آشنایی با آزمایش واحد (unit testing) در دات نت قسمت پنجم
آشنایی با آزمایش واحد (unit testing) در دات نت قسمت ششم
آشنایی با mocking frameworks - قسمت اول
آشنایی با mocking frameworks - قسمت دوم
چگونه کد قابل تست بنویسیم - قسمت اول
چگونه کد قابل تست بنویسیم - قسمت دوم
- تولید خودکار آزمونهای واحد NUnit
- تهیه آزمون واحد جهت کار با محتوای فایلها
- آزمون واحد Entity Framework به کمک چارچوب تقلید
- استفاده از shim و stub برای mock کردن در آزمون واحد
- آزمون واحد در MVVM به کمک تزریق وابستگی
- بررسی میزان پوشش آزمونهای واحد به کمک برنامه PartCover
- قالبی برای ایجاد آزمونهای NUnit مخصوص ReSharper
- آشنایی با تست واحد و استفاده از کتابخانه Moq
- WatIn - Web Application Testing in .Net
- آموزش Coded UI Test #1
- آشنایی با Should Library
- آماده سازی زیرساخت تهیه Integration Tests برای ServiceLayer
مایکروسافت سه ابزار امنیتی رایگان جدید را جهت توسعه دهندگان وب ارائه داده است که فعلا در مرحله آزمایش به سر میبرند و قرار است این مجموعه به صورت جرئی از مجموعه power tools ویژوال استودیو 2010 ارائه شوند. این سه ابزار به شرح زیر هستند:
الف) CAT.NET 2.0 CTP
CAT.NET کاملا از صفر بازنویسی شده و از موتور جدیدی کمک میگیرد. نگارش CTP فعلی آن فقط از طریق خط فرمان قابل اجرا است.
دریافت
ب) WACA 1.0 CTP
نام این ابزار مخفف Web Application Configuration Analyzer است که جهت بررسی تنظیمات برنامههای وب شما، همچنین IIS و SQL Server بکار میرود و نقایص امنیتی آنها را گوشزد خواهد کرد.
دریافت
ج) WPL 1.0 CTP
نام این ابزار مخفف Web Protection Library است. این ابزار شبیه به یک فایروال جهت برنامههای وب شما در مقابل حملات XSS و SQL injection عمل میکند و بدون نیاز به تغییر کد (با کمک یک HTTP Module)، محافظت قابل توجهی را ارائه خواهد داد.
دریافت
بر اساس جستجوهایی که انجام دادهام، CHM پشتیبانی کاملی را از یونیکد انجام نمیدهد (مشکل جستجو و همچنین ایندکس کردن).
اما با ترفندی میتوان این مساله را حل کرد و آن هم تبدیل encoding فایلها به عربی است (windows-1256). در این حالت هم جستجو کار میکند و هم عنوان صفحات هنگام جستجو در لیست موارد یاد شده درست نمایش داده میشود و صفحه add to favorites نیز مشکلی در نمایش عنوانهای صفحهها نخواهد داشت. روش کار به شرح زیر است:
الف) encoding تمام فایلهای html خود را به صورت زیر تغییر دهید (از utf-8 به windows-1256):
<meta content="text/html; charset=Windows-1256" http-equiv="Content-Type">
using System.IO;
using System.Text;
public static void SaveAs1256(string fileName)
{
string content = File.ReadAllText(fileName);
File.WriteAllText(fileName, content, Encoding.GetEncoding("windows-1256"));
}
ج) اصلاح فایل hhp پروژه خود
فایل hhp مربوط به html help work shop را باز کنید. (همان فایل پروژه ساخت راهنما)
اگر مثال قبل را دنبال کرده باشید، محتوای فایل آن چیزی شبیه به خطوط زیر خواهد بود:
[OPTIONS]
Compatibility=1.1 or later
Compiled file=test.chm
Contents file=Table of Contents.hhc
Default Window=win1
Default topic=page1.html
Display compile progress=No
Full-text search=Yes
Index file=Index.hhk
Language=0x429 Farsi
Title=راهنمای یک
[WINDOWS]
win1=,"Table of Contents.hhc","Index.hhk","page1.html","page1.html",,,,,0x3420,,0x304e,,,,,,2,,0
[FILES]
page1.html
page2.html
[INFOTYPES]
به قسمت options چند سطر زیر را اضافه کنید: (زبان فارسی و فونت تاهومای عربی)
Default Font=Tahoma,8,178
Language=0x429 Farsi
محض نمونه، کل وبلاگ جاری را به یک فایل chm تبدیل کردهام که آنرا از آدرس زیر میتوانید دریافت نمائید:
دریافت فایل
برای آزمایش، یک عبارت فارسی را در آن جستجو نمائید.
پ.ن.
این راه حلی است که به نظر من رسیده و جواب داده. اگر شما با encoding های دیگر هم جواب گرفتهاید (مشکل جستجوی فارسی حل شده) لطفا پیغام بگذارید. با تشکر.
هم چنین در قسمت Add folders and core references تیک گزینهی Web Api را نیز فعال مینماییم.
حال احتیاج به نصب پکیج OData با استفاده از nuget package manager داریم. کافیست دستور زیر را در package manager console وارد نماییم.
Install-Package Microsoft.AspNet.Odata
این دستور آخرین ورژن Odata package را از nuget دانلود مینماید.
بعد از نصب شدن OData نیاز به اضافه کردن یک Model داریم. کلاسی را به نام Product در پوشهی Models میسازیم.
کلاس Product.cs حاوی فیلدهای زیر است.
namespace ProductService.Models { public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; } } }
پراپرتی Id، کلید این entity است و کلاینت میتواند کوئری را بر روی entity، به وسیلهی key بزند. برای مثال برای گرفتن Product با Id برابر 2، باید این url را ارسال نمود "(2)Products/"
پرواضح است که Id در Database به عنوان Primary key در نظر گرفته شده است.
حال احتیاج به نصب Entity Framework داریم که با ارسال دستور زیر از طریق nuget نصب خواهد شد
Install-Package EntityFramework
بعد از نصب کردن ef نیاز به اضافه کردن connection string در web config داریم.
<connectionStrings> <add name="ProductsContext" connectionString="Data Source=.; Initial Catalog=ProductsContext; Integrated Security=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" /> </connectionStrings>
الان میتوانیم کلاس ProductsContext را درون پوشهی Models ایجاد نماییم. محتویات آن را به صورت زیر وارد مینماییم
using System.Data.Entity; namespace ProductService.Models { public class ProductsContext : DbContext { public ProductsContext() : base("name=ProductsContext") { } public DbSet<Product> Products { get; set; } } }
درون Constructor کلاس ProductsContext، داریم name=ProductsContext که باید برابر name درون connection string باشد.
حال نیاز به کانفیگ OData داریم. درون پوشهی App_Start و کلاس WebApiConfig.cs محتویات زیر را جایگزین متد register نمایید:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Product>("Products"); config.MapODataServiceRoute( routeName: "ODataRoute", routePrefix: null, model: builder.GetEdmModel()); } }
این کد دو فرآیند زیر را انجام میدهد
1) ساخت Entity Data Model (EDM)
2) اضافه کردن route
EDM یک مدل انتزاعی از data است. EDM برای تولید سند metadata استفاده میشود. کلاس ODataModelBuilder برای ساخت EDM با استفاده از default naming convention میباشد که باعث کاهش کدها میشود. ضمنا کلاس MapODataServiceRoute برای ساخت OData v4 route میباشد. همانگونه که اطلاع دارید، تعریف route برای مدیریت کردن WebApi و چگونگی مسیریابی درخواستهای http میباشد.
اگر application شما احتیاج به چند OData endpoint داشته باشد، میتوانید برای هر کدام routeهای جدا و همچنین نام یکتایی را برای routeName و routePrefix آن در نظر بگیرید.
اضافه کردن OData Controller
یک Controller، کلاسی برای مدیریت کردن درخواستهای http میباشد. شما باید Controllerهای مجزایی را برای هر entity set در OData service خود بسازید. در این مقاله Controller مربوط به موجودیت Product را میسازیم.
در Solution Explorer با کلیک راست بر روی پوشهی Controller، کلاسی به نام ProducsController را میسازیم. دقت کنید نام آن حتما باید به Controller ختم شود.
در OData V3 میتوانیم Controller را با استفاده از Scaffolding بسازیم؛ ولی در V4 این ویژگی وجود ندارد!
محتویات زیر را در این کنترلر اضافه مینماییم:
using ProductService.Models; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Threading.Tasks; using System.Web.Http; using System.Web.OData; namespace ProductService.Controllers { public class ProductsController : ODataController { ProductsContext db = new ProductsContext(); private bool ProductExists(int key) { return db.Products.Any(p => p.Id == key); } protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } } }
این مرحلهی ابتدایی از پیاده سازی کنترلر میباشد و در قسمت بعد به پیاده سازی CRUD مربوط به آن میپردازیم.
Querying The Entity Set
این 2 متد را به کنترلر خود اضافه مینماییم
[EnableQuery] public IQueryable<Product> Get() { return db.Products; } [EnableQuery] public SingleResult<Product> Get([FromODataUri] int key) { IQueryable<Product> result = db.Products.Where(p => p.Id == key); return SingleResult.Create(result); }
ویژگی EnableQuery به معنای امکان Query زدن از سمت کلاینت به آن میباشد. FromODataUri نیز برای امکان پاس دادن پارامتر از طریق Uri است.
متد Get بدون پارامتر، قادر به برگرداندن تمامی Productها میباشد و متد Get با پارامتر، قادر به برگرداندن آن Product خاص با استفاده از unique Id است.
در صورت داشتن EnableQuery با استفاده از Query Option هایی مثل filter$ و sort$ و غیره از سمت کلاینت قادر به تغییر دادن کوئریهای خود هستیم.
Adding and Entity to Entity Set
برای اجازه دادن به کلاینت، جهت اضافه کردن یک Product به دیتابیس، متد Post زیر را اضافه مینماییم
public async Task<IHttpActionResult> Post(Product product) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Products.Add(product); await db.SaveChangesAsync(); return Created(product); }
Updation an Entity
OData از دو روش متفاوت برای Update کردن یک موجودیت استفاده مینماید.
1) Patch : امکان partial update برای موجودیت مربوطه را فراهم میسازد.
2) Put : موجودیت جدید را به صورت کامل جایگزین مینماید.
مشکل روش Put این است که کلاینت مجبور به ارسال تمامی فیلدهای مربوطه میباشد. حتی آن هایی که اساسا تغییری نکردهاند. بنابراین روش Patch ترجیح داده میشود.
در هر صورت ما به پیاده سازی هر دو روش میپردازیم:
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var entity = await db.Products.FindAsync(key); if (entity == null) { return NotFound(); } product.Patch(entity); try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!ProductExists(key)) { return NotFound(); } else { throw; } } return Updated(entity); } public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (key != update.Id) { return BadRequest(); } db.Entry(update).State = EntityState.Modified; try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!ProductExists(key)) { return NotFound(); } else { throw; } } return Updated(update); }
در قسمت Patch کنترلر از <Delta<T استفاده میکند که typeی است برای track کردن تغییرات در مدل مربوطه.
Deleting an Entity
برای حذف هر موجودیت نیز کافیست متد زیر را به کنترلر خود اضافه نمایید:
public async Task<IHttpActionResult> Delete([FromODataUri] int key) { var product = await db.Products.FindAsync(key); if (product == null) { return NotFound(); } db.Products.Remove(product); await db.SaveChangesAsync(); return StatusCode(HttpStatusCode.NoContent); }
من چند رکورد تستی را به صورت زیر وارد کردهام:
حال پروژهی خود را run نموده و آدرس زیر را وارد نمایید:
http://localhost:YourPort/Products
پاسخ، مجموعهای از entityهای زیر خواهد بود:
{ "@odata.context":"http://localhost:4516/$metadata#Products","value":[ { "Id":1,"Name":"Ali","Price":2.00,"Category":"aaa" },{ "Id":2,"Name":"Reza","Price":1.00,"Category":"bbb" },{ "Id":3,"Name":"Ahmad","Price":0.00,"Category":"ccc" } ] }
شما میتوانید از هر کدام از فیلترهای زیر برای کوئری زدن از کلاینت به سمت سرور استفاده نمایید. بطور مثال هر کدام از اینها پاسخ متفاوت و مربوط به خود را برگشت میدهد:
/Products(2)
Productی با آی دی 2 را بر میگرداند.
/Products?$filter=Id gt 1
محصولی را با آی دی بزرگتر از 1، بر میگرداند.
Products?$select=Name
روی محصولات select زده و فقط فیلد Name آنها را بر میگرداند.
Products?$select=Name,Price
آرایهای از objectهایی با پراپرتی Name و Price را بر میگرداند.
/Products?$top=3
فقط 3 رکورد اول را بر میگرداند.
همانطور که ملاحظه میفرمایید، استفاده از OData باعث کمتر شدن کدهای سمت سرور و همچنین امکان کوئری زدن از سمت کلاینت به سمت سرور را مهیا میکند.
بعد از خواندن این مقاله ممکن است به این مساله فکر کنید که این کار باعث کاهش امنیت میشود. باید عرض کنم که امکانات زیادی برای محدود کردن کوئریها، فراهم شده است و هیچ نگرانی از این بابت وجود ندارد. بطور مثال میتوانید تعیین کنید که از entity مربوطه فقط حداکثر 3 پراپرتی قابلیت کوئری زدن را دارند؛ یا اینکه حداکثر در هر کوئری، 10 رکورد قابلیت پاسخ دادن خواهد داشت.
پس بدین صورت میباشد که شما حداکثر امکانات ممکن را به سمت کلاینت میدهید و اختیار بدان واگذار شده که آیا از این امکانات حداکثری، استفاده نماید یا خیر.
امکانات این پروتکل منحصر به فرد است و در مقالههای بعدی به جزئیات بیشتر و دقیقتری خواهیم پرداخت.
{ "name": "Appscope", "display": "standalone", "icons": [{ "src": "icons/icon-192.png", "sizes": "192x192"}, { "src": "icons/icon-512.png", "sizes": "512x512"} ] }
<meta name="apple-mobile-web-app-capable" content="yes">