No Authentication
اگر گزینه No Authentication را انتخاب کنید، پروژه ایجاد شده صفحاتی را برای ورود به سایت نخواهد ساخت. همچنین رابط کاربری ای برای نمایش کاربر فعلی، کلاسهای موجودیتها برای یک دیتابیس عضویت و رشتههای اتصالی نیز وجود نخواهند داشت.
- سیستم عضویت جدید بجای استفاده از ماژول ASP.NET Forms Authentication بر پایه OWIN نوشته شده است. این بدین معنا است که از یک مکانیزم احراز هویت واحد میتوانید در اپلیکیشنهای ASP.NET Web Forms, MVC, Web API و SignalR استفاده کنید.
- سیستم عضویت جدید توسط Entity Framework Code First مدیریت میشود و شامل تمامی کلاسهایی است که نماینده جداول و موجودیتها هستند. این بدین معنا است که روی الگوی دیتابیس کنترل کامل دارید. سفارشی سازی و تغییر اطلاعات کاربران و پروفایل هایشان بسیار سادهتر است، تنها لازم است برای اعمال تغییرات از Code First Migrations استفاده کنید.
- asp.net/identity
- Create an ASP.NET MVC 5 App with Facebook and Google OAuth2 and OpenID Sign-on
- Web API - External Authentication Services
- Adding External Logins to your ASP.NET application in Visual Studio 2013
اگر گزینه Organizational Accounts را انتخاب کنید پروژه ایجاد شده برای استفاده از (Windows Identity Foundation (WIF پیکربندی خواهد شد. این فریم ورک برای احراز هویت کاربران از (Windows Azure Active Directory (WAAD استفاده میکند که شامل Office 365 نیز میشود.
از این گزینه برای احراز هویت کاربرانی استفاده کنید که در قالب یک OWIN Tenant تعریف میشوند. برای مثال سایتی با نام Company.com داریم که برای کارمندان این سازمان از طریق company.onmicrosoft.com قابل دسترسی خواهد بود. نمیتوانید WAAD را طوری پیکربندی کنید که کاربران tenantهای دیگر نیز به اپلیکیشن شما دسترسی داشته باشند.
Domain
نام دامنهای در WAAD که میخواهید اپلیکیشن را برای آن پیکربندی کنید، مثلا company.onmicrosoft.com. اگر از custom domain ها استفاده میکنید مانند company.com بجای company.onmicrosoft.com میتوانید این اطلاعات را اینجا وارد کنید.
سطح دسترسی
اگر اپلیکیشن نیاز به کوئری گرفتن یا بروز رسانی اطلاعات پوشهها (directory information) را توسط Graph API دارد، از گزینههای Single Sign-On, Read Directory Data و یا Single Sign-On, Read and Write Directory Data استفاده کنید. در غیر اینصورت گزینه Single Sign-On را رها کنید. برای اطلاعات بیشتر به Application Access Levels و Using the Graph API to Query Windows Azure AD مراجعه کنید.
Application ID URI
بصورت پیش فرض، قالب پروژه یک شناسه application ID URI برای شما تولید میکند، که این کار با الحاق نام پروژه شما به نام دامنه WAAD صورت میگیرد. برای مثال، اگر نام پروژه Example باشد و نام دامنه contoso.onmicrosoft.com، شناسه خروجی https://contoso.onmicrosoft.com/Example میشود. اگر میخواهید بصورت دستی این فیلد را مقدار دهی کنید، گزینه More Options را انتخاب کنید. این شناسه باید با //:https شروع شود.
بصورت پیش فرض، اگر اپلیکیشنی که در WAAD تهیه و تدارک دیده شده است، شناسهای یکسان با شناسه موجود در پروژه Visual Studio داشته باشد، پروژه شما به اپلیکیشن موجود در WAAD متصل خواهد شد. اگر میخواهید تدارکات جدیدی ببینید تیک گزینه Overwrite the application entry if one with the same ID already exists را حذف کنید.
اگر تیک این گزینه حذف شده باشد، و ویژوال استودیو اپلیکیشنی با شناسهای یکسان را پیدا کند، عددی به آخر URI اضافه خواهد شد. مثلا فرض کنید نام پروژه Example است و اپلیکیشنی نیز با شناسه https://contoso.onmicrosoft.com/Example در WAAD وجود دارد. در این صورت اپلیکیشن جدیدی با شناسه ای مانند https://contoso.onmicrosoft.com/Example_ 20130619330903 ایجاد میشود.
تهیه و تدارک اپلیکیشن در WAAD
برای آنکه یک اپلیکیشن WAAD ایجاد کنید و یا پروژه را به یک اپلیکیشن موجود متصل کنید، ویژوال استودیو به اطلاعات ورود یک مدیر کل برای دامنه مورد نظر، نیاز دارد. هنگامی که در دیالوگ Configure Authentication روی OK کلیک میکنید، اطلاعات ورود یک مدیر کل از شما درخواست میشود و نهایتا هنگامیکه روی Create Project کلیک میکنید، ویژوال استودیو اپلیکیشن شما را در WAAD پیکربندی میکند.
برای اطلاعات بیشتر درباره نحوه استفاده از مدل احراز هویت Cloud - Single Organization به لینکهای زیر مراجعه فرمایید:
- Windows Azure Authentication
- Adding Sign-On to Your Web Application Using Windows Azure AD
- Developing ASP.NET Apps with Windows Azure Active Directory
از این گزینه برای احراز هویت کاربرانی استفاده کنید که در WAAD tenantهای متعددی تعریف شدهاند. برای مثال، نام سایت contoso.com است و برای کارمندان دو سازمان از طریق آدرسهای contoso.onmicrosoft.com و fabrikam.onmicrosoft.com قابل دسترسی خواهد بود. نحوه پیکربندی این مدل نیز مانند قسمت قبلی است.
برای اطلاعات بیشتر درباره احراز هویت Cloud - Multi Organization به لینکهای زیر مراجعه کنید:
- Easy Web App Integration with Windows Azure Active Directory, ASP.NET & Visual Studio
- Developing Multi-Tenant Web Applications with Windows Azure AD
این گزینه را هنگامی انتخاب کنید که کاربران در (Windows Server Active Directory (AD تعریف شده اند و نمیخواهید از WAAD استفاده کنید. از این مدل برای ایجاد وب سایتهای اینترنت و اینترانت میتوانید استفاده کنید. برای یک وب سایت اینترنتی از (Active Directory Federation Services (ADFS استفاده کنید.
برای یک وب سایت اینترانتی، میتوانید کلا این گزینه را رها کنید و از Windows Authentication استفاده کنید. در صورت استفاده از گزینه Windows Authentication لازم نیست تا آدرس سند متادیتا (metadata document URL) را فراهم کنید، همچنین توجه داشته باشید که Windows Authentication امکان کوئری گرفتن از پوشهها و کنترل سطوح دسترسی در Active Directory را ندارد.
On-Premises Authority
آدرس سند متادیتا. این سند اطلاعاتی درباره مختصات Authority دارد که اپلیکیشن از آنها برای به پیش بردن روند احراز هویت و ورود به سایت استفاده میکند.
Application ID URI
یک شناسه منحصر به فرد که AD از آن برای شناسایی اپلیکیشن استفاده میکند. میتوانید این فیلد را خالی رها کنید تا ویژوال استودیو بصورت خودکار اپلیکیشنی بدین منظور بسازد.
قدمهای بعدی
در این مقاله با مدلهای مختلف احراز هویت در اپلیکیشنهای Visual Studio 2013 آشنا شدید و برخی تغییرات و امکانات جدید نیز بررسی شدند. برای اطلاعات تکمیلی به ASP.NET and Web Tools for Visual Studio 2013 Release Notes مراجعه کنید.
Iris Identity
The Problem
What they neglect to say is all that testability and persistence ignorance flies right out the window when you create a new ASP.NET Web Application using the MVC template and "Individual User Accounts" authentication. What you get is a single-layered application, tightly coupled to Entity Framework, that:
-
Ignores the patterns that facilitate testing, including: the repository pattern, unit of work pattern, and dependency injection;
-
Forces you to implement their
IUser
interface in your application’s User entity, thereby coupling it to ASP.NET Identity; -
Eliminates any clear separation between your entities, persistence concerns, and business logic. Persistence ignorance? Forget about it.
Thankfully, due to the extensibility designed into ASP.NET Identity, it is possible to ditch the reference to the Microsoft.AspNet.Identity.EntityFramework
assembly and write a custom implementation that can address these and other architectural issues. Just be forewarned: it is not a trivial undertaking, and you’ll have to put up with some code smell that is baked into the Microsoft.AspNet.Identity.Core
assembly.
جدول AppUserClaims
جدول AppUserClaims، جزو جداول اصلی ASP.NET Core Identity است و هدف آن ذخیرهی اطلاعات ویژهی کاربران و بازیابی سادهتر آنها از طریق کوکیهای آنها است (همانند User.Identity.Name). زمانیکه کاربری به سیستم وارد میشود، بر اساس UserId او، تمام رکوردهای User Claims متعلق به او از این جدول واکشی شده و به صورت خودکار به کوکی او اضافه میشوند.
در پروژهی DNT Identity از این جدول استفاده نمیشود. چون اطلاعات User Claims مورد نیاز آن، هم اکنون در جدول AppUsers موجود هستند. به همین جهت افزودن این نوع User Claimها به جدول AppUserClaims، به ازای هر کاربر، کاری بیهوده است. سناریویی که استفادهی از این جدول را با مفهوم میکند، ذخیره سازی تنظیمات ویژهی هرکاربر است (خارج از فیلدهای جدول کاربران). برای مثال اگر سایتی را چندزبانه طراحی کردید، میتوانید یک User Claim سفارشی جدید را برای این منظور ایجاد و زبان انتخابی کاربر را به عنوان یک رکورد جدید مخصوص آن در این جدول ویژه ثبت کنید. مزیت آن این است که واکشی و افزوده شدن اطلاعات آن به کوکی شخص، به صورت خودکار توسط فریم ورک صورت گرفته و در حین مرور صفحات توسط کاربر، دیگر نیازی نیست تا اطلاعات زبان انتخابی او را از بانک اطلاعاتی واکشی کرد.
بنابراین برای ذخیره سازی تنظیمات با کارآیی بالای ویژهی هرکاربر، جدول جدیدی را ایجاد نکنید. جدول User Claim برای همین منظور درنظر گرفته شدهاست و پردازش اطلاعات آن توسط فریم ورک صورت میگیرد.
ASP.NET Core Identity چگونه اطلاعات جدول AppUserClaims را پردازش میکند؟
ASP.NET Identity Core در حین لاگین کاربر به سیستم، از سرویس SignInManager خودش استفاده میکند که با نحوهی سفارشی سازی آن پیشتر در قسمت دوم این سری آشنا شدیم. سرویس SignInManager پس از لاگین شخص، از یک سرویس توکار دیگر این فریم ورک به نام UserClaimsPrincipalFactory جهت واکشی اطلاعات User Claims و همچنین Role Claims و افزودن آنها به کوکی رمزنگاری شدهی شخص، استفاده میکند.
بنابراین اگر قصد افزودن User Claim سفارشی دیگری را داشته باشیم، میتوان همین سرویس توکار UserClaimsPrincipalFactory را سفارشی سازی کرد (بجای اینکه الزاما رکوردی را به جدول AppUserClaims اضافه کنیم).
اطلاعات جالبی را هم میتوان از پیاده سازی متد CreateAsync آن استخراج کرد:
public virtual async Task<ClaimsPrincipal> CreateAsync(TUser user)
2) userName شخص پس از لاگین از طریق User Claims ایی با نوع Options.ClaimsIdentity.UserNameClaimType به کوکی او اضافه میشود.
3) security stamp او (آخرین بار تغییر اطلاعات اکانت کاربر) نیز یک Claim پیشفرض است.
4) اگر نقشهایی به کاربر انتساب داده شده باشند، تمام این نقشها واکشی شده و به عنوان یک Claim جدید به کوکی او اضافه میشوند.
5) اگر یک نقش منتسب به کاربر دارای Role Claim باشد، این موارد نیز واکشی شده و به کوکی او به عنوان یک Claim جدید اضافه میشوند. در ASP.NET Identity Core نقشها نیز میتوانند Claim داشته باشند (امکان پیاده سازی سطوح دسترسی پویا).
بنابراین حداقل مدیریت Claims این 5 مورد خودکار است و اگر برای مثال نیاز به Id کاربر لاگین شده را داشتید، نیازی نیست تا آنرا از بانک اطلاعاتی واکشی کنید. چون این اطلاعات هم اکنون در کوکی او موجود هستند.
سفارشی سازی کلاس UserClaimsPrincipalFactory جهت افزودن User Claims سفارشی
تا اینجا دریافتیم که کلاس UserClaimsPrincipalFactory کار مدیریت Claims پیشفرض این فریم ورک را برعهده دارد. در ادامه از این کلاس ارث بری کرده و متد CreateAsync آنرا جهت افزودن Claims سفارشی خود بازنویسی میکنیم. این پیاده سازی سفارشی را در کلاس ApplicationClaimsPrincipalFactory میتوانید مشاهده کنید:
public override async Task<ClaimsPrincipal> CreateAsync(User user) { var principal = await base.CreateAsync(user).ConfigureAwait(false); addCustomClaims(user, principal); return principal; } private static void addCustomClaims(User user, IPrincipal principal) { ((ClaimsIdentity) principal.Identity).AddClaims(new[] { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString(), ClaimValueTypes.Integer), new Claim(ClaimTypes.GivenName, user.FirstName ?? string.Empty), new Claim(ClaimTypes.Surname, user.LastName ?? string.Empty), new Claim(PhotoFileName, user.PhotoFileName ?? string.Empty, ClaimValueTypes.String), }); }
برای مثال نام، نام خانوادگی و نام تصویر شخص به صورت Claimهایی جدید به کوکی او اضافه میشوند. در این حالت دیگر نیازی نیست تا به ازای هر کاربر، جدول AppUserClaims را ویرایش کرد و اطلاعات جدیدی را افزود و یا تغییر داد. همینقدر که کاربر به سیستم لاگین کند، شیء User او به متد Create کلاس UserClaimsPrincipalFactory ارسال میشود. به این ترتیب میتوان به تمام خواص این کاربر دسترسی یافت و در صورت نیاز آنها را به صورت Claimهایی به کوکی او افزود.
پس از تدارک کلاس ApplicationClaimsPrincipalFactory، تنها کاری را که باید در جهت معرفی و جایگرینی آن انجام داد، تغییر ذیل در کلاس IdentityServicesRegistry است:
services.AddScoped<IUserClaimsPrincipalFactory<User>, ApplicationClaimsPrincipalFactory>(); services.AddScoped<UserClaimsPrincipalFactory<User, Role>, ApplicationClaimsPrincipalFactory>();
چگونه به اطلاعات User Claims در سرویسهای برنامه دسترسی پیدا کنیم؟
برای دسترسی به اطلاعات User Claims نیاز به دسترسی به HttpContext جاری را داریم. در این مورد و تزریق سرویس IHttpContextAccessor جهت تامین آن، در مطلب «بررسی روش دسترسی به HttpContext در ASP.NET Core» پیشتر بحث شدهاست.
به علاوه در کلاس IdentityServicesRegistry، تزریق وابستگیهای سفارشیتری نیز صورت گرفتهاست:
services.AddScoped<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>()?.HttpContext?.User ?? ClaimsPrincipal.Current);
چگونه اطلاعات User Claims سفارشی را دریافت کنیم؟
برای کار سادهتر با Claims یک کلاس کمکی به نام IdentityExtensions به پروژه اضافه شدهاست و متدهایی مانند دو متد ذیل را میتوانید در آن مشاهده کنید:
public static string FindFirstValue(this ClaimsIdentity identity, string claimType) { return identity?.FindFirst(claimType)?.Value; } public static string GetUserClaimValue(this IIdentity identity, string claimType) { var identity1 = identity as ClaimsIdentity; return identity1?.FindFirstValue(claimType); }
برای نمونه متد GetUserDisplayName این کلاس کمکی، از همان Claims سفارشی که در کلاس ApplicationClaimsPrincipalFactory تعریف کردیم، اطلاعات خود را استخراج میکند و اگر در View ایی خواستید این اطلاعات را نمایش دهید، میتوانید بنویسید:
@User.Identity.GetUserDisplayName()
چگونه پس از ویرایش اطلاعات کاربر، اطلاعات کوکی او را نیز به روز کنیم؟
در پروژه قسمتی وجود دارد جهت ویرایش اطلاعات کاربران (UserProfileController). اگر کاربری برای مثال نام و نام خانوادگی خود را ویرایش کرد، میخواهیم بلافاصله متد GetUserDisplayName اطلاعات صحیح و به روزی را از کوکی او دریافت کند. برای اینکار یا میتوان او را وادار به لاگین مجدد کرد (تا پروسهی رسیدن به متد CreateAsync کلاس ApplicationClaimsPrincipalFactory طی شود) و یا روش بهتری نیز وجود دارد:
// reflect the changes, in the current user's Identity cookie await _signInManager.RefreshSignInAsync(user).ConfigureAwait(false);
کدهای کامل این سری را در مخزن کد DNT Identity میتوانید ملاحظه کنید.
در این حالت هش کردن کلمات عبور ایدهی بهتر است. هشها روشهایی یک طرفه هستند که با داشتن نتیجهی نهایی آنها، نمیتوان به اصل کلمهی عبور مورد استفاده دسترسی پیدا کرد. برای بهبود امنیت هشهای تولیدی، میتوان از مفهومی به نام Salt نیز استفاده نمود. Salt در اصل یک رشتهی تصادفی است که پیش از هش شدن نهایی کلمهی عبور، به آن اضافه شده و سپس حاصل این جمع، هش خواهد شد. اهمیت این مساله در بالا بردن زمان یافتن کلمهی عبور اصلی از روی هش نهایی است (توسط روشهایی مانند brute force یا امتحان کردن بازهی وسیعی از عبارات قابل تصور).
اما واقعیت این است که حتی استفاده از یک Salt نیز نمیتواند امنیت بازیابی کلمات عبور هش شده را تضمین کند. برای مثال نرم افزارهایی موجود هستند که با استفاده از پرداش موازی قادرند بیش از 60 میلیارد هش را در یک ثانیه آزمایش کنند و البته این کارآیی، برای کار با هشهای متداولی مانند MD5 و SHA1 بهینه سازی شدهاست.
روش هش کردن کلمات عبور در ASP.NET Identity
ASP.NET Identity 2.x که در حال حاضر آخرین نگارش تکامل یافتهی روشهای امنیتی توصیه شدهی توسط مایکروسافت، برای برنامههای وب است، از استانداردی به نام RFC 2898 و الگوریتم PKDBF2 برای هش کردن کلمات عبور استفاده میکند. مهمترین مزیت این روش خاص، کندتر شدن الگوریتم آن با بالا رفتن تعداد سعیهای ممکن است؛ برخلاف الگوریتمهایی مانند MD5 یا SHA1 که اساسا برای رسیدن به نتیجه، در کمترین زمان ممکن طراحی شدهاند.
PBKDF2 یا password-based key derivation function جزئی از استاندارد RSA نیز هست (PKCS #5 version 2.0). در این الگوریتم، تعداد بار تکرار، یک Salt و یک کلمهی عبور تصادفی جهت بالا بردن انتروپی (بینظمی) کلمهی عبور اصلی، به آن اضافه میشوند. از تعداد بار تکرار برای تکرار الگوریتم هش کردن اطلاعات، به تعداد باری که مشخص شدهاست، استفاده میگردد. همین تکرار است که سبب کندشدن محاسبهی هش میگردد. عدد معمولی که برای این حالت توصیه شدهاست، 50 هزار است.
این استاندارد در دات نت توسط کلاس Rfc2898DeriveBytes پیاده سازی شدهاست که در ذیل مثالی را در مورد نحوهی استفادهی عمومی از آن، مشاهده میکنید:
using System; using System.Diagnostics; using System.Security.Cryptography; using System.Text; namespace IdentityHash { public static class PBKDF2 { public static byte[] GenerateSalt() { using (var randomNumberGenerator = new RNGCryptoServiceProvider()) { var randomNumber = new byte[32]; randomNumberGenerator.GetBytes(randomNumber); return randomNumber; } } public static byte[] HashPassword(byte[] toBeHashed, byte[] salt, int numberOfRounds) { using (var rfc2898 = new Rfc2898DeriveBytes(toBeHashed, salt, numberOfRounds)) { return rfc2898.GetBytes(32); } } } class Program { static void Main(string[] args) { var passwordToHash = "VeryComplexPassword"; hashPassword(passwordToHash, 50000); Console.ReadLine(); } private static void hashPassword(string passwordToHash, int numberOfRounds) { var sw = new Stopwatch(); sw.Start(); var hashedPassword = PBKDF2.HashPassword( Encoding.UTF8.GetBytes(passwordToHash), PBKDF2.GenerateSalt(), numberOfRounds); sw.Stop(); Console.WriteLine(); Console.WriteLine("Password to hash : {0}", passwordToHash); Console.WriteLine("Hashed Password : {0}", Convert.ToBase64String(hashedPassword)); Console.WriteLine("Iterations <{0}> Elapsed Time : {1}ms", numberOfRounds, sw.ElapsedMilliseconds); } } }
پیش فرضهای پیاده سازی Rfc2898DeriveBytes استفاده از الگوریتم SHA1 با 1000 بار تکرار است؛ چیزی که دقیقا در ASP.NET Identity 2.x بکار رفتهاست.
تفاوتهای الگوریتمهای هش کردن اطلاعات در نگارشهای مختلف ASP.NET Identity
اگر به سورس نگارش سوم ASP.NET Identity مراجعه کنیم، یک چنین کامنتی در ابتدای آن قابل مشاهده است:
/* ======================= * HASHED PASSWORD FORMATS * ======================= * * Version 2: * PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations. * (See also: SDL crypto guidelines v5.1, Part III) * Format: { 0x00, salt, subkey } * * Version 3: * PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations. * Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey } * (All UInt32s are stored big-endian.) */
در یک چنین حالتی بانک اطلاعاتی ASP.NET Identity 2.x شما با نگارش بعدی سازگار نخواهد بود و تمام کلمات عبور آن باید مجددا ریست شده و مطابق فرمت جدید هش شوند. بنابراین امکان انتخاب الگوریتم هش کردن را نیز پیش بینی کردهاند.
در نگارش دوم ASP.NET Identity، متد هش کردن یک کلمهی عبور، چنین شکلی را دارد:
public static string HashPassword(string password, int numberOfRounds = 1000) { if (password == null) throw new ArgumentNullException("password"); byte[] saltBytes; byte[] hashedPasswordBytes; using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 16, numberOfRounds)) { saltBytes = rfc2898DeriveBytes.Salt; hashedPasswordBytes = rfc2898DeriveBytes.GetBytes(32); } var outArray = new byte[49]; Buffer.BlockCopy(saltBytes, 0, outArray, 1, 16); Buffer.BlockCopy(hashedPasswordBytes, 0, outArray, 17, 32); return Convert.ToBase64String(outArray); }
روش پیاده سازی دریافت اطلاعات شخصی در ASP.NET Core Identity 2.1
اگر به IdentityUser نگارشهای اخیر ASP.NET Core Identity دقت کنید، شامل ویژگی جدید PersonalData نیز هست:
public class IdentityUser<TKey> where TKey : IEquatable<TKey> { [PersonalData] public virtual TKey Id { get; set; }
سپس زمانیکه در تصویر فوق بر روی دکمهی download کلیک کرد، ابتدا توسط userManager.GetUserAsync، اطلاعات کاربر جاری از بانک اطلاعاتی دریافت شده و سپس حلقهای بر روی تمام خواص شیء IdentityUser تشکیل میشود. در اینجا هر کدام که مزین به PersonalDataAttribute بود، مقدارش دریافت شده و به دیکشنری personalData اضافه میشود.
var personalData = new Dictionary<string, string>(); var personalDataProps = typeof(TUser).GetProperties().Where( prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute))); foreach (var p in personalDataProps) { personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null"); }
Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json"); return new FileContentResult(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(personalData)), "text/json");
روش پیاده سازی دادن «حق فراموش شدن» به کاربران
اگر به تصویر ارسال شده دقت کنید، یک دکمهی Delete نیز در آن قرار دارد. کار آن، حذف واقعی و فیزیکی کاربر جاری و تمام اطلاعات وابستهی به او از بانک اطلاعاتی است. این دکمه نیز بدون هیچ واسطی در اختیار خود کاربر قرار گرفتهاست. یعنی به این صورت نیست که ابتدا فرمی را پر کند و سپس شخص دیگری اکانت او را حذف کند.
روش پیاده سازی آن نیز به صورت زیر است:
var user = await _userManager.GetUserAsync(User); if (user == null) { return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } RequirePassword = await _userManager.HasPasswordAsync(user); if (RequirePassword) { if (!await _userManager.CheckPasswordAsync(user, Input.Password)) { ModelState.AddModelError(string.Empty, "Password not correct."); return Page(); } }
var result = await _userManager.DeleteAsync(user);
و در آخر، کوکی جاری شخص لاگین شده را نیز حذف میکند تا برای همیشه با او خداحافظی کند!
await _signInManager.SignOutAsync();