چکیده: سیستم عضویت ASP.NET Identity 2.0 تعدادی ویژگی های امنیتی قوی را در اپلیکیشن های دات نت ادغام می کند. این مقاله تعدادی از این ویژگی ها را بیان می کند.
در نظر گرفتن شرایط امنیتی متناسب با نیازهای بیزینسی ذر حوزه های مختلف مانند سیستمهای بانکداری، بیمه و غیره همیشه از دغدغه های اصلی توسعه دهندگان سیستم ها می باشد. علاوه بر این اپلیکیشنهای شبکه های اجتماعی شناخته شده ای نیز وجود دارند که شامل میلیونها کاربر هستند و چون در دسترس عموم در بستر اینترنت هستند همیشه در معرض خطر و آسیب پذیری های امنیتی قرار می گیرند. در نتیجه توصیه می شود که همیشه تدابیر امنیتی شدیدی برای تمام این اپلیکیشن ها در نظر گرفته شود.
ایجاد یک اپلیکیشن امن همیشه یک کار چالشی می باشد. اخیرا خیلی از وب سایت های مدرن امروزی از Identity های شبکه های اجتماعی برای احراز هویت در اپلیکیشن استفاده می نمایند. به هرحال برای مقابله با تغییرات و افزایش تقاضا، نگاه تازه به سیستم عضویت لازم بود.
ASP.NET Identity یک سیستم عضویت جدید برای ایجاد اپلیکیشن های دات نت، موبایل، فروشگاهی یا ترکیبی می باشد.
ASP.NET Identity
ASP.NET Identity با همه فریم ورک های ASP.NET مانند web form ها، MVC،
Web Page ها، Web Api و SignalR می تواند مورد استفاده قرار گیرد.
ASP.NET Identity با تعدادی ویژگی های امنیتی مانند احراز هویت دومرحله ای، قفل کردن حساب کاربری، تایید حساب کاربری و غیره توسعه داده شده است. این سیستم همچنین جهت احراز هویت از provider های شبکه های اجتماعی مانند FaceBook، Twitter، Google و احراز هویت مبتنی بر Claim نیز پشتیبانی می نماید. آن با OWIN کاملا سازگاز می باشد و از NuGet Package Manager قابل دانلود می باشد.
پکیجهایی که برای دانلود ASP.NET Identity 2.0.0 نیاز است اینجا آورده شده است:
Microsoft.AspNet.Identity.EntityFramework Version 2.0.0 – شامل پیاده سازی entity Framework برای انواع identity است. این identity ها برای مدیریت اطلاعات جهت هویت کاربران، نقش ها، Claim، login و غیره استفاده می شوند.
Microsoft.AspNet.Identity.Core Version 2.0.0 – شامل کلاسها و رابط های کاربری برای مدیریت کاربران و نقش ها در ASP.NET Identity می باشد. همچنین شامل کلاسها برای اعتبارسنجی کاربر و اطلاعات ورود کاربر به اپلیکیشن میباشد.
Microsoft.AspNet.Identity.OWIN -Version 2.0.0 – شامل کلاسها برای مدیریت identity های مرتبط با OWIN می باشد.
برای پیاده سازی ASP.NET Identity در یک اپلیکیشن از نوع Empty، مثالهای زیر با استفاده از پکیج زیر نصب می شود:
Microsoft.AspNet.Identity.Samples -Version 2.0.0-beta2 –Pre
این پکیج، کلاسهای ضروری برای ASP.NET Identity 2.0.0 را در اپلیکیشن شما اضافه می نماید و بنابراین کار توسعه را سهولت می بخشد. بنابراین آزادی عمل جهت تغییر دادن کد در هرجای اپلیکشن که نیاز باشد را فراهم می کند.
پیاده سازی ASP.NET Identity
مرحله 1: ویژوال استودیو را باز کنید و یک اپلیکیشن MVC با .NET 4.5 ایجاد نمایید. نام آن را MVC_Identity بگذارید. زمیانی که پروژه ایجاد شد.
مرحله 2: جهت دریافت دستورات پایه برای Identity 2.0.0، نیاز است که ASP.NET Identity sample نصب گردد. به این منظور دستور زیر را در Package Manager Console، اجرا نمایید:
این یک مرحله مهم برای گرفتن دستورات اولیه Identity می باشد.
مرحله 3: بعد از نصب sample، پروژه تعدادی کنترلرهای اضافی خواهد داشت. مبتنی بر کنترلرها، view ها در فولدر view ایجاد می شوند.
مرحله 4: فایل IdentityConfig.cs در فولدر App_Start را باز نمایید. این فایل شامل کلاسهای زیر می باشد:
- ApplicationUserManager
- ApplicationRoleManager
- EmailService
- SmsService
- ApplicationDbInitializer
- SignInHelper
شمارنده SignInStatus تعدادی value برای SignIn کاربر ارائه می دهد.
سوالی که اینجا مطرح می شود این است که این کلاسها مسئول چه کارهایی هستند؟ ما قصد داریم تمام آنها را یکی یکی با ویژگی های امنیتی جدید ارائه شده در ASP.NET Identity مورد بررسی قرار دهیم.
احراز هویت دومرحله ای
احراز هویت دومرحله ای یک لایه امنیتی بیشتر برای حساب کاربری اپلیکیشن ارائه میدهد. این یک لایه امنیتی برای رمز عبور وارد شده توسط کاربر می باشد. این ویژگی از مکانیسم ارسال کد امنیتی به تلفن کاربر و یا ارسال از طریق ایمیل به کاربر استفاده می نماید. کلاس ApplicationUserManager از کلاس پایه UserManager مشتق شده است. این یک کلاس Generic با پارامتر از نوع ApplicationUser می باشد. کلاس ApplicationUser مسئول کار با identity کاربران می باشد. کلاس ApplicationUserManager یک متد Create تعریف می کند. این متد شامل منطق برای اعتبارسنجی نام کاربری و رمز عبور به صورت زیر می باشد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var manager = new ApplicationUserManager(new UserStore(context.Get ())); // Configure validation logic for usernames manager.UserValidator = new UserValidator(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // Configure validation logic for passwords manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; |
قفل کردن حساب کاربری
قفل کردن حساب کاربری ویژگی مهم دیگری است که در ASP.NET Identity 2.0.0 ارائه شده است. توسط این ویژگی، اگر کاربر به تعداد دفعات مشخصی رمز عبور را اشتباه وارد نماید در نتیجه حساب کاربری وی قفل خواهد شد. این ویژگی توسط maximum failed attempts و lockout time span مانند کد زیر تعیین می شود:
1 2 3 4 |
manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5; |
زمانی که validators ها و lockout برای حساب کاربری اعمال شدف حالا احراز هویت دومرحله ای توسط کد زیر می تواند اعمال گردد:
1 2 3 4 5 6 7 8 9 10 11 12 |
manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider { MessageFormat = "Your security code is: {0}" }); manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider { Subject = "SecurityCode", BodyFormat = "Your security code is {0}" }); manager.EmailService = new EmailService(); manager.SmsService = new SmsService(); |
در کد بالا، کلاسهای PhoneNumberTokenProvider وEmailTokenProvider مورد استفاده قرار گرفته اند. این کلاسها از TopSecurityStampBasedTokenProviderمشتق شده اند. این کلاس مسئول ایجاد کدهای مبتنی بر time با استفاده از تدابیر امنیتی کاربران است و کدها را با استفاده از شماره تلفن و آدرس ایمیل با کمک PhoneNumberTokenProvider و EmailTokenProvider ارسال می نماید. در کل برای ارسال sms یا ایمیل، توافق جهت پیاده سازی باید صورت گیرد. برای پیاده سازی سرویس توافق کلاسهای زیر مورد استفاده قرار میگیرد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class EmailService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your email service here to send an email. returnTask.FromResult(0); } } public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Plug in your sms service here to send a text message. return Task.FromResult(0); } } |
این فقط یک مثال است. شما می توانید کد را متناسب با نیاز اپلیکیشن خودتان پیاده سازی نمایید.
استفاده از Email Service برای احراز هویت
مرحله 5: کد زیر را در متد SendAsync در کلاس EmailService قرار دهید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public Task SendAsync(IdentityMessage message) { var mailMessage = new System.Net.Mail.MailMessage("TestAdmin.Admin@MyApplication.com ", message.Destination, message.Subject, message.Body ); //Send the Message SmtpClient client = new SmtpClient(); client.SendAsync(mailMessage, null); return Task.FromResult(true); } |
اینجا کلاس MailMessage پارامترهای زیر را به عنوان ورودی میگیرد:
- Senders Email Address
- Recipients Email address
- Subject
- Body
پیام مورد نظر با استفاده از کلاس SmtpClient فرستاده می شود. توجه نمایید که شما می توانید از تنظیمات سرور ایمیل خودتان اینجا استفاده نمایید.
مرحله 6: در محیط توسعه یک فولدر email drop برای پیکربندی در فایل web.config همانند شکل زیر نیاز است:
پیکربندی بالا، سرویس SMTP را برای گرفتن پیام ایمیل مشخص می نماید.
مرحله 7: فایل web.config یک رشته اتصال برای ذخیره اطلاعات کاربر در SQL Server اضافه می نماید:
1 2 3 |
connectionString="Data Source=(LocalDb)\v11.0; Initial Catalog=MVC_Identity-1-14;Integrated Security=SSPI" providerName="System.Data.SqlClient" /> |
مرحله 8: فایل AccountController.cs را باز نمایید و متد Register را با HttpPost در آن قرار دهید. این کد شامل کدهای مورد نیاز برای ارسال ایمیل جهت تایید حساب کاربری می باشد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public async Task Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = awaitUserManager.CreateAsync(user, model.Password); if (result.Succeeded) { var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking this link: link"); ViewBag.Link = callbackUrl; return View("DisplayEmail"); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); } |
مرحله 9: برنامه را اجرا نمایید و روی لینک Register کلیک نمایید. view مورد نظر به صورت زیر خواهد بود:
مرحله 10: ایمیل و بقیه جزییات را وارد نموده و روی دکمه register کلیک نمایید. در نتیجه view زیر را مشاهده خواهید نمود:
مرحله 11: به پوشه email drop که در فایل config پیکربندی کرده بودید بروید. سپس شما ایمیلی را میبینید که میتواند با نرم افزار Outlook یا چیزی شبیه به آن باز نمایید:
مرحله 12: روی لینک در ایمیل کیلیک نمایید:
مرحله 13: حالا شما همانند شکل زیر وارد سیستم شده اید:
پیاده سازی Lockout حساب کاربری
Account Lockout همانطور که ما در اول مقاله صحبت کردیم یکی از مهمترین مفاهیم پیاده سازی امنیت است که در اکثر سایتهای مالی و تجاری مورد نیاز است.
مرحله 1: در متد create در کلاس ApplicationUserManager ، خصوصیات DefaultAccountLockoutTimeSpan and MaxFiledAccessAttemptBeforeLockout را به صورت زیر تغییر دهید:
1 2 3 4 |
manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(1); manager.MaxFailedAccessAttemptsBeforeLockout = 2; |
مرحله 2: برای پیاده سازی ویژگی account lockout، نیاز است که کد زیر را در ابتدای متد PasswordSignIn بعد از گرفتن نام کاربر توسط FindByNameAsync قرار دهید(به صورت highlight مشخص شده است):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public async Task PasswordSignIn(stringuserName, string password, bool isPersistent, bool shouldLockout) { var user = await UserManager.FindByNameAsync(userName); await UserManager.IsLockedOutAsync(user.Id); await UserManager.AccessFailedAsync(user.Id); await UserManager.SetLockoutEnabledAsync(user.Id, true); if (user == null) { returnSignInStatus.Failure; } if (await UserManager.IsLockedOutAsync(user.Id)) { return SignInStatus.LockedOut; } if (awaitUserManager.CheckPasswordAsync(user, password)) { return await SignInOrTwoFactor(user, isPersistent); } if (shouldLockout) { // If lockout is requested, increment access failed count which might lock out the user await UserManager.AccessFailedAsync(user.Id); if (await UserManager.IsLockedOutAsync(user.Id)) { return SignInStatus.LockedOut; } } return SignInStatus.Failure; } |
در این قطعه کد تعدادی نکته وجود دارد که حائز اهمیت می باشد:
1 |
await UserManager.IsLockedOutAsync(user.Id) : |
اگر کاربر lockout باشد در نتیجه true برمیگرداند.
1 |
await UserManager.AccessFailedAsync(user.Id) : |
تعداد accessfail را برای کاربر افزایش می دهد. اگر تعداد accessfail بیشتر یا برابر با MaxFailedAccessAttemptsBeforeLockout باشد، سپس حساب کاربر به مدت زمانی که توسط lockouttimespan مشخص شده است قفل خواهد شد.
1 |
await UserManager.SetLockoutEnabledAsync(user.Id, true) : |
ویژگی Lockout را برای کاربر فعال میکند.
مرحله 3: برنامه را اجرا کنید و با حساب کاربری که قبلا ثبت کرده بودید سعی کنید 2 بار رمز عبور را اشتباه وارد نمایید که در نتیجه با پیام زیر روبه رو خواهید شد:
حال منتظر بمانبد تا زمان اعمال شده در ویژگی DefaultAccountLockoutTimeSpan به پایان برسد این بار رمز عبور را صحیح وارد نمایید که در نتیجه می توانید با موفقیت وارد سیستم شوید.
این یک امکان عالی است که در ASP.NET Identity 2.0.0 در نظر گرفته شده است تا از ورودهای غیر مجاز برای حفظ اطلاعات کاربر جلوگیری گردد.
ریست کردن رمز عبور
ویژگی Password Reset در صورت فراموش کردن رمز عبور می تواند مورد استفاده قرار گیرد. همانطور که در خیلی از وب سایتهای امروزی مشاهده نمودید کاربر می تواند در صورت فراموشی رمز عبور خود بر روی لینک مربوطه کلیک نموده تا یک لینک درون ایمیل خود جهت ریست کردن رمز عبور دریافت کند .
در این پروژه ما متدهایی را در کلاس AccountController داریم که شامل ForgetPassword و ResetPassword می باشد. این ویژگی با پکیج sample که به همراه پکیج ASP.NET Identity 2.0.0 که ابتدای این مقاله نصب کرده بودیم ارائه شده است.
مرحله 1: برنامه را اجرا نمایید و از قسمت فرم login، بر روی لینک Forget your password کلیک نمایید که در نتیجه فرم زیر برای شما نمایش داده خواهد شد:
مرحله 2: ایمیلتان را وارد نمایید سپس روی دکمه Email Link کلیک نمایید. view زیر نمایش داده می شود:
سپس ایمیل در پوشه drop که در فایل web.config توسط ویژگی pickupDirectoryLocation تعیین کرده بودیم ظاهر می شود که با کلیک بر روی آن، View زیر نمایش داده می شود:
و سپس یک رمز عبور جدید برای ورود به سیستم مورد استفاده قرار میگیرد.
نتیجه گیری
همانطور که احتمالاً مشاهده کرده اید ، این ویژگی های جدید ارائه شده در ASP.NET Identity 2.0.0 یک مکانیزم پیشرفته برای مدیریت امنیت اطلاعات معتبر کاربران در انبار داده های ما ارائه می دهد. در نتیجه یک توسعه دهنده می تواند از این قابلیتهای ارائه شده در دات نت برای پیاده سازی امنیت در اپلیکیشن خود استفاده نماید.
امیدوارم این مقاله به شما کمک کند تا به راحتی بتوانید توسط ASP.NET Identity، امنیت مورد نظر را در اپلیکیشن های خود پیاده سازی نمایید.
برای دانلود سورس کامل پروژه اینجا کلیک نمایدد.