ApiTokenAttribute.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using Microsoft.AspNetCore.Mvc;
  2. using Microsoft.AspNetCore.Mvc.Filters;
  3. using TEAMModelOS.SDK.Extension;
  4. using System;
  5. using TEAMModelOS.Models;
  6. using Microsoft.Extensions.Options;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using System.IdentityModel.Tokens.Jwt;
  9. using System.Linq;
  10. using TEAMModelOS.SDK.DI;
  11. namespace TEAMModelOS.Filter
  12. {
  13. public class LimitPolicy {
  14. /// <summary>
  15. /// 颁发给谁的主体
  16. /// </summary>
  17. public string id { get; set; }
  18. /// <summary>
  19. /// 颁发主体
  20. /// </summary>
  21. public string school { get; set; }
  22. /// <summary>
  23. /// AIP的唯一ID
  24. /// </summary>
  25. public string jti { get; set; }
  26. /// <summary>
  27. /// minute 分钟,表示按分钟限流,多少分钟内只能访问多少次,
  28. /// hour 小时,表示按小时限流,多少小时内只能访问多少次,
  29. /// day 天数,表示按天数限流,多少天数内只能访问多少次,
  30. /// </summary>
  31. public string policy { get; set; }
  32. /// <summary>
  33. /// policy 策略,分钟,小时,天数对应的时长
  34. /// </summary>
  35. public int duration { get; set; }
  36. /// <summary>
  37. /// policy 策略,分钟,小时,天数对应的时长(duration) 可以访问的次数
  38. /// </summary>
  39. public int times { get; set; }
  40. /// <summary>
  41. /// 是否免费调用
  42. /// </summary>
  43. ///public bool free { get; set; }
  44. /// <summary>
  45. /// 每次调用花费多少钱
  46. /// </summary>
  47. ///public decimal cost { get; set; }
  48. }
  49. public class ApiTokenAttribute : Attribute, IFilterFactory
  50. {
  51. public bool IsReusable => true;
  52. public bool Limit { get; set; }
  53. public string Auth { get; set; }
  54. public IFilterMetadata CreateInstance(IServiceProvider services)
  55. {
  56. var option = services.GetService<IOptions<Option>>();
  57. var azureRedis = services.GetService<AzureRedisFactory>();
  58. return new InternalAuthTokenFilter(option ,azureRedis, Auth, Limit);
  59. }
  60. private class InternalAuthTokenFilter : IResourceFilter
  61. {
  62. private readonly Option _option;
  63. //private readonly string _roles;
  64. private readonly string _auth;
  65. private readonly bool _limit;
  66. private readonly AzureRedisFactory _azureRedis;
  67. public InternalAuthTokenFilter(IOptions<Option> option, AzureRedisFactory azureRedis, string auth, bool limit)
  68. {
  69. _option = option.Value;
  70. _auth = auth;
  71. _limit = limit;
  72. _azureRedis = azureRedis;
  73. }
  74. public void OnResourceExecuting(ResourceExecutingContext context)
  75. {
  76. bool pass = false;
  77. string id = string.Empty, school = string.Empty,jti=string.Empty;
  78. var authtoken = context.HttpContext.GetXAuth("ApiToken");
  79. if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateApiToken(authtoken, _option.JwtSecretKey))
  80. {
  81. var jwt = new JwtSecurityTokenHandler().ReadJwtToken(authtoken);
  82. id = jwt.Payload.Sub;
  83. school = jwt.Payload.Azp;
  84. jti = jwt.Payload.Jti;
  85. var permissions = jwt.Claims.Where(c => c.Type.Equals("auth"));
  86. ///当前请求的api的设置的permission值是否包含在 从jwt的获取["1","2","3","4","5"]值中
  87. if (!string.IsNullOrWhiteSpace(_auth)&& permissions.Count()>0)
  88. {
  89. if (permissions.Select(x=>x.Value).Contains(_auth))
  90. {
  91. pass = true;
  92. }
  93. }
  94. if (!string.IsNullOrEmpty(id) && !string.IsNullOrEmpty(school) && !string.IsNullOrEmpty(jti))
  95. {
  96. //AIP 开启限流策略 处理限流问题
  97. if (_limit)
  98. {
  99. }
  100. }
  101. }
  102. if (pass)
  103. {
  104. context.HttpContext.Items.Add("ID", id);
  105. context.HttpContext.Items.Add("School", school);
  106. }
  107. else
  108. {
  109. context.Result = new UnauthorizedResult();
  110. }
  111. }
  112. public void OnResourceExecuted(ResourceExecutedContext context)
  113. {
  114. }
  115. }
  116. }
  117. }