首页 > 解决方案 > Swashbuckle/Swagger - 我如何要求 apiKey 用于某个操作/在每个操作级别?

问题描述

我已经在 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"));

浏览器的测试ui中存在输入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 密钥”?

标签: c#asp.netswaggerswashbuckle

解决方案


根据 Mono 的评论和其他一些网络资源的指导,我现在了解到 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]


推荐阅读