如何根据Swashbuckle中的URL隐藏或显示方法

问题描述

因此,我们有一个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的组名,也将从架构存储库中删除架构。我认为该文档将在每次请求时重新生成,并且能够删除我希望一遍又一遍隐藏的方法和实体。显然不是。一旦删除方法和实体将保持删除状态。

是否有一种方法可以根据请求或URL隐藏或显示方法,实体等?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)