C# Asp.NET Core 2.2:Swagger端点特定安全定义

C# Asp.NET Core 2.2:Swagger端点特定安全定义,c#,swagger,swagger-ui,asp.net-core-2.2,C#,Swagger,Swagger Ui,Asp.net Core 2.2,我正在一个.Net Core 2.2 REST项目中使用Swashback.AspNetCore 5.0.0-rc2。在我的项目中,我提供两个不同的API,它们在逻辑上相互连接 今天,我成功地分离了我的招摇过市文档,使每个api有一个招摇过市端点,其中只包含相应的api控制器 我通过在控制器的api explorer设置中添加指定的组名来实现这一点: [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme

我正在一个.Net Core 2.2 REST项目中使用Swashback.AspNetCore 5.0.0-rc2。在我的项目中,我提供两个不同的API,它们在逻辑上相互连接

今天,我成功地分离了我的招摇过市文档,使每个api有一个招摇过市端点,其中只包含相应的api控制器

我通过在控制器的api explorer设置中添加指定的组名来实现这一点:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiExplorerSettings(GroupName = "contracts")]
public class ContractsController : BaseController

[Authorize(AuthenticationSchemes = "BasicAuthentication")]
[ApiExplorerSettings(GroupName = "clearing")]
public class ClearingController : BaseController
有了这些设置,我就可以在Startup.cs中为swagger指定不同的端点

  // Enable documentation middleware
  app.UseSwagger(so =>
  {
    so.RouteTemplate = "api/doc/{documentName}/swagger.json";
  });
  app.UseSwaggerUI(suo =>
  {
    suo.SwaggerEndpoint("/api/doc/contracts/swagger.json", "Contracts API");
    suo.SwaggerEndpoint("/api/doc/clearing/swagger.json", "Clearing API");
    suo.RoutePrefix = "api/doc";
    suo.SupportedSubmitMethods(SubmitMethod.Get, SubmitMethod.Post, SubmitMethod.Patch, SubmitMethod.Delete);
  });
这很有效,一切都很好

现在,正如您可能注意到的,我对每个api的控制器使用不同的授权方法。第一个是contracts api,使用JWT令牌授权,而第二个是clearing api,使用基本授权

我以为,swagger ui会通过“Authorize”属性自动使用正确的授权方法,但我错了

我向swagger ui中间件添加了两种授权方法,如下所示:

  options.AddSecurityDefinition("Bearer", GetSwaggerTokenSecurityScheme());
  options.AddSecurityDefinition("Basic", GetSwaggerBasicSecurityScheme());

  options.AddSecurityRequirement(GetSwaggerJwtSecurityRequirement());
  options.AddSecurityRequirement(GetSwaggerBasicSecurityRequirement());
以下是我的全部招摇过市配置代码:

/// <summary>
/// Configures the swagger generation
/// </summary>
/// <param name="config">The swagger configuration</param>
/// <param name="options">The swagger gen options instance</param>
public static void ConfigureSwaggerGen(IConfiguration config, SwaggerGenOptions options)
{
  var swaggerConfig = config.Get<SwaggerConfiguration>();
  AddSwaggerDocPerApiType(swaggerConfig, options);

  options.AddSecurityDefinition("Bearer", GetSwaggerTokenSecurityScheme());
  options.AddSecurityDefinition("Basic", GetSwaggerBasicSecurityScheme());

  options.AddSecurityRequirement(GetSwaggerJwtSecurityRequirement());
  options.AddSecurityRequirement(GetSwaggerBasicSecurityRequirement());

  if (!swaggerConfig.SwaggerIncludeXml)
  {
    return;
  }
  var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
  xmlFiles.ToList().ForEach(f => options.IncludeXmlComments(f));
  options.DescribeAllEnumsAsStrings();
}

