netcoreapp2.0 swagger 自定义身份验证失败没有结果

netcoreapp2.0 swagger custom authentication failure gives no result

我正在使用 netcoreapp2.0 网络应用程序并安装了 Swashbuckle.AspNetCore 版本 1.1 来处理 swagger。我只使用身份验证。我没有使用授权。我的意图是将身份验证应用于每个端点。

就我在 Startup.cs 中的 swagger 代码而言,我在 ConfigureServices 下有以下内容。

services.AddSwaggerGen(Config.Configure);

public class Config
{
    public static void Configure(SwaggerGenOptions options)
    {
        options.SwaggerDoc("v1", new Info { Title = "My service name", Version = "v1", });
        options.DescribeAllEnumsAsStrings();
        options.OperationFilter<HttpRequestHeadersFilter>();

    }
}

public class HttpRequestHeadersFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {


        var anon = context.ApiDescription.ControllerAttributes().OfType<AllowAnonymousAttribute>().FirstOrDefault();

        if (anon == null)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List<IParameter>();
            }

            operation.Parameters.Add(
                new NonBodyParameter()
                {

                    Description = "Authorization token.",
                    In = "header",
                    Name = "Authorization",
                    Required = true,

                });
        }
    }
}

在配置下,我有这段代码。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        app.UseSwagger();



        //MUST ADD THIS LINE FOR IT TO AUTHENTICATE
        app.UseAuthentication();



        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My service");

            c.ShowRequestHeaders();


        });


        app.UseMvc();


    }

我正在使用内部令牌生成器。令牌生成器工作正常。当我输入有效的安全信息时,swagger 可以正常工作。当我输入无效的安全信息时,我得到了 swagger 的响应。

响应Body:无内容

响应代码:0

回应Headers: { "error": "no response from server" }

我有这个 OnAuthenticationFailed 代码:

OnAuthenticationFailed = c =>
                    {

                        c.Response.StatusCode = 403;
                        c.Response.ContentType = "application/json";

                        return c.Response.WriteAsync("Invalid token");
                    }

有趣的是,如果我评论此代码并调用 HandleAuthenticateAsync 代码和 return 失败的 AuthenticateResult(并且我有一个 Context.ForbidAsync,如我的 GitHub post 上面),我从 api 端点得到结果,它给出了 403 状态代码,这真的很奇怪。我认为问题可能出在我 return 中的那个 OnAuthenticationFailed回调,但我不知道那会是什么。在我看来,它真的不应该在身份验证失败后继续处理..这似乎不太理想..

我可以使用无效凭据直接命中终点,但它会按预期失败。我可以使用有效凭据在代码中抛出一个随机异常,并大摇大摆地得到一个 500 响应代码和我的错误。我在此处 post 围绕安全设置 GitHub 提出了一个问题,名称为 timdoke -- https://github.com/aspnet/Security/issues/1338

如果需要,我可以添加更多有关身份验证的内容;但是,足以说明我遇到的唯一问题似乎与上面的 GitHub link 有关(双击验证码)。

我的问题是,当身份验证失败时,我如何才能大摇大摆地接受我发送的 HTTP 状态代码?我尝试更改响应内容类型,但没有任何效果。

旁注.. 有趣的是,如果我在 OnAuthenticationFailed 回调中将错误内容类型更改为 text/plain,即使直接使用无效凭据调用端点也会导致我根本得不到任何响应。

我已经尝试添加 ErrorFilters 和异常处理中间件来提供帮助;不幸的是,这些在身份验证期间被绕过了。我也试过弄乱 app.UseStatusCodePages 和 app.UseDeveloperExceptionPage 但它们似乎也没有在这里生效。

谁能帮帮我?谢谢!

我在 GitHub 上发布了这个问题的变体。我很幸运,他们为此创建了一张票,其中包含更多信息:https://github.com/aspnet/Security/issues/1613

基本上,答案是 AuthenticationHandler 不会影响应用程序的 "control flow"。换句话说,您可以在身份验证失败时请求继续。上面的错误部分是为了更新样本。他们故意需要一个授权属性来实际拒绝请求。

为了使这项工作无需授权 header,他们建议我可以通过创建授权中间件来强制执行全局身份验证。该代码看起来像这样,并且可以正常工作。

            app.UseAuthentication();

        app.Use(next => context =>
        {
            if (context.User.Identity.IsAuthenticated)
            {
                return next(context);
            }

            var ps = new PathString("/swagger");
            if (context.Request.Path.StartsWithSegments(ps))
            {
                return next(context);
            }

            return context.ChallengeAsync("Bearer");
        });