關於AspNet.Identity,參考:http://www.cnblogs.com/shanyou/p/3918178.html html
關於OWIN,能夠閱讀:http://www.cnblogs.com/dudu/p/what-is-owin.html 數據庫
OWIN使ASP.NET應用運行在其它平臺上稱爲可能。對ASP.NET程序和IIS進行解耦。咱們能夠在沒有安裝IIS的狀況下,運行ASP.NET程序。在這裏http://katanaproject.codeplex.com/能夠下載源碼。 c#
另外一個概念就是基於聲明(Claim)的認證機制。 數組
首先,這種機制並不是微軟特有的,Claims-based認證和受權在國外被普遍使用,包括微軟的ADFS,Google,Facebook等。 安全
Claims-based認證的主要特色: cookie
接下來,咱們會使用到兩個對象Microsoft.AspNet.Identity.UserManager和Microsoft.AspNet.Identity.Owin.SignInManager,固然,在不使用Microsoft.AspNet.Identity.Owin.SignInManager的狀況下,咱們依然能夠完成認證工做。在這裏,我手動建立了兩個類,分別集成前兩個類。代碼以下: app
TiKuSignInManager 類:
using System; using System.Collections.Generic; using System.Linq; using System.Web; /****************************************************************************************************************** * * * 說 明: (版本:Version1.0.0) * 做 者:李朝強 * 日 期:2015/05/19 * 修 改: * 參 考:http://my.oschina.net/lichaoqiang/ * 備 注:暫無... * * * ***************************************************************************************************************/ namespace AspNetIdentity.Models { public class TiKuSignInManager : Microsoft.AspNet.Identity.Owin.SignInManager<TiKuUser, Guid> { /// <summary> /// 構造函數 /// </summary> /// <param name="UserManager"></param> /// <param name="AuthenticationManager"></param> public TiKuSignInManager(Microsoft.AspNet.Identity.UserManager<TiKuUser, Guid> UserManager, Microsoft.Owin.Security.IAuthenticationManager AuthenticationManager) : base(UserManager, AuthenticationManager) { } /// <summary> /// 根據用戶名密碼,驗證用戶登陸 /// </summary> /// <param name="userName"></param> /// <param name="password"></param> /// <param name="isPersistent"></param> /// <param name="shouldLockout"></param> /// <returns></returns> public override System.Threading.Tasks.Task<Microsoft.AspNet.Identity.Owin.SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout) { return base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout); } } }
TiKuUserManager 類:
using Microsoft.AspNet.Identity; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Web; namespace AspNetIdentity.Models { public class TiKuUserManager : Microsoft.AspNet.Identity.UserManager<TiKuUser, Guid> { /// <summary> /// 構造函數 /// </summary> /// <param name="store"></param> public TiKuUserManager(TiKuUserStore store) : base(store) { //採用老的加密程序 this.PasswordHasher = new OldSystemPasswordHasher(); } /// <summary> /// Use Custom approach to verify password /// </summary> public class OldSystemPasswordHasher : PasswordHasher { /// <summary> /// 對密碼進行Hash加密 /// </summary> /// <param name="password"></param> /// <returns></returns> public override string HashPassword(string password) { byte[] salt; byte[] buffer2; if (password == null) { throw new ArgumentNullException("password"); } using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8)) { salt = bytes.Salt; buffer2 = bytes.GetBytes(0x20); } byte[] dst = new byte[0x31]; Buffer.BlockCopy(salt, 0, dst, 1, 0x10); Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20); return Convert.ToBase64String(dst); } /// <summary> /// 重寫驗證密碼的方法 /// </summary> /// <param name="hashedPassword">加密後的密碼</param> /// <param name="providedPassword">提供的密碼</param> /// <returns></returns> public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) { byte[] buffer4; if (hashedPassword == null) { return PasswordVerificationResult.Failed; } if (string.IsNullOrEmpty(providedPassword)) { throw new ArgumentNullException("providedPassword"); } byte[] src = Convert.FromBase64String(hashedPassword); if ((src.Length != 0x31) || (src[0] != 0)) { return PasswordVerificationResult.Failed; } byte[] dst = new byte[0x10]; Buffer.BlockCopy(src, 1, dst, 0, 0x10); byte[] buffer3 = new byte[0x20]; Buffer.BlockCopy(src, 0x11, buffer3, 0, 0x20); using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(providedPassword, dst, 0x3e8)) { buffer4 = bytes.GetBytes(0x20); } if (ByteEqual(buffer3, buffer4)) { return PasswordVerificationResult.Success; } else { return PasswordVerificationResult.Failed; } } /// <summary> /// 比較兩個字節數組 /// </summary> /// <param name="b1"></param> /// <param name="b2"></param> /// <returns></returns> private static bool ByteEqual(byte[] b1, byte[] b2) { if (b1.Length != b2.Length) return false; if (b1 == null || b2 == null) return false; for (int i = 0; i < b1.Length; i++) { if (b1[i] != b2[i]) { return false; } } return true; } } } }這兩個類,爲咱們提供了用戶認證經常使用的方法。接下來,你在建立UserManager類的時候,發現,須要提供Microsoft.AspNet.Identity.IUserStore<TiKuUser, Guid>類型對象來構造UserManager對象,因而我繼承了這個Microsoft.AspNet.Identity.IUserStore<TiKuUser, Guid>接口:
using Microsoft.AspNet.Identity; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; using System.Web; /****************************************************************************************************************** * * * 說 明:TiKuUserStore (版本:Version1.0.0) * 做 者:李朝強 * 日 期:2015/05/19 * 修 改: * 參 考:http://my.oschina.net/lichaoqiang/ * 備 注:暫無... * IUserLockoutStore<User, TKey>: 在嘗試必定的失敗次數後容許鎖定一個帳號 IUserEmailStore<User, TKey>: 使用郵件地址作確認 (例如經過郵件進行確認) IUserPhoneNumberStore<User, TKey>: 使用手機號碼作確認(例如經過短信進行確認) IUserTwoFactorStore<User, TKey>: 啓用2中途徑進行安全驗證 (例如經過用戶名/密碼和經過郵件或者短信的令牌),當用戶密碼可能存在不安全隱患的時候,系統會以短信或郵件的方式向用戶發送安全碼 * * ***************************************************************************************************************/ namespace AspNetIdentity.Models { public class TiKuUserStore : Microsoft.AspNet.Identity.IUserStore<TiKuUser, Guid>, IUserPasswordStore<TiKuUser, Guid>, IUserClaimStore<TiKuUser, Guid>, IUserLockoutStore<TiKuUser, Guid>, IUserEmailStore<TiKuUser, Guid>, IUserPhoneNumberStore<TiKuUser, Guid>, IUserTwoFactorStore<TiKuUser, Guid> { /// <summary> /// 聲明 /// </summary> public IList<System.Security.Claims.Claim> Claims = null; /// <summary> /// 實例化 /// </summary> public TiKuUserStore() { //聲明 Claims = new List<System.Security.Claims.Claim>(); } /// <summary> /// 用戶 /// </summary> public TiKuUser UserIdentity = null; /// <summary> /// 建立用戶 /// </summary> /// <param name="user"></param> /// <returns></returns> public System.Threading.Tasks.Task CreateAsync(TiKuUser user) { return Task.Run(() => { string strInsertCmd = @"INSERT INTO[tb_User](ID,UserName,UserPwd) VALUES(@UserID,@UserName,@UserPwd);"; SqlParameter[] parameters = { new SqlParameter("@UserName",SqlDbType.NVarChar,30), new SqlParameter("@UserPwd",SqlDbType.NVarChar,100), new SqlParameter("@UserID",SqlDbType.UniqueIdentifier) }; parameters[0].Value = user.UserName; parameters[1].Value = user.Password; parameters[2].Value = user.Id; int iResult = DbHelper.ExecuteNonQuery(strInsertCmd, parameters); }); } /// <summary> /// 刪除用戶 /// </summary> /// <param name="user"></param> /// <returns></returns> public System.Threading.Tasks.Task DeleteAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 2>經過用戶ID,獲取用戶 /// </summary> /// <param name="userId"></param> /// <returns></returns> public System.Threading.Tasks.Task<TiKuUser> FindByIdAsync(Guid userId) { return Task<TiKuUser>.Run<TiKuUser>(() => { if (UserIdentity != null) { return UserIdentity; } string strCmd = "SELECT * FROM [tb_User] WHERE ID=@UserID;"; SqlParameter[] parameters = { new SqlParameter("@UserID", SqlDbType.UniqueIdentifier) }; parameters[0].Value = userId; List<TiKuUser> list = new List<TiKuUser>(); using (IDataReader data = DbHelper.ExecuteReader(strCmd, parameters)) { while (data.Read()) { //model TiKuUser user = new TiKuUser(); user.Id = Guid.Parse(data["ID"].ToString()); user.UserName = data["UserName"].ToString(); user.Password = data["UserPwd"].ToString(); list.Add(user); } } UserIdentity = list.FirstOrDefault(); return UserIdentity; }); } /// <summary> /// 1>經過用戶名獲取用戶信息 /// </summary> /// <param name="userName"></param> /// <returns></returns> public System.Threading.Tasks.Task<TiKuUser> FindByNameAsync(string userName) { return Task<TiKuUser>.Run<TiKuUser>(() => { if (UserIdentity != null) { return UserIdentity; } string strCmd = "SELECT * FROM [tb_User] WHERE UserName=@UserName;"; SqlParameter[] parameters = { new SqlParameter("@UserName", SqlDbType.NVarChar, 30) }; parameters[0].Value = userName; List<TiKuUser> list = new List<TiKuUser>(); using (IDataReader data = DbHelper.ExecuteReader(strCmd, parameters)) { while (data.Read()) { //model TiKuUser user = new TiKuUser(); user.Id = Guid.Parse(data["ID"].ToString()); user.UserName = data["UserName"].ToString(); user.Password = data["UserPwd"].ToString(); list.Add(user); } } //模擬數據庫 UserIdentity = list.FirstOrDefault(); return UserIdentity; }); } /// <summary> /// 更新用戶信息 /// </summary> /// <param name="user"></param> /// <returns></returns> public System.Threading.Tasks.Task UpdateAsync(TiKuUser user) { return Task.Run(() => { }); } /// <summary> /// 釋放 /// </summary> public void Dispose() { throw new NotImplementedException(); } /// <summary> /// 獲取密碼 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<string> GetPasswordHashAsync(TiKuUser user) { return Task<string>.Run(() => { return user.Password; }); } /// <summary> /// 是否有密碼 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> HasPasswordAsync(TiKuUser user) { return Task.FromResult<bool>(!string.IsNullOrEmpty(user.Password)); } /// <summary> /// 密碼進行加密 /// </summary> /// <param name="user"></param> /// <param name="passwordHash"></param> /// <returns></returns> public Task SetPasswordHashAsync(TiKuUser user, string passwordHash) { return Task.Run(() => { user.Password = passwordHash;//加密後 }); } /// <summary> /// 添加一個聲明 /// </summary> /// <param name="user"></param> /// <param name="claim"></param> /// <returns></returns> public Task AddClaimAsync(TiKuUser user, System.Security.Claims.Claim claim) { return Task.Run(() => { Claims.Add(claim); }); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<IList<System.Security.Claims.Claim>> GetClaimsAsync(TiKuUser user) { return Task.Run<IList<System.Security.Claims.Claim>>(() => { IList<System.Security.Claims.Claim> list = new List<System.Security.Claims.Claim>(); //聲明 //System.Security.Claims.Claim claimUserName = new System.Security.Claims.Claim("nick", user.UserName);//UserName //System.Security.Claims.Claim claimUserId = new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.NameIdentifier, user.Id.ToString());//UserId //list.Add(claimUserName); //list.Add(claimUserId); return list; }); } /// <summary> /// 移除聲明 /// </summary> /// <param name="user"></param> /// <param name="claim"></param> /// <returns></returns> public Task RemoveClaimAsync(TiKuUser user, System.Security.Claims.Claim claim) { throw new NotImplementedException(); } /// <summary> /// 獲取訪問失敗次數 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<int> GetAccessFailedCountAsync(TiKuUser user) { return Task<Int32>.FromResult<Int32>(1); } /// <summary> /// 獲取鎖定狀態 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetLockoutEnabledAsync(TiKuUser user) { return Task<bool>.Run<bool>(() => { return false; }); } /// <summary> /// 獲取鎖定結束時間 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<DateTimeOffset> GetLockoutEndDateAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<int> IncrementAccessFailedCountAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 重置訪問時間計數 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task ResetAccessFailedCountAsync(TiKuUser user) { return Task.FromResult(false); } #region LockOut /// <summary> /// 修改鎖定狀態 /// </summary> /// <param name="user"></param> /// <param name="enabled"></param> /// <returns></returns> public Task SetLockoutEnabledAsync(TiKuUser user, bool enabled) { return Task.Run(() => { }); } /// <summary> /// 設置鎖定時間 /// </summary> /// <param name="user"></param> /// <param name="lockoutEnd"></param> /// <returns></returns> public Task SetLockoutEndDateAsync(TiKuUser user, DateTimeOffset lockoutEnd) { return Task.Run(() => { }); } #endregion #region Email /// <summary> /// 經過郵箱獲取用戶信息 /// </summary> /// <param name="email"></param> /// <returns></returns> public Task<TiKuUser> FindByEmailAsync(string email) { throw new NotImplementedException(); } /// <summary> /// 獲取用戶郵箱 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<string> GetEmailAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 確認郵件 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetEmailConfirmedAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 修改郵箱 /// </summary> /// <param name="user"></param> /// <param name="email"></param> /// <returns></returns> public Task SetEmailAsync(TiKuUser user, string email) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="confirmed"></param> /// <returns></returns> public Task SetEmailConfirmedAsync(TiKuUser user, bool confirmed) { throw new NotImplementedException(); } #endregion #region Phone /// <summary> /// 獲取手機號 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<string> GetPhoneNumberAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetPhoneNumberConfirmedAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="phoneNumber"></param> /// <returns></returns> public Task SetPhoneNumberAsync(TiKuUser user, string phoneNumber) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="confirmed"></param> /// <returns></returns> public Task SetPhoneNumberConfirmedAsync(TiKuUser user, bool confirmed) { throw new NotImplementedException(); } #endregion /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetTwoFactorEnabledAsync(TiKuUser user) { return Task.Run<bool>(() => { return false; }); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="enabled"></param> /// <returns></returns> public Task SetTwoFactorEnabledAsync(TiKuUser user, bool enabled) { return Task.Run(() => { }); } } }下面,咱們看看註冊方法該怎麼寫,在這裏,我用MVC5做爲代碼示例,在解決方案中,建立AccountController控制器:
[Authorize] public class AccountController : Controller { /// <summary> ///註冊:這裏省事,沒有寫UI /// </summary> /// <param name="user"></param> /// <returns></returns> [AllowAnonymous] public async Task<ActionResult> Register() { //user TiKuUser user = new TiKuUser { Id = Guid.NewGuid(), UserName = "chaoqiangli", Password = "XXXX" }; //Context Microsoft.Owin.IOwinContext OwinContext = HttpContext.GetOwinContext(); //用戶儲存 Models.TiKuUserStore userStore = new Models.TiKuUserStore(); //UserManager TiKuUserManager UserManager = new TiKuUserManager(userStore); IdentityResult result = await UserManager.CreateAsync(user, user.Password); if (result.Succeeded) { Response.Write("註冊成功!"); } return View(); } }
咱們來看看,Models.TiKuUserStore 對象都完成了那些工做。 async
using Microsoft.AspNet.Identity; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; using System.Web; /****************************************************************************************************************** * * * 說 明:TiKuUserStore (版本:Version1.0.0) * 做 者:李朝強 * 日 期:2015/05/19 * 修 改: * 參 考:http://my.oschina.net/lichaoqiang/ * 備 注:暫無... * IUserLockoutStore<User, TKey>: 在嘗試必定的失敗次數後容許鎖定一個帳號 IUserEmailStore<User, TKey>: 使用郵件地址作確認 (例如經過郵件進行確認) IUserPhoneNumberStore<User, TKey>: 使用手機號碼作確認(例如經過短信進行確認) IUserTwoFactorStore<User, TKey>: 啓用2中途徑進行安全驗證 (例如經過用戶名/密碼和經過郵件或者短信的令牌),當用戶密碼可能存在不安全隱患的時候,系統會以短信或郵件的方式向用戶發送安全碼 * * ***************************************************************************************************************/ namespace AspNetIdentity.Models { public class TiKuUserStore : Microsoft.AspNet.Identity.IUserStore<TiKuUser, Guid>, IUserPasswordStore<TiKuUser, Guid>, IUserClaimStore<TiKuUser, Guid>, IUserLockoutStore<TiKuUser, Guid>, IUserEmailStore<TiKuUser, Guid>, IUserPhoneNumberStore<TiKuUser, Guid>, IUserTwoFactorStore<TiKuUser, Guid> { /// <summary> /// 聲明 /// </summary> public IList<System.Security.Claims.Claim> Claims = null; /// <summary> /// 實例化 /// </summary> public TiKuUserStore() { //聲明 Claims = new List<System.Security.Claims.Claim>(); } /// <summary> /// 用戶 /// </summary> public TiKuUser UserIdentity = null; /// <summary> /// 建立用戶 /// </summary> /// <param name="user"></param> /// <returns></returns> public System.Threading.Tasks.Task CreateAsync(TiKuUser user) { return Task.Run(() => { string strInsertCmd = @"INSERT INTO[tb_User](ID,UserName,UserPwd) VALUES(@UserID,@UserName,@UserPwd);"; SqlParameter[] parameters = { new SqlParameter("@UserName",SqlDbType.NVarChar,30), new SqlParameter("@UserPwd",SqlDbType.NVarChar,100), new SqlParameter("@UserID",SqlDbType.UniqueIdentifier) }; parameters[0].Value = user.UserName; parameters[1].Value = user.Password; parameters[2].Value = user.Id; int iResult = DbHelper.ExecuteNonQuery(strInsertCmd, parameters); }); } /// <summary> /// 刪除用戶 /// </summary> /// <param name="user"></param> /// <returns></returns> public System.Threading.Tasks.Task DeleteAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 2>經過用戶ID,獲取用戶 /// </summary> /// <param name="userId"></param> /// <returns></returns> public System.Threading.Tasks.Task<TiKuUser> FindByIdAsync(Guid userId) { return Task<TiKuUser>.Run<TiKuUser>(() => { if (UserIdentity != null) { return UserIdentity; } string strCmd = "SELECT * FROM [tb_User] WHERE ID=@UserID;"; SqlParameter[] parameters = { new SqlParameter("@UserID", SqlDbType.UniqueIdentifier) }; parameters[0].Value = userId; List<TiKuUser> list = new List<TiKuUser>(); using (IDataReader data = DbHelper.ExecuteReader(strCmd, parameters)) { while (data.Read()) { //model TiKuUser user = new TiKuUser(); user.Id = Guid.Parse(data["ID"].ToString()); user.UserName = data["UserName"].ToString(); user.Password = data["UserPwd"].ToString(); list.Add(user); } } UserIdentity = list.FirstOrDefault(); return UserIdentity; }); } /// <summary> /// 1>經過用戶名獲取用戶信息 /// </summary> /// <param name="userName"></param> /// <returns></returns> public System.Threading.Tasks.Task<TiKuUser> FindByNameAsync(string userName) { return Task<TiKuUser>.Run<TiKuUser>(() => { if (UserIdentity != null) { return UserIdentity; } string strCmd = "SELECT * FROM [tb_User] WHERE UserName=@UserName;"; SqlParameter[] parameters = { new SqlParameter("@UserName", SqlDbType.NVarChar, 30) }; parameters[0].Value = userName; List<TiKuUser> list = new List<TiKuUser>(); using (IDataReader data = DbHelper.ExecuteReader(strCmd, parameters)) { while (data.Read()) { //model TiKuUser user = new TiKuUser(); user.Id = Guid.Parse(data["ID"].ToString()); user.UserName = data["UserName"].ToString(); user.Password = data["UserPwd"].ToString(); list.Add(user); } } //模擬數據庫 UserIdentity = list.FirstOrDefault(); return UserIdentity; }); } /// <summary> /// 更新用戶信息 /// </summary> /// <param name="user"></param> /// <returns></returns> public System.Threading.Tasks.Task UpdateAsync(TiKuUser user) { return Task.Run(() => { }); } /// <summary> /// 釋放 /// </summary> public void Dispose() { throw new NotImplementedException(); } /// <summary> /// 獲取密碼 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<string> GetPasswordHashAsync(TiKuUser user) { return Task<string>.Run(() => { return user.Password; }); } /// <summary> /// 是否有密碼 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> HasPasswordAsync(TiKuUser user) { return Task.FromResult<bool>(!string.IsNullOrEmpty(user.Password)); } /// <summary> /// 密碼進行加密 /// </summary> /// <param name="user"></param> /// <param name="passwordHash"></param> /// <returns></returns> public Task SetPasswordHashAsync(TiKuUser user, string passwordHash) { return Task.Run(() => { user.Password = passwordHash;//加密後 }); } /// <summary> /// 添加一個聲明 /// </summary> /// <param name="user"></param> /// <param name="claim"></param> /// <returns></returns> public Task AddClaimAsync(TiKuUser user, System.Security.Claims.Claim claim) { return Task.Run(() => { Claims.Add(claim); }); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<IList<System.Security.Claims.Claim>> GetClaimsAsync(TiKuUser user) { return Task.Run<IList<System.Security.Claims.Claim>>(() => { IList<System.Security.Claims.Claim> list = new List<System.Security.Claims.Claim>(); //聲明 //System.Security.Claims.Claim claimUserName = new System.Security.Claims.Claim("nick", user.UserName);//UserName //System.Security.Claims.Claim claimUserId = new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.NameIdentifier, user.Id.ToString());//UserId //list.Add(claimUserName); //list.Add(claimUserId); return list; }); } /// <summary> /// 移除聲明 /// </summary> /// <param name="user"></param> /// <param name="claim"></param> /// <returns></returns> public Task RemoveClaimAsync(TiKuUser user, System.Security.Claims.Claim claim) { throw new NotImplementedException(); } /// <summary> /// 獲取訪問失敗次數 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<int> GetAccessFailedCountAsync(TiKuUser user) { return Task<Int32>.FromResult<Int32>(1); } /// <summary> /// 獲取鎖定狀態 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetLockoutEnabledAsync(TiKuUser user) { return Task<bool>.Run<bool>(() => { return false; }); } /// <summary> /// 獲取鎖定結束時間 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<DateTimeOffset> GetLockoutEndDateAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<int> IncrementAccessFailedCountAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 重置訪問時間計數 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task ResetAccessFailedCountAsync(TiKuUser user) { return Task.FromResult(false); } #region LockOut /// <summary> /// 修改鎖定狀態 /// </summary> /// <param name="user"></param> /// <param name="enabled"></param> /// <returns></returns> public Task SetLockoutEnabledAsync(TiKuUser user, bool enabled) { return Task.Run(() => { }); } /// <summary> /// 設置鎖定時間 /// </summary> /// <param name="user"></param> /// <param name="lockoutEnd"></param> /// <returns></returns> public Task SetLockoutEndDateAsync(TiKuUser user, DateTimeOffset lockoutEnd) { return Task.Run(() => { }); } #endregion #region Email /// <summary> /// 經過郵箱獲取用戶信息 /// </summary> /// <param name="email"></param> /// <returns></returns> public Task<TiKuUser> FindByEmailAsync(string email) { throw new NotImplementedException(); } /// <summary> /// 獲取用戶郵箱 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<string> GetEmailAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 確認郵件 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetEmailConfirmedAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// 修改郵箱 /// </summary> /// <param name="user"></param> /// <param name="email"></param> /// <returns></returns> public Task SetEmailAsync(TiKuUser user, string email) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="confirmed"></param> /// <returns></returns> public Task SetEmailConfirmedAsync(TiKuUser user, bool confirmed) { throw new NotImplementedException(); } #endregion #region Phone /// <summary> /// 獲取手機號 /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<string> GetPhoneNumberAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetPhoneNumberConfirmedAsync(TiKuUser user) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="phoneNumber"></param> /// <returns></returns> public Task SetPhoneNumberAsync(TiKuUser user, string phoneNumber) { throw new NotImplementedException(); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="confirmed"></param> /// <returns></returns> public Task SetPhoneNumberConfirmedAsync(TiKuUser user, bool confirmed) { throw new NotImplementedException(); } #endregion /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> public Task<bool> GetTwoFactorEnabledAsync(TiKuUser user) { return Task.Run<bool>(() => { return false; }); } /// <summary> /// /// </summary> /// <param name="user"></param> /// <param name="enabled"></param> /// <returns></returns> public Task SetTwoFactorEnabledAsync(TiKuUser user, bool enabled) { return Task.Run(() => { }); } } }如今,咱們能夠編寫用戶註冊的方法了,這是,咱們會用到另外一個對象,TiKuUser,它繼承自Microsoft.AspNet.Identity.IUser<Guid>接口,根據實際狀況,咱們能夠去拓展它。
using Microsoft.AspNet.Identity; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Web; namespace AspNetIdentity.Models { public class TiKuUser : Microsoft.AspNet.Identity.IUser<Guid> { /// <summary> /// 用戶編號 /// </summary> public Guid Id { get; set; } /// <summary> /// /// </summary> [DisplayName("登陸名")] public string UserName { get; set; } /// <summary> /// 密碼 /// </summary> [DisplayName("密碼")] public string Password { get; set; } /// <summary> /// 暱稱 /// </summary> [DisplayName("暱稱")] public string Nick { get; set; } } }這樣,就完成了用戶的註冊。接下來,就是用戶認證的過程了。這時,你會發現,Microsoft.AspNet.Identity.Owin.SignInManager爲咱們提供了豐富的方法,來完成用戶的認證。認證成功後,會向客戶端發送加密的Cookie。這時,咱們可經過HttpContext.Current.User對象,來獲取認證信息。
登陸代碼以下: ide
/// <summary> /// 登錄 /// </summary> /// <param name="user"></param> /// <returns></returns> [HttpPost] [AllowAnonymous] public async Task<ActionResult> Login(TiKuUser @user) { if (string.IsNullOrEmpty(@user.UserName)) { return View(); } if (string.IsNullOrEmpty(@user.Password)) { return View(); } //Context Microsoft.Owin.IOwinContext OwinContext = HttpContext.GetOwinContext(); //實例化UserStore對象 Models.TiKuUserStore userStore = new Models.TiKuUserStore(); //UserManager TiKuUserManager UserManager = new TiKuUserManager(userStore); //signInManager TiKuSignInManager signInManager = new TiKuSignInManager(UserManager, AutherticationManager); //登陸 Microsoft.AspNet.Identity.Owin.SignInStatus SignInStatus = await signInManager.PasswordSignInAsync(@user.UserName, @user.Password, true, shouldLockout: false); //狀態 switch (SignInStatus) { //成功 case Microsoft.AspNet.Identity.Owin.SignInStatus.Success: //標示 //System.Security.Claims.ClaimsIdentity identity = UserManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie); //受權登錄 //AutherticationManager.SignIn(new Microsoft.Owin.Security.AuthenticationProperties { IsPersistent = true }, identity); return RedirectToAction("index", "home"); //鎖定 case Microsoft.AspNet.Identity.Owin.SignInStatus.LockedOut: Response.Write("LockedOut!"); break; //要求驗證 case Microsoft.AspNet.Identity.Owin.SignInStatus.RequiresVerification: Response.Write("RequiresVerification!"); break; //登陸失敗 case Microsoft.AspNet.Identity.Owin.SignInStatus.Failure: Response.Write("Failure!"); break; } return View(@user); } }咱們來看看實際效果吧。
這裏,作了個簡單的登陸表單。登陸成功後,會發現,客戶端多了一長串Cookie。 函數
這是加密後的用戶登陸憑據。這樣,用戶認證成功後,就能夠訪問到[Authorize]的Action了。
咱們在建立MVC項目的時候,有兩個文件須要注意下,就是根目錄下的Startup.cs和App_Start目錄下的Startup.Auth.cs兩個類,它們以分佈類的形式,存放於解決方案不一樣目錄中。咱們看看Startup都作了那些工做。
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; /****************************************************************************************************************** * * * 說 明: Startup(版本:Version1.0.0) * 做 者:李朝強 * 日 期:2015/05/19 * 修 改: * 參 考:http://my.oschina.net/lichaoqiang/ * 備 注:暫無... * * * ***************************************************************************************************************/ [assembly: OwinStartup(typeof(AspNetIdentity.Startup))] namespace AspNetIdentity { public partial class Startup { /// <summary> /// 配置 /// </summary> /// <param name="app"></param> public void Configuration(IAppBuilder app) { // 有關如何配置應用程序的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkID=316888 ConfigureAuth(app); } } } using Microsoft.AspNet.Identity; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; using Owin; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace AspNetIdentity { public partial class Startup { // 有關配置身份驗證的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { // 使應用程序能夠使用 Cookie 來存儲已登陸用戶的信息 app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), CookieHttpOnly = true, CookieName = "__KaoLaTicketSid" }); // Use a cookie to temporarily store information about a user logging in with a third party login provider app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); } } }
有了這個兩個啓動類,應用程序在啓動的時候,就會觸發Configuration方法,完成OWIN的配置工做。
若是你有更多疑問,不妨說出來,咱們共同探討。