前言:最近跟上潮流,把辛苦搭建的core3放棄,踏上net5的快車,abp版本是4.2,沒想到第一步就遇到了難題,那就是token,網上查找資料,
說通過connect/token獲取,原文鏈接:https://blog.csdn.net/liuyonghong159632/article/details/112301317#comments_14518263,
經過我翻天掘地的測試,失敗告終。
從長計議后,我決定,先放棄探索框架自帶的token,自己寫,當我還沒寫到解析,竟然連通了,我知道,abp終於把core3的問題完善了,
說重點,我會持續測試新快車,只要更加的合理,我會繼續拋棄,目前我決定先自定義生成token,也許有人好奇,不是本來那個account/login,不就解決登錄問題了么,
首先,我是拋棄session的流派,再次,我必須用我自己寫的權限以及本地化,那么開始吧
1.搭建jwt的環境,地址:https://mp.weixin.qq.com/s/ZOX9D4ncqqeXxipYapTeBA,這里我沒有用外部登錄,正常來說,這個鏈接,完全解決了問題,
但是,我只所以拋棄core3,一個重要的因素就是多租戶問題,我發現core3不管如何配置和解析都無法自動處理多租戶,最后沒辦法,我采用了自己解析保存,
一直到響應、倉儲都是自己寫,在惆悵中,新版本問世了
2.在4.2中,我直接只需要寫好token,多租戶自動解析,解救了強迫症晚期的我,以下放出生成token的代碼,
為了測試方便,我直接寫死了token值
1 /// <summary> 2 /// 根據登錄信息獲取Token 3 /// </summary> 4 /// <param name="username">登錄名</param> 5 /// <param name="password">密碼</param> 6 /// <returns>Token</returns> 7 public async Task<ServiceResult<string>> GetTokenByLoginInfo(string username, string password) 8 { 9 var result = new ServiceResult<string>(); 10 11 if (string.IsNullOrEmpty(username)) 12 { 13 result.IsFailed("登錄名不得為空!"); 14 return result; 15 } 16 else if (string.IsNullOrEmpty(password)) 17 { 18 result.IsFailed("密碼不得為空!"); 19 return result; 20 } 21 // AuthenticationStatus認證狀態:(默認值)0代表未認證,1代表認證通過,2代表認證不通過 22 //// DelFlag刪除狀態:(默認值)0代表未刪除,1代表已刪除 23 //var jwtUser = await _JWTUserRepository.FindAsync( 24 // x => x.UserName.Equals(username) 25 // && x.PassWord.Equals(password) 26 // && x.AuthenticationStatus == 1); 27 //if (jwtUser == null) 28 //{ 29 // result.IsFailed("登錄失敗,賬號或密碼不正確!"); 30 // return result; 31 //} 32 /* 33 if (JWTUser.Id != Pro215UserAPIConfig.UserId) 34 { 35 result.IsFailed("當前賬號未授權"); 36 return result; 37 }*/ 38 result.IsSuccess( 39 CreateJWTToken( 40 "13F1F1CD-41B6-5C01-AAD4-39FA6ED6441B", 41 "Com1Admin", 42 "13F1F1CD-41B6-5C01-AAD4-39FA6ED6441B", 43 "828BA489-4643-2198-CA0E-39FA6ED64389")); 44 return await Task.FromResult(result); 45 } 46 47 /// <summary> 48 /// 簽發JWT,返回token 49 /// </summary> 50 /// <param name="guid">jwtuser表pkid</param> 51 /// <param name="userName">jwtuser表用戶名</param> 52 /// <param name="roleGroupId">jwtuser表權限組id</param> 53 /// <param name="tenantId">jwtuser表租戶代碼</param> 54 /// <returns></returns> 55 public string CreateJWTToken(string guid, string userName, string roleGroupId, string tenantId) 56 { 57 58 var claims = new[] { 59 new Claim(ClaimTypes.NameIdentifier, guid), 60 new Claim(AbpClaimTypes.UserId, guid), 61 new Claim(AbpClaimTypes.UserName, userName), 62 new Claim(ClaimTypes.Name, userName), 63 new Claim(ClaimTypes.Role, roleGroupId), 64 new Claim(AbpClaimTypes.TenantId, tenantId), 65 new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(1800)).ToUnixTimeSeconds()}"), 66 new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") 67 }; 68 69 var key = new SymmetricSecurityKey(AppSettings.JWT.SecurityKey.GetBytes()); 70 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 71 72 var securityToken = new JwtSecurityToken( 73 issuer: AppSettings.JWT.Domain, 74 audience: AppSettings.JWT.Domain, 75 claims: claims, 76 expires: DateTime.Now.AddMinutes(AppSettings.JWT.Expires), 77 signingCredentials: creds); 78 79 var token = new JwtSecurityTokenHandler().WriteToken(securityToken); 80 return token; 81 }
2.獲取到token后,測試下效果,記得controller添加屬性[Authorize],貼上application邏輯代碼,我是用官方的寫的demo測試的,這里的CurrentTenant與CurrentUser我就是為了測試切換租戶與用戶,跳權限操作之類的
1 public class BookAppService : 2 CrudAppService< 3 Book, //The Book entity 4 BookDto, //Used to show books 5 Guid, //Primary key of the book entity 6 PagedAndSortedResultRequestDto, //Used for paging/sorting 7 CreateUpdateBookDto>, //Used to create/update a book 8 IBookAppService //implement the IBookAppService 9 { 10 private readonly BookAppCacheService _bookAppCacheService; 11 private readonly ICurrentTenant _currentTenant; 12 private readonly ICurrentUser _currentUser; 13 public BookAppService(IRepository<Book, Guid> repository, 14 BookAppCacheService bookAppCacheService, 15 ICurrentTenant _ICurrentTenant 16 , ICurrentUser currentUser) 17 : base(repository) 18 { 19 _bookAppCacheService = bookAppCacheService; 20 _currentTenant = _ICurrentTenant; 21 _currentUser = currentUser; 22 23 } 24 public Task<BookDto> CreateAsync11(CreateUpdateBookDto input) 25 { 26 //1.邏輯中判斷權限,手動拋出或者截停邏輯代碼 27 /* 28 var result = await AuthorizationService 29 .AuthorizeAsync("Book_Author_Create"); 30 if (result.Succeeded == false) 31 { 32 //throw exception 33 throw new AbpAuthorizationException("..."); 34 } 35 36 */ 37 /* 2.可以不使用但推薦用[Authorize("Book")]的方式,在代碼中主動檢查 38 * 如果未授權 CheckAsync 擴展方法會拋出 AbpAuthorizationException 異常. 39 * 還有一個 IsGrantedAsync 擴展方法會返回 true 或 false. 40 * IAuthorizationService 中有多個 AuthorizeAsync 方法重載. 41 * ASP.NET Core 授權文檔中有詳細的解釋. 42 * 提示: 盡可能使用聲明式的 Authorize attribute,因為它比較簡單不會侵入方法內部. 43 * 如果你需要在業務代碼中有條件的檢查權限,那么請使用 IAuthorizationService. 44 * 示例:await AuthorizationService.CheckAsync("Author_Management_Create_Books"); 45 */ 46 return base.CreateAsync(input); 47 } 48 /// <summary> 49 /// (緩存)獲取書本分頁數據 50 /// </summary> 51 /// <param name="input">查詢條件</param> 52 /// <returns></returns> 53 public async Task<PagedResultDto<BookDto>> GetListCacheAsync(PagedAndSortedResultRequestDto input) 54 { 55 return await _bookAppCacheService.GetListCacheAsync(input, () => 56 { 57 return base.GetListAsync(input); 58 }); 59 } 60 61 }
3.看看數據庫的數據,