/// <summary>
/// Adds a swagger documentation for each api type
/// </summary>
/// <param name="config">The swagger configuration</param>
/// <param name="options">The swagger gen options instance</param>
private static void AddSwaggerDocPerApiType(SwaggerConfiguration config, SwaggerGenOptions options)
{
  options.SwaggerDoc("contracts", GetSwaggerInformationParams(config, "Contracts"));
  options.SwaggerDoc("clearing", GetSwaggerInformationParams(config, "Clearing"));
}

/// <summary>
/// Generates swagger information params object
/// according to the given configuration
/// </summary>
/// <param name="config">The configuration</param>
/// <param name="apiType">The api type</param>
/// <returns>The swagger information</returns>
private static OpenApiInfo GetSwaggerInformationParams(SwaggerConfiguration config, string apiType = "")
{
  var title = string.IsNullOrEmpty(apiType) ? config.SwaggerTitle : apiType;
  var version = string.IsNullOrEmpty(apiType) ? Assembly.GetExecutingAssembly().GetName().Version.ToString() : apiType;

  var swaggerInfo = new OpenApiInfo()
  {
    Title = title,
    Version = version.ToLower(),
    Description = config.SwaggerDescription,
    Contact = new OpenApiContact()
    {
      Name = config.SwaggerCompany,
      Email = config.SwaggerContactMail,
      Url = new Uri(config.SwaggerContactUrl)
    }
  };
  return swaggerInfo;
}

/// <summary>
/// Generates the swagger jwt security scheme object
/// </summary>
/// <returns>The swagger jwt security scheme</returns>
private static OpenApiSecurityScheme GetSwaggerTokenSecurityScheme()
{
  var scheme = new OpenApiSecurityScheme
  {
    Description = "JWT authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
    Name = "JwtAuthorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.ApiKey
  };
  return scheme;
}

/// <summary>
/// Generates the swagger basic security scheme object
/// </summary>
/// <returns>The swagger basic security scheme</returns>
private static OpenApiSecurityScheme GetSwaggerBasicSecurityScheme()
{
  var scheme = new OpenApiSecurityScheme
  {
    Description = "Basic authorization header. Example: \"Authorization: username:password\"",
    Name = "BasicAuthorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.Http,
    Scheme = "basic"
  };
  return scheme;
}

/// <summary>
/// Generates the swagger security scheme object
/// </summary>
/// <returns>The swagger security scheme</returns>
private static OpenApiSecurityRequirement GetSwaggerJwtSecurityRequirement()
{
  var req = new OpenApiSecurityRequirement()
  {
    {
      new OpenApiSecurityScheme()
      {
        Reference = new OpenApiReference() {Type = ReferenceType.SecurityScheme, Id = "Bearer"}
      },
      new[] {"readAccess", "writeAccess"}
    }
  };
  return req;
}

