JwtHandler.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using Admin.NET.Core;
  2. using Admin.NET.Core.Service;
  3. using Furion;
  4. using Furion.Authorization;
  5. using Furion.DataEncryption;
  6. using Microsoft.AspNetCore.Authorization;
  7. using Microsoft.AspNetCore.Http;
  8. using System.Threading.Tasks;
  9. using Microsoft.Extensions.DependencyInjection;
  10. namespace Admin.NET.Web.Core
  11. {
  12. public class JwtHandler : AppAuthorizeHandler
  13. {
  14. /// <summary>
  15. /// 自动刷新Token
  16. /// </summary>
  17. /// <param name="context"></param>
  18. /// <returns></returns>
  19. public override async Task HandleAsync(AuthorizationHandlerContext context)
  20. {
  21. // 获取Token过期时间
  22. var serviceProvider = context.GetCurrentHttpContext().RequestServices;
  23. var sysConfigService = serviceProvider.GetService<SysConfigService>();
  24. var tokenExpire = await sysConfigService.GetTokenExpire();
  25. var refreshTokenExpire = await sysConfigService.GetRefreshTokenExpire();
  26. if (JWTEncryption.AutoRefreshToken(context, context.GetCurrentHttpContext(), tokenExpire, refreshTokenExpire))
  27. {
  28. await AuthorizeHandleAsync(context);
  29. }
  30. else
  31. {
  32. context.Fail(); // 授权失败
  33. DefaultHttpContext currentHttpContext = context.GetCurrentHttpContext();
  34. if (currentHttpContext == null)
  35. return;
  36. currentHttpContext.SignoutToSwagger();
  37. }
  38. }
  39. public override async Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
  40. {
  41. // 已自动验证 Jwt Token 有效性
  42. return await CheckAuthorzieAsync(httpContext);
  43. }
  44. /// <summary>
  45. /// 权限校验核心逻辑
  46. /// </summary>
  47. /// <param name="httpContext"></param>
  48. /// <returns></returns>
  49. private static async Task<bool> CheckAuthorzieAsync(DefaultHttpContext httpContext)
  50. {
  51. // 路由/按钮名称
  52. var routeName = httpContext.Request.Path.Value[1..].Replace("/", ":");
  53. string accountType = App.User.FindFirst(ClaimConst.AccountType)?.Value;
  54. string superAdmin = ((int)AccountTypeEnum.SuperAdmin).ToString();
  55. // 只有超管可以操作数据库
  56. if (routeName.Contains("sysDatabase") && accountType != superAdmin) return false;
  57. // 登录模式判断PC、APP
  58. if (App.User.FindFirst(ClaimConst.LoginMode)?.Value == ((int)LoginModeEnum.APP).ToString())
  59. return true;
  60. // 排除超管
  61. if (accountType == superAdmin)
  62. return true;
  63. // 获取用户拥有按钮权限集合
  64. var ownBtnPermList = await App.GetService<SysMenuService>().GetOwnBtnPermList();
  65. // 获取系统所有按钮权限集合
  66. var allBtnPermList = await App.GetService<SysMenuService>().GetAllBtnPermList();
  67. // 已拥有该按钮权限或者所有按钮集合里面不存在
  68. var exist1 = ownBtnPermList.Exists(u => routeName.Contains(u, System.StringComparison.CurrentCultureIgnoreCase));
  69. var exist2 = allBtnPermList.TrueForAll(u => !routeName.Contains(u, System.StringComparison.CurrentCultureIgnoreCase));
  70. return exist1 || exist2;
  71. }
  72. }
  73. }