RequireSmartOpsModuleMenuAttribute.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using Admin.NET.Core;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.AspNetCore.Mvc.Filters;
  5. using Microsoft.Extensions.DependencyInjection;
  6. namespace Admin.NET.Plugin.AiDOP.Infrastructure;
  7. /// <summary>
  8. /// 按动态看板路由中的 moduleCode 校验对应 PC 看板菜单。
  9. /// 权限来源仍是 PC 的 SysMenu/SysRoleMenu;非法或未授权模块一律拒绝。
  10. /// </summary>
  11. [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  12. public sealed class RequireSmartOpsModuleMenuAttribute : Attribute, IAsyncAuthorizationFilter
  13. {
  14. private static readonly HashSet<string> SupportedModules = new(StringComparer.OrdinalIgnoreCase)
  15. {
  16. "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S9"
  17. };
  18. public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
  19. {
  20. if (context.HttpContext.User?.Identity?.IsAuthenticated != true)
  21. {
  22. context.Result = new UnauthorizedResult();
  23. return;
  24. }
  25. var moduleCode = context.RouteData.Values["moduleCode"]?.ToString()?.Trim().ToUpperInvariant();
  26. if (string.IsNullOrWhiteSpace(moduleCode) || !SupportedModules.Contains(moduleCode))
  27. {
  28. context.Result = Forbid();
  29. return;
  30. }
  31. var accessService = context.HttpContext.RequestServices.GetService<ICurrentUserMenuAccessService>();
  32. if (accessService == null)
  33. {
  34. context.Result = Forbid();
  35. return;
  36. }
  37. try
  38. {
  39. var suffix = moduleCode.ToLowerInvariant();
  40. if (await accessService.HasMenuPathAsync($"/aidop/smart-ops/{suffix}") ||
  41. await accessService.HasMenuPathAsync($"/aidop/kanban/{suffix}"))
  42. return;
  43. }
  44. catch
  45. {
  46. // 权限基础设施异常时 fail-closed。
  47. }
  48. context.Result = Forbid();
  49. }
  50. private static ObjectResult Forbid() => new(new { message = "没有权限访问该功能" })
  51. {
  52. StatusCode = StatusCodes.Status403Forbidden
  53. };
  54. }