【问题标题】:Swashbuckle/Swagger - how do I require the apiKey for a certain operation/at per operation level?Swashbuckle/Swagger - 我如何要求 apiKey 用于某个操作/在每个操作级别?
【发布时间】:2020-06-04 20:48:42
【问题描述】:

我在一个 ASP.NET 标准项目中安装了 Swashbuckle,并在 Swagger 和 SwaggerUI 中启用了 ApiKey 选项,并使用默认配置选项:

GlobalConfiguration.Configuration.EnableSwagger(c =>
  c.ApiKey("whatever")
    .Description("API Key Authentication")
    .Name("apiKey")
    .In("header")
).EnableSwaggerUI(c => c.EnableApiKeySupport("apiKey", "header"));

在浏览器的测试界面中存在输入apikey的选项,但操作并不关心我输入的内容;他们无论如何都会跑。我觉得我还需要做其他事情,而这条评论也暗示了同样的事情:

//These only define the schemes and need to be coupled with a corresponding "security" property
// at the document or operation level to indicate which schemes are required for an operation. To do this,
// you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties
// according to your specific authorization implementation

但我不太确定接下来我要做什么/它打算如何在 Swashbuckle 的上下文中工作。似乎没有任何 [SwaggerXxx] 注释显然是“如果添加此注释,则只有在 apikey 正确的情况下,该操作才会起作用”

如何将我的操作/控制器方法标记为“需要有效的 api 密钥”?

【问题讨论】:

  • 这与招摇无关。您的 webapi 需要一个身份验证和一个授权中间件。然后,您可以在控制器、端点上使用策略或基于角色的授权,或作为所有调用的全局过滤器。 docs.microsoft.com/en-us/aspnet/core/security/authentication/…
  • @Mono 所以你是说这个配置选项只是告诉swagger“每次你描述这个服务时,还提到远程用户必须发送一个具有相关值的 ApiKey 标头” - 这没什么与实际实现安全性有关,它纯粹是关于记录服务,因为 Swashbuckle 无法检查/反映方法并计算出必须传递哪些身份验证子项才能使身份验证过滤器通过并调用操作?而且即使是文档/操作过滤器也没有实现任何安全性,它们只是描述了如何生成安全性的文档
  • 它当然可以使用反射来检查您的控制器的授权属性,例如:github.com/domaindrivendev/… 但无论如何您必须自己保护您的休息 api。即使你可以带 swagger 来响应 401/403,你的 rest api 仍然可以在浏览器中使用,而无需使用 swagger。 Swagger 旨在为外部开发人员描述(和测试)您的 API。它就像一个文档工具

标签: c# asp.net swagger swashbuckle


【解决方案1】:

根据 Mono 的 cmets 和其他一些网络资源的指导,我现在了解到 Swashbuckle 中的此设置不会将基于 api 密钥的身份验证添加到项目中,它只会导致 Swashbuckle/Swagger 发出描述服务的 json,其中包括建议服务需要具有合适值的 Api Key 标头(无论是否正确,在我的情况下,因为没有 auth 中间层,所以它不正确)

我通过创建以下类实现了这一点:

    class AuthorizeByApiKeyAttribute : Attribute, System.Web.Http.Filters.IAuthenticationFilter
    {

        public bool AllowMultiple => false;

        public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            if (context.Request.Headers.TryGetValues("apikey", out var e) && e.Contains("KEY HERE"))
                context.Principal = new System.Security.Claims.ClaimsPrincipal(new System.Security.Claims.ClaimsIdentity("Negotiate"));
            else
                context.ErrorResult = new System.Net.Http.HttpResponseMessage(HttpStatusCode.Unauthorized) as IHttpActionResult;

            return Task.CompletedTask;
        }

        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
    }

然后用[Authorize][AuthorizeByApiKey]装饰我想要保护的东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 2022-06-20
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多