管杀不管埋?! 如何在浏览器中访问 .NET 8 保护的 Swagger UI 终结点?

目录

官方示例

问题

探索

解决

总结


.NET 8 引入了一项新特性:调用 MapSwagger().RequireAuthorization 来保护 Swagger UI 终结点。这是一个很有用的功能,可以防止未经授权的用户访问 API 文档。

但是,这也带来了一个问题:如何在浏览器中访问受保护的 Swagger UI 终结点?

官方示例

官方文档给出了保护 swagger 终结点的示例代码:

using System.Security.Claims;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();

var app = builder.Build();

//if (app.Environment.IsDevelopment())
//{
    app.UseSwagger();
    app.UseSwaggerUI();
//}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapSwagger().RequireAuthorization();

app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
    .RequireAuthorization();

app.MapGet("/weatherforecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

在上面的代码中,/weatherforecast 终结点不需要授权,但 Swagger 终结点需要授权。

以下 Curl 传递 JWT 令牌来访问 Swagger UI 终结点:

curl -i -H "Authorization: Bearer {token}" https://localhost:{port}/swagger/v1/swagger.json

问题

虽然使用 Curl 可以访问 swagger.json,但是这并不是一个方便的方式。

一般来说,我们更倾向于使用浏览器来查看 API 文档。但是,使用浏览器访问的效果如下:

图片

因为浏览器请求swagger.json时没法传递 JWT 令牌。

搜索了一下,官网没有提供解决方案,网上也没有人说碰到了这个问题。

这是一个值得关注的问题,因为它影响了开发者的体验和效率。

为了解决这个问题,我们需要找到一种方法,让浏览器请求swagger.json时能够携带 JWT 令牌。

探索

查看swagger/index.html的源代码,我们发现swagger.json是通过一个 JavaScript 函数加载的。

window.onload函数中找到这样一段:

// Parse and add interceptor functions
var interceptors = JSON.parse('{"RequestInterceptorFunction":null,"ResponseInterceptorFunction":null}');
if (interceptors.RequestInterceptorFunction)
    configObject.requestInterceptor = parseFunction(interceptors.RequestInterceptorFunction);

RequestInterceptorFunction这个名字可以猜测,它是用来拦截请求的

但是现在它的值为 null, 那么怎么为RequestInterceptorFunction赋值呢?

那只能在注册 Swagger UI 的位置了。

解决

app.UseSwaggerUI方法中,我们找到了RequestInterceptorFunction属性,它的帮助文档里的示例如下:

/// Ex: "function (req) { req.headers['MyCustomHeader'] = 'CustomValue'; return req; }"

这正是我们想要的效果!

请求swagger.json时传递 JWT 令牌。

最后实现代码如下:

var js = @"function (req) {
    if(req.url.includes('swagger.json'))
    { 
        searchParams = new URLSearchParams(window.location.search);
        if (searchParams.has('token'))
        {
            req.headers['Authorization'] = 'Bearer '+searchParams.get('token');
        }
    }
    return req; 
}";

app.UseSwaggerUI(option=>option.Interceptors.RequestInterceptorFunction = js.Replace("\r\n",""));

当请求swagger.json时,我们将浏览器地址栏中的token参数添加到Authorization Header中。

图片

总结

.NET 8 引入了一项新特性:调用 MapSwagger().RequireAuthorization 来保护 Swagger UI 终结点。这是一个很有用的功能,可以防止未经授权的用户访问 API 文档。

但是,官方并没提供如何在浏览器中优雅地访问受保护的 Swagger UI 终结点的方案。

我们通过修改 Swagger UI 的配置,实现了在浏览器中携带 JWT 令牌访问 Swagger UI 的功能。

引入地址 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值