Swagger UI 授权不发送令牌

问题描述 投票:0回答:2

我是 Swagger 新手。我正在使用 OpenAPI 3.0.2。

当我运行 Swagger UI 时,顶部和每个 API 都会出现授权按钮,但它们不起作用。当我单击它们时,我可以在 apiKey 框中输入任何文本,它会接受它并表示我已获得授权。但是没有 API 起作用,它们都返回 401

这里是Startup.ConfigureServices中的相关代码

services.AddAuthentication(
        x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }
    )
    .AddJwtBearer(
        x =>
        {
            x.RequireHttpsMetadata = false;
            x.SaveToken = true;
            x.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = false,
                ValidateAudience = false,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidIssuer = Configuration["Tokens:Issuer"],
                ValidAudience = Configuration["Tokens:Audience"],
            };
        }
    );
services.AddSwaggerGen(
    setupAction =>
    {
        setupAction.SwaggerDoc(
            "LibraryOpenApiSpecification",
            new Microsoft.OpenApi.Models.OpenApiInfo()
            {
                Title = "Library API",
                Version = "2.0",
                Description = "Text",

                Contact = new Microsoft.OpenApi.Models.OpenApiContact()
                {
                    Email = "[email protected]",
                    Name = "user1",
                    Url = new Uri("http://www.google.com")
                }
            }
        );

        setupAction.AddSecurityDefinition(
            "Bearer",
            new OpenApiSecurityScheme
            {
                Name = "Authorization",
                Type = SecuritySchemeType.ApiKey,
                Scheme = "Bearer",
                BearerFormat = "JWT",
                In = ParameterLocation.Header,
                Description = "JWT Authorization header using the Bearer scheme."
            }
        );


        setupAction.AddSecurityRequirement(
            new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    },
                    new string[] { }
                }
            }
        );


        var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        var xmlCommentFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile);
        setupAction.IncludeXmlComments(xmlCommentFullPath);
    }
);

该代码不是我的,是由其他开发人员引入的。 如果需要,我将提供更多代码和信息

asp.net-core swagger swagger-ui swashbuckle.aspnetcore
2个回答
4
投票

这是一个工作示例:

services.AddSwaggerGen(
    c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiPlayground", Version = "v1" });
        c.AddSecurityDefinition(
            "token",
            new OpenApiSecurityScheme
            {
                Type = SecuritySchemeType.Http,
                BearerFormat = "JWT",
                Scheme = "Bearer",
                In = ParameterLocation.Header,
                Name = HeaderNames.Authorization
            }
        );
        c.AddSecurityRequirement(
            new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "token"
                        },
                    },
                    Array.Empty<string>()
                }
            }
        );
    }
);

配置完成后,Swagger UI 会为您提供一个进行身份验证的按钮

一旦您填写了令牌并发送请求,它就会将其发送到

Authorization
标头中。

现在,应用程序必须为每个请求解析和验证此令牌,因此您必须在

Startup.Configure
方法中启用身份验证中间件。

app.UseAuthentication();
app.UseAuthorization();

然后,如果令牌通过验证,您应该能够使用

HttpContext.User
属性访问用户。

如果您仍然收到 401 错误,这意味着令牌验证存在问题,请检查您是否已在

Startup.Configure
方法中配置了授权服务:

services.AddAuthorization(
    options => options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).Build()
);

这将要求所有请求进行身份验证,除非使用

[Authorize]
(或
[AllowAnonymous]
)属性设置另一个授权策略。这将确保令牌被解析和验证。

这是一个用于签名和验证令牌的端到端 API。

internal class HardCodedConfiguration
{
    public static SymmetricSecurityKey SigningKey = new SymmetricSecurityKey(
        Encoding.UTF8.GetBytes(
            "alongrandomstringhere.11b48736983e87c5cff022c462849ca5b7c5e99b76d81e9707fa35e76024cba8"
        )
    );

    public static SigningCredentials SigningCredentials => new SigningCredentials(
        SigningKey,
        SecurityAlgorithms.HmacSha256
    );
}

[ApiController]
[Route("")]
public class HelloController : ControllerBase
{
    [AllowAnonymous]
    [HttpGet("token")]
    public ActionResult SignToken()
    {
        var token = new JwtSecurityTokenHandler().WriteToken(
            new JwtSecurityToken(
                claims: new List<Claim>()
                {
                    new Claim("name", "abdusco")
                },
                expires:DateTime.Now.AddHours(1),
                signingCredentials: HardCodedConfiguration.SigningCredentials
            )
        );
        return Ok(token);
    }

    [HttpGet]
    public IActionResult AuthorizedEndpoint()
    {
        return Ok(User.Claims.Select(c => new { c.Type, c.Value }).ToList());
    }
}

// inside Startup class
public void ConfigureServices(IServiceCollection services)
{
    // swagger configuration
    // ...
    services.AddControllers();
    services.AddAuthorization(
        options => options.FallbackPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).Build()
    );
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(
            o =>
            {
                o.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    IssuerSigningKey = HardCodedConfiguration.SigningKey,
                };
            }
        );
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}

0
投票

为了让 Swagger UI(.NET 6、OpenApi v3、Swashbuckle v6.5)身份验证为我工作,我必须创建一个

AuthenticationRequirementsOperationFilter
并将其添加到过滤器中,如 此 github 答案中所述。同样重要的是,关键字
bearer
AddSecurityDefinition
OpenApiSecurityScheme
中保持相同。

这是示例代码:

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(opt =>
        {
            opt.SwaggerDoc("v1", new OpenApiInfo { Title = "My Api", Version = "v1" });
            opt.AddSecurityDefinition("bearer", new OpenApiSecurityScheme
            {
                Type = SecuritySchemeType.Http,
                BearerFormat = "JWT",
                In = ParameterLocation.Header,
                Scheme = "bearer"
            });
            opt.OperationFilter<AuthenticationRequirementsOperationFilter>();
        });
    }
}

public class AuthenticationRequirementsOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Security == null)
            operation.Security = new List<OpenApiSecurityRequirement>();

        var scheme = new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearer" } };
        operation.Security.Add(new OpenApiSecurityRequirement
        {
            [scheme] = new List<string>()
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.