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

时间:2018-01-18 17:50:18

标签: authentication swagger swagger-ui asp.net-core-2.0

我正在使用netcoreapp2.0 Web应用程序并安装了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,

                });
        }
    }
}

在Configure下,我有这段代码。

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得到这个回复。

回复正文:无内容

回复代码:0

响应标题: {   “错误”:“服务器无响应” }

我有OnAuthenticationFailed的代码:

OnAuthenticationFailed = c =>
                    {

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

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

有趣的是,如果我评论这段代码并且只是调用HandleAuthenticateAsync代码并返回失败的AuthenticateResult(我在上面的GitHub帖子中有一个Context.ForbidAsync),我从api终点得到结果并且它给出了一个403状态代码,这真的很奇怪。我认为问题可能是我在OnAuthenticationFailed回调中返回的内容,但我不知道那是什么。在我的拙见中认证失败后,真的不应该继续处理..这似乎并不理想..

我可以使用无效凭据直接命中终点,并且会按预期失败。我可以使用有效凭据在代码中抛出一个随机异常,并在swagger中获得500响应代码和错误。我在GitHub上发布了一个关于安全设置的问题,名称为timdoke - https://github.com/aspnet/Security/issues/1338

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

我的问题是,如何从认证失败中获得我发送的http状态代码时,我会如何大摇大摆?我尝试更改响应内容类型,但没有做任何事情。

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

我尝试过添加ErrorFilters来帮助处理中间件和异常处理;不幸的是,这些在认证过程中被绕过了。我也尝试过使用app.UseStatusCodePages和app.UseDeveloperExceptionPage,但它们似乎也没有在这里产生影响。

任何人都可以帮助我吗?谢谢!

1 个答案:

答案 0 :(得分:1)

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

基本上,答案是AuthenticationHandler不会影响应用程序的“控制流”。换句话说,您可以通过身份验证失败,并且请求将继续。上面的错误部分是为了更新样本..它们故意要求Authorization属性实际拒绝请求。

为了使这项工作没有Authorization标头,他们建议我可以通过创建授权中间件来强制进行全局身份验证。该代码看起来像这样,它的工作原理。

            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");
        });