问题描述
因此,我们有一个Api,仅当从我们公司获得凭据时才可以访问。每个客户都有基于de子域的自己的网址。可以说,我们有2个客户:
- CustomerA-> Apikey = A->网址是a.api.example.com
- CustomerB-> Apikey = B->网址为b.api.example.com 我们的api还具有一些功能切换(针对每个客户),允许客户在付款时使用特定功能,否则他们将无法使用它。 到现在为止还挺好。 现在,我想隐藏客户不付费的Api方法(取决于功能)。 控制器或方法标有描述功能的属性。在数据库中设置了客户是否可以访问特定功能。 假设我们有: CustomerA可以访问的
- Feat1 CustomerB可以访问的
- Feat2
class MyController : ControllerBase{
[HttpGet]
[Feature("Feat1")]
public object GetFeat1(){
// impleMetation here
}
[HttpGet]
[Feature("Feat2")]
public object GetFeat2(){
// impleMetation here
}
}
我的第一个实现如下:
public class FeatureAuthorizeOperationsFilter : IDocumentFilter,ISchemaFilter
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IServiceProvider _serviceProvider;
public FeatureAuthorizeOperationsFilter(IHttpContextAccessor httpContextAccessor,IServiceProvider serviceProvider)
{
_httpContextAccessor = httpContextAccessor;
_serviceProvider = serviceProvider;
}
public void Apply(OpenApiDocument swaggerDoc,DocumentFilterContext context)
{
using (var scope = _serviceProvider.CreateScope())
{
var dbContext = scope.ServiceProvider.GetService<AppDbContext>();
foreach (var apiDescription in context.ApiDescriptions)
{
if (apiDescription.TrygetmethodInfo(out MethodInfo method))
{
var featureAttribute = method.GetCustomAttribute<FeatureAuthorizeAttribute>() ?? method.ReflectedType.GetCustomAttribute<FeatureAuthorizeAttribute>();
if (featureAttribute == null)
continue;
var subd = _httpContextAccessor.HttpContext.Request.Host.Host.Split(".")[0];
var hasFeature = (from s in dbContext.Subdomain
join f in dbContext.ChannelFeatures on s.ChannelId equals f.ChannelId
where f.Feature == (int)featureAttribute.Feature
&& s.Subdomain1 == subd
select 1).Any();
if (!hasFeature)
{
// remove the path from all swagger api paths
//swaggerDoc.Paths.Remove($"/{apiDescription.RelativePath}");
// empty the groupname
// if all calls from 1 group are removed,but the groupname remains => Group is still visible in swagger without calls
apiDescription.GroupName = "";
}
}
}
//remove all schemas with type hidden
var hiddenKeys = context.SchemaRepository.Schemas.Where(s => s.Value.Type == "HIDDEN").Select(s => s.Key).ToList();
foreach (var key in hiddenKeys)
{
if (context.SchemaRepository.Schemas.ContainsKey(key))
context.SchemaRepository.Schemas.Remove(key);
}
}
}
public void Apply(OpenApiSchema schema,SchemaFilterContext context)
{
if (schema?.Properties == null || context?.Type == null)
return;
using (var scope = _serviceProvider.CreateScope())
{
var dbContext = scope.ServiceProvider.GetService<AppDbContext>();
var featureAttribute = context?.Type.GetCustomAttribute<FeatureAuthorizeAttribute>();
if (featureAttribute == null)
return;
var subd = _httpContextAccessor.HttpContext.Request.Host.Host.Split(".")[0];
var hasFeature = (from s in dbContext.Subdomain
join f in dbContext.ChannelFeatures on s.ChannelId equals f.ChannelId
where f.Feature == (int)featureAttribute.Feature
&& s.Subdomain1 == subd
select 1).Any();
if (!hasFeature)
{
// set type to hidden so we can filter this later on
schema.Type = "HIDDEN";
}
}
}
}
这将清除ApiDescription的组名,也将从架构存储库中删除架构。我认为该文档将在每次请求时重新生成,并且能够删除我希望一遍又一遍隐藏的方法和实体。显然不是。一旦删除,方法和实体将保持删除状态。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)