NET 8.0.402. منتشر شد
- تنظیمات پیش فرض باید تغییر کنند تا کلمات عبور حداقل 10 کاراکتر باشند
- کلمه عبور حداقل یک عدد و یک کاراکتر ویژه باید داشته باشد
- امکان استفاده از 5 کلمه عبور اخیری که ثبت شده وجود ندارد
ایجاد اپلیکیشن جدید
در پنجره Solution Explorer روی نام پروژه کلیک راست کنید و گزینه Manage NuGet Packages را انتخاب کنید. به قسمت Update بروید و تمام انتشارات جدید را در صورت وجود نصب کنید.
بگذارید تا به روند کلی ایجاد کاربران جدید در اپلیکیشن نگاهی بیاندازیم. این به ما در شناسایی نیازهای جدیدمان کمک میکند. در پوشه Controllers فایلی بنام AccountController.cs وجود دارد که حاوی متدهایی برای مدیریت کاربران است.
- کنترلر Account از کلاس UserManager استفاده میکند که در فریم ورک Identity تعریف شده است. این کلاس به نوبه خود از کلاس دیگری بنام UserStore استفاده میکند که برای دسترسی و مدیریت دادههای کاربران استفاده میشود. در مثال ما این کلاس از Entity Framework استفاده میکند که پیاده سازی پیش فرض است.
- متد Register POST یک کاربر جدید میسازد. متد CreateAsync به طبع متد 'ValidateAsync' را روی خاصیت PasswordValidator فراخوانی میکند تا کلمه عبور دریافتی اعتبارسنجی شود.
var user = new ApplicationUser() { UserName = model.UserName }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); }
قانون 1: کلمههای عبور باید حداقل 10 کاراکتر باشند
- مقدار حداقل کاراکترهای کلمه عبور به دو شکل میتواند تعریف شود. راه اول، تغییر کنترلر Account است. در متد سازنده این کنترلر کلاس UserManager وهله سازی میشود، همینجا میتوانید این تغییر را اعمال کنید. راه دوم، ساختن کلاس جدیدی است که از UserManager ارث بری میکند. سپس میتوان این کلاس را در سطح global تعریف کرد. در پوشه IdentityExtensions کلاس جدیدی با نام ApplicationUserManager بسازید.
public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager(): base(new UserStore<ApplicationUser>(new ApplicationDbContext())) { PasswordValidator = new MinimumLengthValidator (10); } }
- حال باید کلاس ApplicationUserManager را در کنترلر Account استفاده کنیم. متد سازنده و خاصیت UserManager را مانند زیر تغییر دهید.
public AccountController() : this(new ApplicationUserManager()) { } public AccountController(ApplicationUserManager userManager) { UserManager = userManager; } public ApplicationUserManager UserManager { get; private set; }
- اپلیکیشن را اجرا کنید و سعی کنید کاربر محلی جدیدی ثبت نمایید. اگر کلمه عبور وارد شده کمتر از 10 کاراکتر باشد پیغام خطای زیر را دریافت میکنید.
قانون 2: کلمههای عبور باید حداقل یک عدد و یک کاراکتر ویژه داشته باشند
- در پوشه IdentityExtensions کلاس جدیدی بنام CustomPasswordValidator بسازید و اینترفیس مذکور را پیاده سازی کنید. از آنجا که نوع کلمه عبور رشته (string) است از <IIdentityValidator<string استفاده میکنیم.
public class CustomPasswordValidator : IIdentityValidator<string> { public int RequiredLength { get; set; } public CustomPasswordValidator(int length) { RequiredLength = length; } public Task<IdentityResult> ValidateAsync(string item) { if (String.IsNullOrEmpty(item) || item.Length < RequiredLength) { return Task.FromResult(IdentityResult.Failed(String.Format("Password should be of length {0}",RequiredLength))); } string pattern = @"^(?=.*[0-9])(?=.*[!@#$%^&*])[0-9a-zA-Z!@#$%^&*0-9]{10,}$"; if (!Regex.IsMatch(item, pattern)) { return Task.FromResult(IdentityResult.Failed("Password should have one numeral and one special character")); } return Task.FromResult(IdentityResult.Success); }
- قدم بعدی تعریف این اعتبارسنج سفارشی در کلاس UserManager است. باید مقدار خاصیت PasswordValidator را به این کلاس تنظیم کنیم. به کلاس ApplicationUserManager که پیشتر ساختید بروید و مقدار خاصیت PasswordValidator را به CustomPasswordValidator تغییر دهید.
public class ApplicationUserManager : UserManager<ApplicationUser> { public ApplicationUserManager() : base(new UserStore<ApplicationUser(new ApplicationDbContext())) { PasswordValidator = new CustomPasswordValidator(10); } }
قانون 3: امکان استفاده از 5 کلمه عبور اخیر ثبت شده وجود ندارد
public class PreviousPassword { public PreviousPassword() { CreateDate = DateTimeOffset.Now; } [Key, Column(Order = 0)] public string PasswordHash { get; set; } public DateTimeOffset CreateDate { get; set; } [Key, Column(Order = 1)] public string UserId { get; set; } public virtual ApplicationUser User { get; set; } }
- خاصیت جدیدی به کلاس ApplicationUser اضافه کنید تا لیست آخرین کلمات عبور استفاده شده را نگهداری کند.
public class ApplicationUser : IdentityUser { public ApplicationUser() : base() { PreviousUserPasswords = new List<PreviousPassword>(); } public virtual IList<PreviousPassword> PreviousUserPasswords { get; set; } }
public class ApplicationUserStore : UserStore<ApplicationUser> { public ApplicationUserStore(DbContext context) : base(context) { } public override async Task CreateAsync(ApplicationUser user) { await base.CreateAsync(user); await AddToPreviousPasswordsAsync(user, user.PasswordHash); } public Task AddToPreviousPasswordsAsync(ApplicationUser user, string password) { user.PreviousUserPasswords.Add(new PreviousPassword() { UserId = user.Id, PasswordHash = password }); return UpdateAsync(user); } }
public class ApplicationUserManager : UserManager<ApplicationUser> { private const int PASSWORD_HISTORY_LIMIT = 5; public ApplicationUserManager() : base(new ApplicationUserStore(new ApplicationDbContext())) { PasswordValidator = new CustomPasswordValidator(10); } public override async Task<IdentityResult> ChangePasswordAsync(string userId, string currentPassword, string newPassword) { if (await IsPreviousPassword(userId, newPassword)) { return await Task.FromResult(IdentityResult.Failed("Cannot reuse old password")); } var result = await base.ChangePasswordAsync(userId, currentPassword, newPassword); if (result.Succeeded) { var store = Store as ApplicationUserStore; await store.AddToPreviousPasswordsAsync(await FindByIdAsync(userId), PasswordHasher.HashPassword(newPassword)); } return result; } public override async Task<IdentityResult> ResetPasswordAsync(string userId, string token, string newPassword) { if (await IsPreviousPassword(userId, newPassword)) { return await Task.FromResult(IdentityResult.Failed("Cannot reuse old password")); } var result = await base.ResetPasswordAsync(userId, token, newPassword); if (result.Succeeded) { var store = Store as ApplicationUserStore; await store.AddToPreviousPasswordsAsync(await FindByIdAsync(userId), PasswordHasher.HashPassword(newPassword)); } return result; } private async Task<bool> IsPreviousPassword(string userId, string newPassword) { var user = await FindByIdAsync(userId); if (user.PreviousUserPasswords.OrderByDescending(x => x.CreateDate). Select(x => x.PasswordHash).Take(PASSWORD_HISTORY_LIMIT) .Where(x => PasswordHasher.VerifyHashedPassword(x, newPassword) != PasswordVerificationResult.Failed).Any()) { return true; } return false; } }
سورس کد این مثال را میتوانید از این لینک دریافت کنید. نام پروژه Identity-PasswordPolicy است، و زیر قسمت Samples/Identity قرار دارد.
که بعد از بررسی به راه حلهای زیر رسیدم:
راه حل اول
بعد از اجرای وب سرویس و باز کردن آدرس آن به صورت HTTPS در مرورگر، پیام مبنی بر عدم اعتبار گواهی HTTPS را در آدرس وارد شده، مشاهده میکنیم. (Untrusted certificate) (که نسبت به مرورگر استفاده شده، این پیام متفاوت است و من در اینجا از مرورگر IE استفاده میکنم)
- بر روی Certificate error در نوار آدرس، کلیک کرده و View certificates را انتخاب میکنیم.
- وقتی پنجره Certificate باز شد بر روی دکمه Install Certificate کلیک کرده و پنجره Certificate Import Wizard باز شده و Next را میزنیم و Place all certificates in the following store را انتخاب میکنیم و بر روی دکمه Browse کلیک میکنیم.
- از پنجره باز شده Trusted Root Certification Authorities را انتخاب میکنیم و بر روی دکمه OK، کلیک میکنیم.
- سپس Next را میزنیم و در پایان بر روی دکمه Finish کلیک میکنیم.
- پس از اتمام Wizard، پنجره Security Warning به شما نمایش داده میشود که باید بر روی Yes آن کلیک کنید، بعد از تایید، پیام .The import was successful به شما نمایش داده میشود.
راه حل دوم
ممکن است کامپیوتر شما با توسعه دهندگان دیگر که با حساب کاربری خود وارد میشوند، مشترک باشد و بخواهید اطلاعات مربوط به گواهی اعتبار، به صورت مشترک استفاده شود. جزئیات در این روش بیشتر از روش قبل است.
- بازکردن پنجره Run و وارد کردن دستور mmc و زدن دکمه OK.
- اضافه کردن Snap-in
- انتخاب Add/Remove Snap-in از منوی File
- انتخاب Certificates از لیست سمت چپ و انتخاب دکمه Add
- در پنجره Certificates Snap-ins انتخاب گزینه Computer account و انتخاب دکمه Next
- انتخاب Local computer و کلیک بر روی دکمه Finish
- انتخاب دکمه OK
- استخراج IIS Express certificate از computer’s personal store
- در قسمت Console Root ، بخش Certificates (Local Computer)، سپس قسمت Personal و انتخاب Certificates.
- انتخاب گواهی با مشخصات زیر:
- "Issued to = "localhost
- "Issued by = "localhost
- "Friendly Name = "IIS Express Development Certificate
- انتخاب گزینه Export از زیرمنوی All Tasks در منوی Action
- پنجره Certificate Export Wizard باز شده و انتخاب دکمه Next
- انتخاب No, do not export the private key و انتخاب دکمه Next
- انتخاب DER encoded binary X.509 (.CER) و انتخاب دکمه Next
- انتخاب مسیر ذخیره فایل گواهی تصدیق مجوز و انتخاب دکمه Next
- انتخاب دکمه Finish برای انجام عملیات Export و مشاهده پیام موفقیت
- وارد کردن IIS Express certificate به computer’s Trusted Root Certification Authorities store
- در قسمت Console Root ، بخش Certificates (Local Computer)، سپس قسمت Trusted Root Certification Authorities و انتخاب Certificates.
- انتخاب گزینه Import از زیرمنوی All Tasks در منوی Action
- پنجره Certificate Export Wizard باز شده و انتخاب دکمه Next
- انتخاب مسیر فایل ذخیره شده در مرحله قبل و انتخاب دکمه Next
- انتخاب Place all certificates in the following store و در قسمت Certificate store ، انتخاب بخش Trusted Root Certification Authorities و انتخاب دکمه Next
- انتخاب دکمه Finish برای انجام عملیات Import و مشاهده پیام موفقیت و مشاهده گواهی تصدیق مجوز با نام localhost در لیست Trusted Root Certification Authorities
راه حل سوم
با استفاده از Developer Command Prompt نیز میتوان این کار را انجام داد.
- با اجرای دستور زیر و دریافت فایل خروجی
makecert -r -n "CN=localhost" -b 01/01/2000 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.1 -sv localhost.pvk localhost.cer cert2spc localhost.cer localhost.spc pvk2pfx -pvk localhost.pvk -spc localhost.spc -pfx localhost.pfx
- اجرای فایل localhost.pfx و وقتی پنجره Certificate Import Wizard باز شد، Next را میزنیم.
- نام فایل انتخاب شده را در این قسمت مشاهده میکنیم و Next را میزنیم.
- در صورت داشتن کلمه عبور، آن را وارد کرده (که در اینجا کلمه عبوری را تعریف نکردهایم) و Next را میزنیم.
- صفحه Place all certificates in the following store را انتخاب میکنیم و بر روی دکمه Browse کلیک میکنیم.
- از پنجره باز شده، Trusted Root Certification Authorities را انتخاب میکنیم و بر روی دکمه OK، کلیک میکنیم.
- سپس Next را میزنیم و در پایان بر روی دکمه Finish کلیک میکنیم.
- پس از اتمام Wizard، پنجره Security Warning به شما نمایش داده میشود که باید بر روی Yes کلیک کنید. بعد از تایید، پیام .The import was successful به شما نمایش داده میشود.
نکته: در صورتی که بخواهید برنامه شما (windows form) بتواند به سرور از طریق HTTPS اتصال پیدا کند، باید این فایل pfx بر روی هر کلاینت نصب شده باشد. شما میتوانید با اجرای دستور زیر در ابتدای فایل program.cs این کار را انجام دهید.
var cert = new X509Certificate2( Properties.Resources.localhost ); var store = new X509Store( StoreName.AuthRoot, StoreLocation.LocalMachine ); store.Open(OpenFlags.ReadWrite); store.Add(cert); store.Close();
ردیس ۷ در راه است
گویا ۳ برابر سریعتر از الستیکسرچ است!
In Redis 7.0, Redis Labs is adding two enhancements to its JSON support. The first is with search. RediSearch 2.0, which itself only became generally available barely a month ago; it now adds JSON as a supported data type. Before this, search was run as a separate feature that sat apart from the nodes housing the data engine. RediSearch 2.0 adds new scale-out capabilities to conduct massively parallel searches across up to billions of JSON documents across multiple nodes, returning results in fractions of a second. As the search engine was optimized for the Redis database, Redis Labs claims it runs up to 3x faster than Elasticsearch.
FastReport سورس باز شد
We are very pleased to announce the launch of our Open Source project - Fast Report Open Source.
We are hoping to develop a friendly community of .Net Core developers who will share our eagerness to create fast, powerful and convenient reporting tool for Windows, Windows Server, Linux and MacOS.
We also encourage you to be a part of the global reporting team! Join us on GitHub: github.com/FastReports/FastReport