OWIN+AspNet.Identity實現用戶認證/登陸/註冊(MVC)

關於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(基於聲明)的認證

    首先,這種機制並不是微軟特有的,Claims-based認證和受權在國外被普遍使用,包括微軟的ADFS,Google,Facebook等。 安全


Claims-based認證的主要特色: cookie

  • 將認證與受權拆分紅獨立的服務
  • 服務調用者(通常是網站),不須要關注你如何去認證,你用Windows認證也好,用令牌手機短信也好,與我無關。
  • 若是用戶成功登陸的話,認證服務(假如是QQ) 會返回給咱們一個令牌。
  • 令牌當中包含了服務調用者所須要的信息,用戶名,以及角色信息等等。
     總的來講就是,我不再用管你怎麼登陸,怎麼樣去拿你有哪些角色了,我只須要把你跳到那個登陸站點上,而後它返回給我令牌信息,我從令牌上獲取須要的信息來肯定你是誰,你擁有什麼角色就能夠了。


    接下來,咱們會使用到兩個對象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的配置工做。

 若是你有更多疑問,不妨說出來,咱們共同探討。

相關文章
相關標籤/搜索