Microsoft.OpenAPI 示例或文档?

Phi*_*lip 6 c# swashbuckle openapi.net

刚刚尝试使用 Swashbuckle 5 rc2 + Microsoft OpenAPI 实现,但很难理解如何通过 OperationFilter 使用 OpenApiSecurityRequirement 注入安全要求

我正在将 OperationFilter 从 Swashbuckle 4 转换为使用 Microsoft 的 OpenApi 的 Swashbuckle 5 rc2。在 Swashbuckle 4 实现中,我有 OperationFilter(这允许我使用 oauth2 隐式流作用域以及 api_key,我可以在 SwaggerUI 中显式设置不记名 JTW 令牌:

// Swashbuckle 4 code
operation.Security = new List<Dictionary<String, IEnumerable<String>>>
{    
  new Dictionary<string, IEnumerable<string>>
  {
      { "Bearer", new string[] { } }
  },
  new Dictionary<string, IEnumerable<string>>
  {
      { "oauth2", requiredScopes }
  }
};
Run Code Online (Sandbox Code Playgroud)

不太确定如何使用 OpenAPI 来描述相同的安全要求,但在转换后的 OperationFilter 实现中,我基本上找到了具有 Authorize 属性的端点并读取策略以检索范围:

if (requiredScopes.Any())
{
  operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
  operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });

  OpenApiSecurityRequirement bearerSecurityRequirement = new OpenApiSecurityRequirement();
  bearerSecurityRequirement[new OpenApiSecurityScheme()
  {
    Type = SecuritySchemeType.Http,
    Scheme = "Bearer",
    BearerFormat = "JWT",
    In = ParameterLocation.Header,
    Name = "api_key",


  }] = new List<String>();

  OpenApiSecurityRequirement oauth2SecurityRequirement = new OpenApiSecurityRequirement();
  oauth2SecurityRequirement[new OpenApiSecurityScheme()
  {
    Type = SecuritySchemeType.OAuth2,
    Flows = new OpenApiOAuthFlows()
    {
      Implicit = new OpenApiOAuthFlow()
      {
        AuthorizationUrl = new Uri("<authorization url here>"),
        TokenUrl = new Uri("<token url here>"),
        Scopes = requiredScopes.ToDictionary(x => x) // TODO: Fix descriptions
      }
    },
    In = ParameterLocation.Header,
    Name = "oauth2"
  }] = new List<String>(requiredScopes);

  operation.Security = new List<OpenApiSecurityRequirement>
  {
      bearerSecurityRequirement,
      oauth2SecurityRequirement
  };
}
Run Code Online (Sandbox Code Playgroud)

在为我刚刚看到的操作生成的 swagger doc/openapi doc 的 json 输出中:

"security" : [
  {"api_key": []},
  {
    "oauth2": [
      "",
      ""
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

我想我的目标是根据 OpenAPI 标准生成以下 json,其中 api_key 和 oauth2 只是我的安全方案的名称。

"security" : [
  {"api_key": []},
  {
    "oauth2": [
      "<scope1>",
      "<scope2>"
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

是否有任何文档或可能有一些更完整的示例来实际演示如何为 oauth2 和 api 密钥方法声明受保护的端点?

Mik*_*der 0

您需要设置ReferenceOpenApiSecurityScheme.


我最终得到的结果和你一样,只是一个空物体。

我尝试添加 HTTP 基本身份验证,如示例所示:

openapi: 3.0.0
...
components:
  securitySchemes:
    basicAuth:     # <-- arbitrary name for the security scheme
      type: http
      scheme: basic
security:
  - basicAuth: []  # <-- use the same name here
Run Code Online (Sandbox Code Playgroud)

使用 Microsoft.OpenApi 来做到这一点:

var document = new OpenApiDocument
{
    Components = new OpenApiComponents
    {
        SecuritySchemes =
        {
            {
                "basicAuth", new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.Http,
                    Scheme = "basic"
                }
            }
        }
    },
    SecurityRequirements =
    {
        new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme 
                {
                    Reference = new OpenApiReference()
                    {
                        Type = ReferenceType.SecurityScheme, 
                        Id = "basicAuth"
                    }
                }, 
                new List<string>()
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

通过查看源代码OpenApiSecurityRequirement可以看到它正在检查OpenApiSecurityScheme.Reference而不是Name

foreach (var securitySchemeAndScopesValuePair in this)
{
    var securityScheme = securitySchemeAndScopesValuePair.Key;
    var scopes = securitySchemeAndScopesValuePair.Value;

    if (securityScheme.Reference == null)
    {
        // Reaching this point means the reference to a specific OpenApiSecurityScheme fails.
        // We are not able to serialize this SecurityScheme/Scopes key value pair since we do not know what
        // string to output.
        continue;
    }

    securityScheme.SerializeAsV3(writer);

    writer.WriteStartArray();

    foreach (var scope in scopes)
    {
        writer.WriteValue(scope);
    }

    writer.WriteEndArray();
}
Run Code Online (Sandbox Code Playgroud)