Asp.Net.Identity為何物請自行搜索,也可轉向此文章http://www.cnblogs.com/shanyou/p/3918178.html 本來微軟已經幫我們將授權、認證以及資料庫存儲都一一處理好了。但是總有這種情況,如我們現在的項目是已經存在了資料庫,且庫里已經有用戶、角色等信息表 ...
Asp.Net.Identity為何物請自行搜索,也可轉向此文章http://www.cnblogs.com/shanyou/p/3918178.html
本來微軟已經幫我們將授權、認證以及資料庫存儲都一一處理好了。但是總有這種情況,如我們現在的項目是已經存在了資料庫,且庫里已經有用戶、角色等信息表,但是
我們還是貪心想使用微軟的授權、認證類庫。這裡我就來實際實踐下到底可行不可行~
第一步、新建一個Asp.Net MVC框架的web工程
第二部、Nuget上安裝Microsoft.AspNet.Identity、Microsoft.AspNet.Identity.Owin
其中Microsoft.AspNet.Identity.Owin有依賴項,它依賴了這幾個包:
Microsoft.Owin.Security.OAuth MSDN註解:包含與 OAuth 提供程式相關的類型。(詳細信息參考 https://msdn.microsoft.com/zh-cn/library/microsoft.owin.security.oauth(v=vs.111).aspx)
Microsoft.Owin.Security.Cookies MSDN註解:提供與身份 cookie 相關的類型。 (詳細信息參考 https://msdn.microsoft.com/zh-cn/library/microsoft.owin.security.cookies(v=vs.111).aspx)
Microsoft.Owin.Security MSDN註解:包含與身份驗證相關的類型。 (詳細信息參考 https://msdn.microsoft.com/zh-cn/library/microsoft.owin.security(v=vs.111).aspx)
Microsoft.AspNet.Identity.Core MSDN註解:包含與管理 ASP.NET Identity 的用戶和角色相關的類和介面。
(信息信息參考:https://msdn.microsoft.com/library/microsoft.aspnet.identity(v=vs.111).aspx)
從MSDN的註解可以看出來Microsoft.AspNet.Identity.Owin里其實就是將網站的登錄、註冊業務場景所需的API進行了封裝;
第三部、建模
如我現在的資料庫的用戶表為BASE_USER,表結構如下
CREATE TABLE [dbo].[BASE_USER]( [ID] [uniqueidentifier] NOT NULL PRIMARY KEY, [NAME] [varchar](50) NOT NULL, [PWD] [varchar](50) NOT NULL, ) ON [PRIMARY]
我們在工程站點的Models文件夾里新建一個BASE_USER類,讓它繼承Microsoft.AspNet.Identity.IUser<GUID>,這裡我們加一個數據表不存在的NICKNAME昵稱欄位,到後面看看會有什麼效果~
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 6 namespace IdeintityDemo.Models 7 { 8 public class BASE_USER : Microsoft.AspNet.Identity.IUser<Guid> 9 { 10 /// <summary> 11 /// 用戶編號 12 /// </summary> 13 public Guid Id { get; set; } 14 /// <summary> 15 /// 用戶名 16 /// </summary> 17 public string UserName { get; set; } 18 /// <summary> 19 /// 密碼 20 /// </summary> 21 public string PWD { get; set; } 22 /// <summary> 23 /// 昵稱 24 /// </summary> 25 public string NickName { get; set; } 26 27 public bool RememberMe { get; set; } 28 } 29 }View Code
第四部 創建UserStore類,該類通過繼承介面IUserStore來實現用戶存儲在資料庫的api
1 using Microsoft.AspNet.Identity; 2 using System; 3 using System.Collections.Generic; 4 using System.Data; 5 using System.Data.SqlClient; 6 using System.Linq; 7 using System.Threading.Tasks; 8 using System.Web; 9 using System.Security.Claims; 10 using IdeintityDemo.Models; 11 using IdeintityDemo.Common; 12 13 namespace IdeintityDemo.Identity 14 { 15 16 /// <summary> 17 /// 用戶持久化存儲對象 18 /// 必須實現Microsoft.AspNet.Identity相應介面,否則在SignInManager類進行登錄校驗過程中 19 /// 會彈出未實現相關介面的異常! 20 /// IUserStore:檢測是否存在賬戶 21 /// IUserPasswordStore:校驗密碼 22 /// IUserLockoutStore:鎖定賬戶相關操作 23 /// IUserClaimStore:存儲用戶特定的聲明 24 /// IUserEmailStore:郵箱關聯、驗證等相關操作 25 /// IUserPhoneNumberStore:手機關聯、驗證相關操作 26 /// IUserTwoFactorStore:獲取或設置用戶雙重身份驗證的方法。 27 /// </summary> 28 public class HsUserStore : Microsoft.AspNet.Identity.IUserStore<BASE_USER, Guid>, 29 Microsoft.AspNet.Identity.IUserPasswordStore<BASE_USER, Guid>, 30 Microsoft.AspNet.Identity.IUserLockoutStore<BASE_USER, Guid>, 31 Microsoft.AspNet.Identity.IUserClaimStore<BASE_USER, Guid>, 32 Microsoft.AspNet.Identity.IUserEmailStore<BASE_USER, Guid>, 33 Microsoft.AspNet.Identity.IUserPhoneNumberStore<BASE_USER, Guid>, 34 Microsoft.AspNet.Identity.IUserTwoFactorStore<BASE_USER, Guid> 35 { 36 37 /// <summary> 38 /// 聲明 39 /// </summary> 40 public IList<System.Security.Claims.Claim> Claims = null; 41 /// <summary> 42 /// 用戶 43 /// </summary> 44 public BASE_USER UserIdentity = null; 45 46 /// <summary> 47 /// 實例化 48 /// </summary> 49 public HsUserStore() 50 { 51 //聲明 52 Claims = new List<System.Security.Claims.Claim>(); 53 } 54 /// <summary> 55 /// 創建用戶 56 /// </summary> 57 /// <param name="user"></param> 58 /// <returns></returns> 59 public Task CreateAsync(BASE_USER user) 60 { 61 return Task.Run(() => { 62 string sql = @"INSERT INTO [dbo].[BASE_USER]([ID],[NAME],[PWD]) 63 VALUES(@UserID,@name,@pwd)"; 64 SqlParameter[] parameters = { 65 new SqlParameter("@UserID", Guid.NewGuid()), 66 new SqlParameter("@name", user.UserName), 67 new SqlParameter("@pwd", user.PWD) 68 }; 69 int iResult = DbHelperSQL.ExecuteSql(sql, parameters); 70 }); 71 } 72 /// <summary> 73 /// 刪除用戶 74 /// </summary> 75 /// <param name="user"></param> 76 /// <returns></returns> 77 public Task DeleteAsync(BASE_USER user) 78 { 79 return Task.Run(() => { 80 string sql = @"DELETE FROM [dbo].[BASE_USER] WHERE ID=@ID"; 81 SqlParameter[] parameters = { 82 new SqlParameter("@UserID", user.Id)}; 83 int iResult = DbHelperSQL.ExecuteSql(sql, parameters); 84 }); 85 } 86 /// <summary> 87 /// 根據用戶id獲取用戶 88 /// </summary> 89 /// <param name="userId"></param> 90 /// <returns></returns> 91 public Task<BASE_USER> FindByIdAsync(Guid userId) 92 { 93 return Task<BASE_USER>.Run(() => 94 { 95 BASE_USER result = new BASE_USER(); 96 string sql = @"SELECT * FROM [dbo].[BASE_USER] WHERE ID=@ID"; 97 SqlParameter[] parameters = { 98 new SqlParameter("@ID", userId)}; 99 DataSet ds = DbHelperSQL.Query(sql, parameters); 100 if (ds == null || ds.Tables == null || ds.Tables[0].Rows.Count <= 0) 101 return result; 102 //model 103 DataRow dr = ds.Tables[0].Rows[0]; 104 result.Id = Guid.Parse(dr["ID"].ToString()); 105 result.UserName = dr["NAME"].ToString(); 106 result.PWD = dr["PWD"].ToString(); 107 return result; 108 }); 109 } 110 /// <summary> 111 /// 根據名稱獲取用戶信息 112 /// </summary> 113 /// <param name="userName"></param> 114 /// <returns></returns> 115 public Task<BASE_USER> FindByNameAsync(string userName) 116 { 117 return Task<BASE_USER>.Run(() => 118 { 119 BASE_USER result = new BASE_USER(); 120 string sql = @"SELECT * FROM [dbo].[BASE_USER] WHERE NAME=@NAME"; 121 SqlParameter[] parameters = { 122 new SqlParameter("@NAME", userName)}; 123 DataSet ds = DbHelperSQL.Query(sql, parameters); 124 if (ds == null || ds.Tables == null || ds.Tables[0].Rows.Count <= 0) 125 return result; 126 //model 127 DataRow dr = ds.Tables[0].Rows[0]; 128 result.Id = Guid.Parse(dr["ID"].ToString()); 129 result.UserName = dr["NAME"].ToString(); 130 result.PWD = dr["PWD"].ToString(); 131 132 return result; 133 }); 134 } 135 /// <summary> 136 /// 更新用戶 137 /// </summary> 138 /// <param name="user"></param> 139 /// <returns></returns> 140 public Task UpdateAsync(BASE_USER user) 141 { 142 return Task.Run(() => 143 { 144 //省略... 145 }); 146 } 147 /// <summary> 148 /// 非同步返回當前失敗的訪問嘗試次數。當密碼被驗證或帳戶被鎖定時,這個數字通常會被重置。 149 /// (這裡因為我資料庫里沒有去做這一塊的記錄保存,所以先寫死返回1) 150 /// </summary> 151 /// <param name="user">用戶</param> 152 /// <returns></returns> 153 public Task<int> GetAccessFailedCountAsync(BASE_USER user) 154 { 155 return Task.FromResult<int>(1); 156 } 157 /// <summary> 158 /// 獲取鎖定狀態 159 /// </summary> 160 /// <param name="user"></param> 161 /// <returns></returns> 162 public Task<bool> GetLockoutEnabledAsync(BASE_USER user) 163 { 164 return Task.FromResult<bool>(false); 165 } 166 /// <summary> 167 /// 獲取鎖定結束時間 168 /// </summary> 169 /// <param name="user"></param> 170 /// <returns></returns> 171 public Task<DateTimeOffset> GetLockoutEndDateAsync(BASE_USER user) 172 { 173 throw new NotImplementedException(); 174 } 175 /// <summary> 176 /// 記錄試圖訪問用戶失敗的記錄。 177 /// </summary> 178 /// <param name="user"></param> 179 /// <returns></returns> 180 public Task<int> IncrementAccessFailedCountAsync(BASE_USER user) 181 { 182 return Task.FromResult<int>(1); 183 } 184 /// <summary> 185 /// 重置訪問失敗計數,通常在帳戶成功訪問之後 186 /// </summary> 187 /// <param name="user"></param> 188 /// <returns></returns> 189 public Task ResetAccessFailedCountAsync(BASE_USER user) 190 { 191 return Task.FromResult(false); 192 } 193 /// <summary> 194 /// 非同步設置是否可以鎖定用戶。 195 /// </summary> 196 /// <param name="user"></param> 197 /// <param name="enabled"></param> 198 /// <returns></returns> 199 public Task SetLockoutEnabledAsync(BASE_USER user, bool enabled) 200 { 201 return Task.Run(() => { }); 202 } 203 /// <summary> 204 /// 非同步鎖定用戶直到指定的結束日期 205 /// </summary> 206 /// <param name="user"></param> 207 /// <param name="lockoutEnd"></param> 208 /// <returns></returns> 209 public Task SetLockoutEndDateAsync(BASE_USER user, DateTimeOffset lockoutEnd) 210 { 211 return Task.Run(() => 212 { 213 214 }); 215 } 216 /// <summary> 217 /// 獲取用戶密碼 218 /// </summary> 219 /// <param name="user"></param> 220 /// <returns></returns> 221 public Task<string> GetPasswordHashAsync(BASE_USER user) 222 { 223 return Task<string>.Run(() => 224 { 225 return user.PWD; 226 }); 227 } 228 /// <summary> 229 /// 是否有密碼 230 /// </summary> 231 /// <param name="user"></param> 232 /// <returns></returns> 233 public Task<bool> HasPasswordAsync(BASE_USER user) 234 { 235 return Task.FromResult<bool>(!string.IsNullOrEmpty(user.PWD)); 236 } 237 /// <summary> 238 /// 密碼進行加密 239 /// </summary> 240 /// <param name="user"></param> 241 /// <param name="passwordHash"></param> 242 /// <returns></returns> 243 public Task SetPasswordHashAsync(BASE_USER user, string passwordHash) 244 { 245 return Task.Run(() => 246 { 247 user.PWD = passwordHash;//加密後 248 }); 249 } 250 /// <summary> 251 /// 添加一個聲明 252 /// </summary> 253 /// <param name="user"></param> 254 /// <param name="claim"></param> 255 /// <returns></returns> 256 public Task AddClaimAsync(BASE_USER user, Claim claim) 257 { 258 return Task.Run(() => { Claims.Add(claim); }); 259 } 260 /// <summary> 261 /// 獲取改用戶的所有聲明 262 /// </summary> 263 /// <param name="user"></param> 264 /// <returns></returns> 265 public Task<IList<Claim>> GetClaimsAsync(BASE_USER user) 266 { 267 return Task.Run<IList<System.Security.Claims.Claim>>(() => 268 { 269 IList<System.Security.Claims.Claim> list = new List<System.Security.Claims.Claim>(); 270 return list; 271 }); 272 } 273 /// <summary> 274 /// 移除申明 275 /// </summary> 276 /// <param name="user"></param> 277 /// <param name="claim"></param> 278 /// <returns></returns> 279 public Task RemoveClaimAsync(BASE_USER user, Claim claim) 280 { 281 return Task.Run(() => 282 { 283 284 }); 285 } 286 /// <summary> 287 /// 通過郵箱獲取對應的用戶信息 288 /// </summary> 289 /// <param name="email"></param> 290 /// <returns></returns> 291 public Task<BASE_USER> FindByEmailAsync(string email) 292 { 293 return Task<BASE_USER>.Run(() => new BASE_USER()); 294 } 295 /// <summary> 296 /// 獲取郵箱 297 /// </summary> 298 /// <param name="user"></param> 299 /// <returns></returns> 300 public Task<string> GetEmailAsync(BASE_USER user) 301 { 302 return Task<string>.Run(() => string.Empty); 303 } 304 /// <summary> 305 /// 確認郵箱 306 /// </summary> 307 /// <param name="user"></param> 308 /// <returns></returns> 309 public Task<bool> GetEmailConfirmedAsync(BASE_USER user) 310 { 311 return Task.FromResult<bool>(true); 312 } 313 /// <summary> 314 /// 修改郵箱 315 /// </summary> 316 /// <param name="user"></param> 317 /// <param name="email"></param> 318 /// <returns></returns> 319 public Task SetEmailAsync(BASE_USER user, string email) 320 { 321 return Task.Run(() => { }); 322 } 323 /// <summary> 324 ///設置用戶是否郵箱確認 325 /// </summary> 326 /// <param name="user"></param> 327 /// <param name="confirmed"></param> 328 /// <returns></returns> 329 public Task SetEmailConfirmedAsync(BASE_USER user, bool confirmed) 330 { 331 throw new NotImplementedException(); 332 } 333 /// <summary> 334 /// 獲取聯繫電話 335 /// </summary> 336 /// <param name="user"></param> 337 /// <returns></returns> 338 public Task<string> GetPhoneNumberAsync(BASE_USER user) 339 { 340 return Task.FromResult<string>(string.Empty); 341 } 342 /// <summary> 343 /// 獲取用戶電話號碼是否已確認 344 /// </summary> 345 /// <param name="user"></param> 346 /// <returns></returns> 347 public Task<bool> GetPhoneNumberConfirmedAsync(BASE_USER user) 348 { 349 return Task.FromResult<bool>(true); 350 } 351 /// <summary> 352 /// 設置用戶電話號碼 353 /// </summary> 354 /// <param name="user"></param> 355 /// <param name="phoneNumber"></param> 356 /// <returns></returns> 357 public Task SetPhoneNumberAsync(BASE_USER user, string phoneNumber) 358 { 359 return Task.Run(() => { }); 360 } 361 /// <summary> 362 /// 設置與用戶關聯的電話號碼 363 /// </summary> 364 /// <param name="user"></param> 365 /// <param name="confirmed"></param> 366 /// <returns></returns> 367 public Task SetPhoneNumberConfirmedAsync(BASE_USER user, bool confirmed) 368 { 369 return Task.Run(() => { }); 370 } 371 /// <summary> 372 /// 是否為用戶啟用了雙重身份驗證。 373 /// </summary> 374 /// <param name="user"></param> 375 /// <returns></returns> 376 public Task<bool> GetTwoFactorEnabledAsync(BASE_USER user) 377 { 378 return Task.FromResult<bool>(false); 379 } 380 /// <summary> 381 /// 設置雙重身份驗證 382 /// </summary> 383 /// <param name="user"></param> 384 /// <param name="enabled"></param> 385