| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- using Admin.NET.Core.Service;
- using Admin.NET.Plugin.AiDOP.Entity.DataPlatform;
- using SqlSugar;
- namespace Admin.NET.Plugin.AiDOP.DataPlatform.Inbound;
- /// <summary>grant 授权 + IP 白名单 + 限流。行数上限由接收服务按 grant/entity 取 min。</summary>
- public sealed class MdpInboundAuthService : ITransient
- {
- private readonly ISqlSugarClient _db;
- private readonly SysCacheService _cache;
- public MdpInboundAuthService(ISqlSugarClient db, SysCacheService cache)
- {
- _db = db;
- _cache = cache;
- }
- /// <summary>返回 null = 通过;否则 (httpStatus, message)。</summary>
- public async Task<(int Status, string Message)?> CheckAsync(
- string accessKey, long tenantId, string entityCode, string clientIp, CancellationToken ct)
- {
- var code = (entityCode ?? string.Empty).Trim().ToUpperInvariant();
- var entity = await _db.Queryable<MdpEntity>()
- .Where(e => e.InboundEnabled == 1)
- .Where("UPPER(entity_code) = @code", new SugarParameter("@code", code))
- .FirstAsync(ct);
- if (entity == null)
- return (403, "entity not authorized");
- var grant = await _db.Queryable<MdpInboundGrant>()
- .Where(g => g.AccessKey == accessKey && g.Status == 1)
- .Where("UPPER(entity_code) = @code", new SugarParameter("@code", code))
- .FirstAsync(ct);
- if (grant == null)
- return (403, "entity not authorized");
- if (grant.TenantId != tenantId)
- return (403, "entity not authorized");
- if (!string.IsNullOrWhiteSpace(grant.IpAllowlist))
- {
- var allowed = grant.IpAllowlist
- .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
- var ip = (clientIp ?? string.Empty).Trim();
- if (ip.Length == 0 || !allowed.Contains(ip, StringComparer.OrdinalIgnoreCase))
- return (403, "ip not allowed");
- }
- var minute = DateTime.Now.ToString("yyyyMMddHHmm");
- var rateKey = $"AIDOP_INBOUND_RATE:{accessKey}:{code}:{minute}";
- var current = _cache.Get<int>(rateKey);
- var next = current + 1;
- _cache.Set(rateKey, next, TimeSpan.FromMinutes(1));
- if (next > grant.RateLimitPerMin)
- return (429, "rate limit exceeded");
- return null;
- }
- public async Task<MdpInboundGrant> GetGrantAsync(string accessKey, string entityCode, CancellationToken ct)
- {
- var code = (entityCode ?? string.Empty).Trim().ToUpperInvariant();
- return await _db.Queryable<MdpInboundGrant>()
- .Where(g => g.AccessKey == accessKey && g.Status == 1)
- .Where("UPPER(entity_code) = @code", new SugarParameter("@code", code))
- .FirstAsync(ct);
- }
- }
|