آموزش سفارشی کردن Asp.Net Identity با پایگاه داده خارجی
سه شنبه 4 آبان 1395Asp.Net Identity به این دلیل طراحی شده است تا به ما توانایی و قابلیت استفاده از Storage Providerهای مختلف را در برنامه های ASP.Net ، به ما بدهد . ما میتوانیم ازIdentity Providerهایی که با Net Framework. عرضه شده است استفاده کنیم و هم میتوانیم Providerهای خودمان را طراحی کنیم . در این مقاله به بررسی ایجاد Provider های سفارشی خواهیم پرداخت .
آموزش تصویری نصب و استفاده از Asp.Net Identity 2
دو دلیل اساسی برای ایجاد Providerهای سفارشی وجود دارد .
ما نیاز به ذخیرهسازی اطلاعات Identity در data sourceای راداریم که توسط Identity Provider ای که در
Net Framework. وجود دارد ، پشتیبانی نمیشود ، مثل پایگاه داده های MySQL ، یک پایگاه داده Oracle یا منابع داده های دیگر .
ما باید اطلاعات Identity را با استفاده از یک Database schema ای که با Provider ، Database schema ما متفاوت است ، مدیریت کنیم .
در مثالی که در ادامه مقاله مشاهده خواهید کرد ، ما قصد پیاده سازی و پیکربندی یک Identity Provider سفارشی با استفاده از ASP.Net MVC 5 را داریم .
ایجاد پروژه ASP.Net MVC :
Visual Studio راباز کرده و یک پروژه ASP.NET Web application ایجاد کنید و MVC Template را انتخاب کنید .
بعد از ایجاد شدن پروژه F5 را میزنیم تا برنامه اجرا شود . بعد اجرا Register را برای ساختن یک کاربر جدید میزنیم . مراحل زیر را دنبال کنید :
بعد از پر کردن فیلد های مربوط به ثبت نام Register را بزنید :
در Solution Explorer روی فولدر App_Data کلیک راست کرده و فولدر root آن را باز کنید :
خواهید دید که بعد از اجرای برنامه پایگاه داده ایی با نام aspnet-AspNetIdentity-20160402093629 ساخته خواهد شد ، asp.net از این پایگاه داده برای ذخیره سازی اطلاعات امنیتی نظیر username ، Password و ... استفاده خواهد کرد .
توجه داشته باشید که aspnet-AspNetIdentity-2016040209362 در پایگاه داده ساخته نشده است اما به آن ضمیمه شده است . پس ، ما پایگاه داده را به SQL Server منتقل میکنیم و آن برای Customize Identity استفاده میکنیم .
در Visual Studio در قسمت منو، روی View کلیک و سپس روی SQL Server Object Explorer کلیک کنید ، پایگاه داده خود را انتخاب کرده و فولدر Table را باز کنید :
پنج Table ساخته شده است :
AspNetRoles, AspNetUserClaims, AspNetUserLogins, AspNetUserRoles, AspNetUsers .
با ایجاد یک database diagram ما میتوانیم یک نگاه اجمالی به modelهای پایگاه داده خود داشته باشیم :
در نهایت ، فایل web.Config را باز کرده و مشخصات ConnectionString را برای پایگاه داده خود تنظیم کنید :
حال F5 را میزنیم تا برنامه اجرا شود ، بعد به سراغ ایجاد یک کاربر جدید میرویم :
درحال حاضر برنامه ما، برای استفاده از یک Storage خارجی آماده است . در مرحله بعد ، چگونگی سفارشی کردن پایگاه داده خارجی را برای شما بیان خواهیم کرد .
ایجاد Identity Library Project :
یک class library ایجاد کرده و نام آن را IdentityLibrary میگذاریم :
روی References کلیک راست کرده و Manage NuGet Packages را انتخاب کنید :
Microsoft.AspNet.Identity.Core و Microsoft.AspNet.Identity.EntityFramework را نصب کنید .
یک کلاس با نام IdentityUser برای نگهداری اطلاعات کاربران ایجاد کنید ، این کلاس از IdentityUser ارثبری میکند :
کلاس IdentityRole را برای نگهداری اطلاعات در مورد نقش کاربران را ایجاد کنید :
یک کلاس با نام UserStore ایجاد کنید ، Asp.Net MVC بصورت پیش فرض از این کلاس استفاده خواهد کرد :
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
اما با این وجود ، ما برای سفارشی کردن Storage Provider آن را پیاده سازی میکنیم :
برای پیاده سازی IRoleIdentity ، کلاسی با نام RoleStore میکنیم :
ایجاد یک Entity Framework dataModel :
روی پروژه IdentityLibrary راست کلیک کرده و add new item را بزنید ، ADO.NET Entity Data Model را انتخاب کرده و Add را بزنید :
Code First From Database را انتخاب کرده و Next را بزنید :
اگه ما یک data connection داریم میتوانیم آن را انتخاب کنیم یا اینکه یک connection جدید ایجاد کنیم :
Server Name را انتخاب کنید ، از Windows Authentication یا SQL Server Authentication استفاده کنید ،
سپس پایگاه داده مورد نظر را انتخاب کرده و Ok را بزنید :
جداول پایگاه داده را چک انتخاب کرده تا model ما را تولید کند :
خب ، پنج کلاس در پروژه IdentityLibrary ایجاد شده است ، که به جداول پایگاه داده متصل است :
برای هدف قرار دادن ASP.Net Client ، Custom Identity Library را پیکربندی میکنیم :
پیاده سازی Custom Identity :
• پیاده سازی UserStore :
/// <summary> /// Class that implements the key ASP.NET Identity user store iterfaces /// </summary> public class UserStore<T> : IUserRoleStore<T>, IUserStore<T>, IUserPasswordStore<T>, IUserEmailStore<T>, IUserLockoutStore<T, string>, IUserTwoFactorStore<T, string> where T : IdentityUser { private readonly UserRepository<T> _userTable; private readonly UserRolesRepository _userRolesTable; public UserStore(DatabaseContext databaseContext) { _userTable = new UserRepository<T>(databaseContext); _userRolesTable = new UserRolesRepository(databaseContext); } public Task CreateAsync(T user) { if (user == null) { throw new ArgumentNullException(“user”); } return Task.Run(() => _userTable.Insert(user)); } public Task<T> FindByIdAsync(string userId) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentException(“Null or empty argument: userId”); } return Task.Run(() => _userTable.GeTById(userId)); } public Task<bool> GetTwoFactorEnabledAsync(T user) { return Task.FromResult(user.TwoFactorEnabled); } public Task<T> FindByNameAsync(string userName) { if (string.IsNullOrEmpty(userName)) { throw new ArgumentException(“Null or empty argument: userName”); } return Task.Run(() => _userTable.GeTByName(userName)); } public Task<IList<string>> GetRolesAsync(T user) { if (user == null) { throw new ArgumentNullException(“user”); } return Task.Run(() => _userRolesTable.FindByUserId(user.Id)); } public Task<string> GetPasswordHashAsync(T user) { return Task.Run(() => _userTable.GetPasswordHash(user.Id)); } public Task SetPasswordHashAsync(T user, string passwordHash) { return Task.Run(() => user.PasswordHash = passwordHash); } public Task<T> FindByEmailAsync(string email) { if (String.IsNullOrEmpty(email)) { throw new ArgumentNullException(“email”); } return Task.Run(() => _userTable.GeTByEmail(email)); } public Task<string> GetEmailAsync(T user) { return Task.FromResult(user.Email); } public Task<int> GetAccessFailedCountAsync(T user) { return Task.FromResult(user.AccessFailedCount); } public Task<bool> GetLockoutEnabledAsync(T user) { return Task.FromResult(user.LockoutEnabled); } public Task<DateTimeOffset> GetLockoutEndDateAsync(T user) { return Task.FromResult(user.LockoutEndDateUtc.HasValue ? new DateTimeOffset(DateTime.SpecifyKind(user.LockoutEndDateUtc.Value, DateTimeKind.Utc)) : new DateTimeOffset()); } public Task SetLockoutEnabledAsync(T user, bool enabled) { user.LockoutEnabled = enabled; return Task.Run(() => _userTable.Update(user)); } public Task SetLockoutEndDateAsync(T user, DateTimeOffset lockoutEnd) { throw new NotImplementedException(); } public Task SetTwoFactorEnabledAsync(T user, bool enabled) { throw new NotImplementedException(); } public Task DeleteAsync(T user) { throw new NotImplementedException(); } public Task<int> IncrementAccessFailedCountAsync(T user) { throw new NotImplementedException(); } public Task ResetAccessFailedCountAsync(T user) { throw new NotImplementedException(); } public Task<bool> GetEmailConfirmedAsync(T user) { throw new NotImplementedException(); } public Task SetEmailAsync(T user, string email) { throw new NotImplementedException(); } public Task SetEmailConfirmedAsync(T user, bool confirmed) { throw new NotImplementedException(); } public Task<bool> IsInRoleAsync(T user, string roleName) { throw new NotImplementedException(); } public Task RemoveFromRoleAsync(T user, string roleName) { throw new NotImplementedException(); } public Task<bool> HasPasswordAsync(T user) { throw new NotImplementedException(); } public Task UpdateAsync(T user) { throw new NotImplementedException(); } public Task AddToRoleAsync(T user, string roleName) { throw new NotImplementedException(); } public void Dispose() { //throw new NotImplementedException(); } }
• ایجاد یک کلاس UserRepository و پیادهسازی آن :
public class UserRepository<T> where T : IdentityUser { private readonly DatabaseContext _databaseContext; public UserRepository(DatabaseContext databaseContext) { _databaseContext = databaseContext; } internal T GeTByName(string userName) { var user = _databaseContext.AspNetUsers.SingleOrDefault(u => u.UserName == userName); if (user != null) { T result = (T)Activator.CreateInstance(typeof(T)); result.Id = user.Id; result.UserName = user.UserName; result.PasswordHash = user.PasswordHash; result.SecurityStamp = user.SecurityStamp; result.Email = result.Email; result.EmailConfirmed = user.EmailConfirmed; result.PhoneNumber = user.PhoneNumber; result.PhoneNumberConfirmed = user.PhoneNumberConfirmed; result.LockoutEnabled = user.LockoutEnabled; result.LockoutEndDateUtc = user.LockoutEndDateUtc; result.AccessFailedCount = user.AccessFailedCount; return result; } return null; } internal T GeTByEmail(string email) { var user = _databaseContext.AspNetUsers.SingleOrDefault(u => u.Email == email); if (user != null) { T result = (T)Activator.CreateInstance(typeof(T)); result.Id = user.Id; result.UserName = user.UserName; result.PasswordHash = user.PasswordHash; result.SecurityStamp = user.SecurityStamp; result.Email = result.Email; result.EmailConfirmed = user.EmailConfirmed; result.PhoneNumber = user.PhoneNumber; result.PhoneNumberConfirmed = user.PhoneNumberConfirmed; result.LockoutEnabled = user.LockoutEnabled; result.LockoutEndDateUtc = user.LockoutEndDateUtc; result.AccessFailedCount = user.AccessFailedCount; return result; } return null; } internal int Insert(T user) { _databaseContext.AspNetUsers.Add(new AspNetUsers { Id = user.Id, UserName = user.UserName, PasswordHash = user.PasswordHash, SecurityStamp = user.SecurityStamp, Email = user.Email, EmailConfirmed = user.EmailConfirmed, PhoneNumber = user.PhoneNumber, PhoneNumberConfirmed = user.PhoneNumberConfirmed, LockoutEnabled = user.LockoutEnabled, LockoutEndDateUtc = user.LockoutEndDateUtc, AccessFailedCount = user.AccessFailedCount }); return _databaseContext.SaveChanges(); } /// <summary> /// Returns an T given the user’s id /// </summary> /// <param name=”userId”>The user’s id</param> /// <returns></returns> public T GeTById(string userId) { var user = _databaseContext.AspNetUsers.Find(userId); T result = (T)Activator.CreateInstance(typeof(T)); result.Id = user.Id; result.UserName = user.UserName; result.PasswordHash = user.PasswordHash; result.SecurityStamp = user.SecurityStamp; result.Email = result.Email; result.EmailConfirmed = user.EmailConfirmed; result.PhoneNumber = user.PhoneNumber; result.PhoneNumberConfirmed = user.PhoneNumberConfirmed; result.LockoutEnabled = user.LockoutEnabled; result.LockoutEndDateUtc = user.LockoutEndDateUtc; result.AccessFailedCount = user.AccessFailedCount; return result; } /// <summary> /// Return the user’s password hash /// </summary> /// <param name=”userId”>The user’s id</param> /// <returns></returns> public string GetPasswordHash(string userId) { var user = _databaseContext.AspNetUsers.FirstOrDefault(u => u.Id == userId); var passHash = user != null ? user.PasswordHash : null; return passHash; } /// <summary> /// Updates a user in the Users table /// </summary> /// <param name=”user”></param> /// <returns></returns> public int Update(T user) { var result = _databaseContext.AspNetUsers.FirstOrDefault(u => u.Id == user.Id); if (result != null) { result.UserName = user.UserName; result.PasswordHash = user.PasswordHash; result.SecurityStamp = user.SecurityStamp; result.Email = result.Email; result.EmailConfirmed = user.EmailConfirmed; result.PhoneNumber = user.PhoneNumber; result.PhoneNumberConfirmed = user.PhoneNumberConfirmed; result.LockoutEnabled = user.LockoutEnabled; result.LockoutEndDateUtc = user.LockoutEndDateUtc; result.AccessFailedCount = user.AccessFailedCount; return _databaseContext.SaveChanges(); } return 0; } }
• ایجاد یک کلاس UserRolesRepository و پیاده سازی آن :
حال ، برنامه ما برای استفاده از IdentityLibrary آماده است .
آموزش asp.net mvc
- ASP.net MVC
- 3k بازدید
- 10 تشکر