ApiIdentityAttribute.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using Bowin.Common.Cache;
  2. using Bowin.Common.Encoder.DES;
  3. using Bowin.Common.Utility;
  4. using Microsoft.AspNetCore.Mvc.Filters;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. namespace Bowin.Common.ServiceToken.ApiIdentity
  10. {
  11. /// <summary>
  12. /// Header:{ auth-key: 密文(系统ID|访问时间(MMyyyyddmmHHss)), auth-system: 系统ID明文 }
  13. /// </summary>
  14. public class ApiIdentityAttribute : ActionFilterAttribute
  15. {
  16. public List<string> ScopeList { get; set; }
  17. public ApiIdentityAttribute(params string[] scopes)
  18. {
  19. ScopeList = scopes.ToList();
  20. }
  21. public override void OnActionExecuting(ActionExecutingContext context)
  22. {
  23. if (!ApiIdentityHelper.IsStarted)
  24. {
  25. return;
  26. }
  27. var systemService = (ISystemService)HttpHelper.GetService(ApiIdentityHelper.SystemServiceType);
  28. var systemList = systemService.GetSystemList();
  29. var systemID = context.HttpContext.Request.Headers["auth-system"].ToString();
  30. var secret = systemList.Where(x => x.SystemID == systemID).FirstOrDefault()?.Secret;
  31. if (string.IsNullOrEmpty(secret))
  32. {
  33. throw new ServiceException(-1, "无效的auth-system");
  34. }
  35. var des = new DesAccessor();
  36. var key = Encoding.UTF8.GetBytes(secret).Take(8).ToArray();
  37. var iv = key;
  38. var encodedText = context.HttpContext.Request.Headers["auth-key"].ToString();
  39. var decodedString = des.Decrypt(encodedText, key, iv);
  40. var spliteData = decodedString.Split('|', StringSplitOptions.RemoveEmptyEntries);
  41. DateTime visitTime;
  42. if (spliteData.Length != 2 || spliteData[0] != systemID || !DateTime.TryParseExact(spliteData[1], "MMyyyyddmmHHss", null, System.Globalization.DateTimeStyles.None, out visitTime))
  43. {
  44. throw new ServiceException(-1, "无效auth-key");
  45. }
  46. var passTime = Math.Abs(DateTime.Now.Subtract(visitTime).TotalMinutes);
  47. if (passTime > 5)
  48. {
  49. throw new ServiceException(-1, "auth-key访问超时,请重新生成auth-key");
  50. }
  51. var scopeList = systemService.GetScopeList(systemID);
  52. if (scopeList.Intersect(ScopeList).Count() == 0)
  53. {
  54. throw new ServiceException(-2, "未授权的操作。");
  55. }
  56. ///考虑如何处理频繁访问,暂时想到是每一次调用接口时记录缓存,一分钟后缓存消失,这时候才可以再次访问,但需要考虑是不是所有将来的接口都需要有这个限制;
  57. ///另一个方式就是直接记录日志,访问太频繁线下找对方追责
  58. }
  59. }
  60. }