/// <summary>
/// Generates the swagger security scheme object
/// </summary>
/// <returns>The swagger security scheme</returns>
private static OpenApiSecurityRequirement GetSwaggerBasicSecurityRequirement()
{
  var req = new OpenApiSecurityRequirement()
  {
    {
      new OpenApiSecurityScheme()
      {
        Reference = new OpenApiReference() {Type = ReferenceType.SecurityScheme, Id = "Basic"}
      },
      new[] {"readAccess", "writeAccess"}
    }
  };
  return req;
}
//
///配置昂首阔步的一代
/// 
///昂首阔步的配置
///大摇大摆的gen选项实例
公共静态无效配置SwaggerGen(IConfiguration配置,SwaggerGenOptions选项)
{
var swaggerConfig=config.Get();
AddSwiggerDocPerapType(SwiggerConfig,选项);
AddSecurityDefinition(“Bearer”,GetSwaggerTokenSecurityScheme());
options.AddSecurityDefinition(“Basic”,GetSwaggerBasicSecurityScheme());
options.AddSecurityRequirement(GetSwaggerJwtSecurityRequirement());
options.addSecurityRequest(getSwaggerBasicSecurityRequest());
如果(!swaggerConfig.SwaggerIncludeXml)
{
返回;
}
var xmlFiles=Directory.GetFiles(AppContext.BaseDirectory,“*.xml”);
ForEach(f=>options.includexmlcomcomments(f));
options.descripbeAllenumsasstrings();
}
/// 
///为每种api类型添加一个招摇过市的文档
/// 
///昂首阔步的配置
///大摇大摆的gen选项实例
私有静态void addswaggerdocperapype(SwaggerConfiguration配置、SwaggerGenOptions选项)
{
options.SwaggerDoc(“合同”,GetSwaggerInformationParams(配置,“合同”);
options.SwaggerDoc(“清除”,GetSwaggerInformationParams(配置,“清除”);
}
/// 
///生成摆动信息参数对象
///根据给定的配置
/// 
///配置
///api类型
///招摇过市的消息
私有静态openapinfo GetSwaggerInformationParams(SwaggerConfiguration配置,字符串apiType=“”)
{
var title=string.IsNullOrEmpty(apiType)?config.SwaggerTitle:apiType;
var version=string.IsNullOrEmpty(apiType)?Assembly.getExecutionGassembly().GetName().version.ToString():apiType;
var swaggerInfo=new openapinfo()
{
头衔,
Version=Version.ToLower(),
Description=config.SwaggerDescription,
Contact=new OpenApiContact()
{
Name=config.SwaggerCompany,
Email=config.SwaggerContactMail,
Url=新Uri(config.SwaggerContactUrl)
}
};
返回虚张声势信息;
}
/// 
///生成swagger jwt安全方案对象
/// 
///swagger-jwt安全方案
私有静态OpenApiSecurityScheme GetSwaggerTokenSecurityScheme()
{
var scheme=新的OpenApiSecurityScheme
{
Description=“使用承载方案的JWT授权头。示例:\“授权:承载{token}\”,
Name=“JwtAuthorization”,
In=参数位置.Header,
类型=SecuritySchemeType.ApiKey
};
退货计划;
}
/// 
///生成swagger基本安全方案对象
/// 
///大摇大摆的基本安全方案
私有静态OpenApiSecurityScheme GetSwagger基本安全模式()
{
var scheme=新的OpenApiSecurityScheme
{
Description=“基本授权标头。示例:\”授权:用户名:密码\“”,
Name=“基本授权”,
In=参数位置.Header,
Type=SecuritySchemeType.Http,
Scheme=“基本”
};
退货计划;
}
/// 
///生成swagger安全方案对象
/// 
///招摇过市的安全计划
私有静态OpenApiSecurityRequirement GetSwagggerJWTSecurityRequirement()
{
var req=新的OpenApiSecurityRequirement()
{
{
新的OpenApiSecurityScheme()
{
Reference=new openapirection(){Type=ReferenceType.SecurityScheme,Id=“Bearer”}
},
新[]{“读访问”、“写访问”}
}
};
返回请求;
}
/// 
///生成swagger安全方案对象
/// 
///招摇过市的安全计划
私有静态OpenApiSecurityRequirement GetSwagger基本安全要求()
{
var req=新的OpenApiSecurityRequirement()
{
{
新的OpenApiSecurityScheme()
{
Reference=new openapirection(){Type=ReferenceType.SecurityScheme,Id=“Basic”}
},
新[]{“读访问”、“写访问”}
}
};
返回请求;
}
现在我想要实现的是,只有JWT令牌授权可用于contracts api控制器,只有基本授权可用于clearing api控制器

目前,我始终有两种授权方法可用于任何api:

有人知道如何只为特定的文档端点指定安全性吗


致以最诚挚的问候

根据此处的信息:

  • 您需要删除“options.addSecurityRequest”语句添加的全局安全要求

    并将其替换为由“options.AddSecurityDefinition”定义的安全操作,并将其绑定到应用于操作的Authorize语句

    swagger.io上的链接展示了所需安全性的各种模式

    希望有帮助


    +RD

    招摇过市选项。AddSecurityRequirement
    将应用Se