在 .NET 9.0 Web API 中实现 Scalar 接口文档及JWT集成

示例代码:https://download.csdn.net/download/hefeng_aspnet/90408075 

介绍

        随着 .NET 9 的发布,微软宣布他们将不再为任何 .NET API 项目提供默认的 Swagger gen UI。以前,当我们创建 .NET API 项目时,微软会自动添加 Swagger Swashbuckle 包,该包提供了app.UseSwagger()和app.UseSwaggerUI() 等方法。这些方法显示了带有预定义 UI 的 API 文档,可直接在浏览器中进行测试,而无需使用 Postman 等任何第三方应用程序。但是,Swagger 不再与 .NET 9 Web API 项目集成。做出此决定是因为该包最近没有得到妥善维护,并且许多用户报告的问题仍未解决。 

        微软团队创建了一个名为 Microsoft.AspNetCore.OpenApi 的新包,它提供了类似于 Swagger 的内置 OpenAPI 文档生成功能。但是,这只提供了所有端点和架构定义的 JSON 文档,而浏览器中不会显示任何 UI。这一变化的主要目的是让用户实现他们喜欢的 UI 库,无论是 Swagger 还是任何其他替代方案。微软删除默认的 Swagger 包并不意味着您不能在项目中再次安装 Swagger——您可以添加它并执行与以前相同的所有操作。

        目前有许多 Swagger 的替代方案,但在本文中,我们将讨论并在我们的 API 项目中实现 Scalar。继 Swagger 之后,Scalar 在开发人员中越来越受欢迎。

创建新项目

        当您使用 .NET 9 创建新项目时,它会询问您是否要配置 OpenAPI 支持。如果您选中此复选框,它会将 Microsoft.AspNetCore.OpenApi 包添加到您的项目中,并在 program.cs 文件中注册 OpenAPI 服务,如下所示:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();

现在,当您运行 API 并导航到/OpenApi/v1.json时,它将显示默认生成的文档,其中包含有关您的端点和您使用的所有模式的信息,如下图所示:

配置 Scalar.NET

首先,打开你的包管理器并安装Scalar.AspNetCore。

然后,只需在program.cs文件中添加app.MapScalarApiReference();即可映射 Scalar UI 的所有 API 引用和路由。

现在,如果您转到/Scalar/V1,您将看到端点的漂亮 UI。在这里,我只有一个端点,所以它看起来像这样。

配置标量的选项

您可以配置多个选项并更改 UI 的设置。一些配置包括。

1、Title:设置显示在浏览器选项卡顶部的文档标题
2、DarkMode: true/false 启用或禁用暗模式
3、Favicon:设置文档的图标
4、DefaultHttpClient:在浏览器中加载 UI 时显示默认 HTTP 客户端。它显示相应编程语言的代码实现。
5、HideModels: true/false 设置是否显示模型定义
6、Layout:设置 Scalar UI 的布局/主题
7、ShowSidebar: true/false 设定是否显示侧边栏。这仅在您选择了现代布局时才有效。
还有更多。

默认打开 Scalar UI

        您可能已经注意到,我们每次都必须在 URL 中输入 scalar/v1 才能看到 Scalar UI。我们可以更改启动 URL,这样就不必重复执行此操作。打开launchsettings.json文件并将启动 URL 添加到您的配置文件中。我已为 HTTP 和 HTTPS 添加了它。您可以根据您的要求进行配置。

使用授权和 JWT 令牌

        在大多数 API 中,我们都会实现 JWT 令牌或其他类型的令牌身份验证。因此,我添加了几行代码来使用 JWT 令牌实现授权。我还为此安装了 Microsoft.AspNetCore.Authentication.JwtBearer 包。

builder.Services
    .AddAuthorization()
    .AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = false,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("your_jwt_key")),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/test1", () => "This is test 1 endpoint")
    .WithName("Test1")
    .RequireAuthorization();

        当我调用此 test1 端点时,它给出了401 错误(未经授权)。那么,我们如何解决这个问题呢?我们可以简单地传递一个身份验证令牌,但如果你看看 Scalar,你会发现没有选项可以在他们的 UI 上添加身份验证/承载令牌。即使我在MapScalarApiReference中添加了PreferredSecurityScheme作为承载者,也没有针对身份验证类型的选项。

options.Authentication = new ScalarAuthenticationOptions
{
    PreferredSecurityScheme = "Bearer"
};

        如果您在标头中将身份验证令牌与授权密钥一起传递,则它可以工作,但这不是我们想要的,对吗?我们想要一个类似于 Swagger 的界面,它显示在主页或各个端点上添加令牌的选项。这是 Scalar 的一个问题,已在其 GitHub 存储库中报告:https://github.com/scalar/scalar/issues/4055。

        但是,有一种方法可以实现我们想要的并解决这个问题。我们可以使用 OpenAPI 中的文档转换器功能,微软在这里提供了详细的文档:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/customize-openapi ?view=aspnetcore-9.0 。

        使用这个转换器,我们可以通知 Scalar 我们想要在 UI 上显示身份验证选项,以便 Scalar 可以将其添加到主页以及各个端点上。

这是压缩类:

internal sealed class BearerSecuritySchemeTransformer : IOpenApiDocumentTransformer
{
    private readonly IAuthenticationSchemeProvider _authenticationSchemeProvider;

    public BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider)
    {
        _authenticationSchemeProvider = authenticationSchemeProvider;
    }

    public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
    {
        var authenticationSchemes = await _authenticationSchemeProvider.GetAllSchemesAsync();

        if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
        {
            var requirements = new Dictionary<string, OpenApiSecurityScheme>
            {
                ["Bearer"] = new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer",
                    In = ParameterLocation.Header,
                    BearerFormat = "JWT"
                }
            };

            document.Components ??= new OpenApiComponents();
            document.Components.SecuritySchemes = requirements;

            foreach (var operation in document.Paths.Values.SelectMany(path => path.Operations))
            {
                operation.Value.Security.Add(new OpenApiSecurityRequirement
                {
                    [new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Id = "Bearer",
                            Type = ReferenceType.SecurityScheme
                        }
                    }] = Array.Empty<string>()
                });
            }
        }
    }
}

此代码将在主页和所有请求端点添加一个身份验证选项,您可以在其中传递令牌来发送请求。

此代码修改了 OpenAPI/Scalar 文档以显示 API 支持 Bearer 令牌认证。

1、它首先检查 API 是否启用了“Bearer”身份验证
2、如果存在 Bearer 身份验证,它会在 OpenAPI/Scalar 中添加安全方案
3、此安全方案告诉 OpenAPI/Scalar,请求应在授权标头中包含 JWT(JSON Web Token)
4、默认情况下,这仅添加了对身份验证的支持,但在 OpenAPI/Scalar UI 中不需要它
5、为了使 UI 中看起来需要身份验证,代码循环遍历所有 API 端点并将它们标记为需要 Bearer 令牌

下面的循环就是这么做的:

foreach (var operation in document.Paths.Values.SelectMany(path => path.Operations))
{
    operation.Value.Security.Add(new OpenApiSecurityRequirement
    {
        [new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Id = "Bearer",
                Type = ReferenceType.SecurityScheme
            }
        }] = Array.Empty<string>()
    });
}

这可确保每次生成 OpenAPI/Scalar 文档时都会添加安全方案和要求。

如果您想要真正强制身份验证,则需要向控制器添加[Authorize]或在 Minimal API 中添加 RequireAuthorization() 。

现在您可以在此输入中传递您的令牌,它将被传递到服务器而不会出现任何问题,并且您将不再收到 401 错误。

您可以下载该示例项目:https://download.csdn.net/download/hefeng_aspnet/90408075

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38678.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统笔记】操作系统的功能

上节课,我们学习了《什么是操作系统》。接下来,我们来看看操作系统有哪些功能? 这里讲的内容有两部分,一个是操作系统的目标,另外一个就是操作系统的功能。这两个细节可能会在考试的时候考到,但是最近好些年很少考到了。为了理解,我们还是一起来看一下。 操作系统的目标…

C/C++蓝桥杯算法真题打卡(Day7)

一、P8723 [蓝桥杯 2020 省 AB3] 乘法表 - 洛谷 算法代码&#xff1a; #include<bits/stdc.h> // 包含标准库中的所有头文件&#xff0c;通常用于竞赛编程中简化代码 using namespace std; // 使用标准命名空间&#xff0c;避免每次调用标准库函数时都要加std:: ty…

数据结构5(初):排序

目录 1、排序的概念以及常见的排序算法 1.1、排序的概念 1.2、常见的排序算法 2、常见排序算法的实现 2.1、插入排序 2.1.1、直接插入排序 2.1.2、希尔排序 2.2、选择排序 2.2.1、直接选择排序 2.2.2、堆排序 2.3、交换排序 2.3.1、冒泡排序 2.3.2、快速排序 2.3.…

VS2022中通过VCPKG安装的ceres之后调试ceres的例程设置

1.采用C20. vcpkg中设置: 2.增加预处理宏: GLOG_USE_GLOG_EXPORT 3.屏蔽sdl错误 在 项目-属性-C/C -命令行中添加 /sdl /w34996 #include "ceres/ceres.h" //#include <iostream> //#include<glog/logging.h>using ceres::AutoDiffCostFunction; usi…

Pydantic字段级校验:解锁@validator的12种应用

title: Pydantic字段级校验:解锁@validator的12种应用 date: 2025/3/23 updated: 2025/3/23 author: cmdragon excerpt: Pydantic校验系统支持通过pre验证器实现原始数据预处理,在类型转换前完成字符清洗等操作。格式验证涵盖正则表达式匹配与枚举值约束,确保护照编号等字…

函数递归和迭代

1.什么是递归&#xff1f; 在C语言中递归就是自己调用自己。 看一下简单函数的递归&#xff1a; 上面的代码实现演示一下函数的递归&#xff0c;最终是会陷入死循环的&#xff0c;栈溢出 。 1.1递归的思想&#xff1a; 把一个大型的问题一步一步的转换成一个个小的子问题来解…

发票查验/发票验真如何用Java实现接口调用

一、什么是发票查验&#xff1f;发票验真接口&#xff1f; 输入发票基本信息发票代码、发票号码、开票日期、校验码后6位、不含税金额、含税金额&#xff0c;核验发票真伪。 该接口也适用于机动车、二手车销售发票、航空运输电子客票、铁路电子客票等。 二、如何用Java实现接口…

AM32-MultiRotor-ESC项目固件编译和烧录方法介绍

AM32-MultiRotor-ESC项目固件编译和烧录方法介绍 &#x1f4cd;AM32-MultiRotor-ESC项目地址:https://github.com/AlkaMotors/AM32-MultiRotor-ESC-firmware&#x1f388;Updater with V8 Bootloader&#xff1a; https://github.com/AlkaMotors/F051_Bootloader_Updater&#…

HarmonyOS:@AnimatableExtend 装饰器自学指南

在最近的项目开发中&#xff0c;我遇到了需要实现复杂动画效果的需求。在探索解决方案的过程中&#xff0c;我发现了 AnimatableExtend 装饰器&#xff0c;它为实现动画效果提供了一种非常灵活且强大的方式。然而&#xff0c;在学习这个装饰器的过程中&#xff0c;我发现相关的…

Windows server 2022域控制服务器的配置

Windows server 2022介绍 一、核心特性与改进 安全核心服务器&#xff08;Secured-Core Server&#xff09; 硬件级安全&#xff1a;支持基于硬件的安全功能&#xff08;如TPM 2.0、Secure Boot、基于虚拟化的安全防护VBS&#xff09;&#xff0c;防止固件攻击。受信任的启动链…

C++语法之模板函数和模板类

模板函数是什么&#xff1f;就是不指定类型的函数&#xff0c;不指定类型如何写代码?所以得用到模板&#xff0c;可以先用模板代替&#xff0c;就好像方程式&#xff0c;先用x,y代替一样。 它的写法是这样&#xff0c;定义函数时&#xff0c;开头加一句:(其中的T就相当于x,y之…

时序分析笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、周期约束 二、建立时间和保持时间 三、时序路径 四、时序模型 前言 约束文件笔记&#xff0c;傅里叶的猫的视频。 一、周期约束 时序约束就是告诉软件输…

六十天前端强化训练之第二十八天之Composition 函数完全指南

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、核心概念解析 1.1 什么是 Composition 函数 1.2 为什么需要封装 1.3 设计原则 二、实战案例&#xff1a;鼠标跟踪器 2.1 未封装版本 2.2 封装后的 Composition 函数…

MySQL 锁机制详解

MySQL 锁机制详解 5.1 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、 RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有 效性是所有数…

常见中间件漏洞攻略-Apache篇

漏洞名称&#xff1a;Apache HTTP Server 路径穿越漏洞-CVE-2021-41773 第一步&#xff1a;拉取环境、启动环境 #拉取环境 docker pull blueteamsteve/cve-2021-41773:no-cgidhttp://121.40.229.129:8080#启动环境 docker run -dit -p 8080:80 blueteamsteve/cve-2021-41773:n…

站群服务器是什么意思呢?

站群服务器是一种专门为托管和管理多个网站而设计的服务器&#xff0c;其核心特点是为每个网站分配独立的IP地址。这种服务器通常用于SEO优化、提高网站权重和排名&#xff0c;以及集中管理多个网站的需求。以下是站群服务器的详细解释&#xff1a; 一、站群服务器的定义 站群…

Excel 小黑第22套

对应大猫22 新建一行&#xff0c;输入第一个人名字&#xff0c; 填充 -快速填充 修改员工编号&#xff08;1—001&#xff09;&#xff1a;选中所有员工编号&#xff0c;开始 -数据组 -自定义数字格式 000 在所有空表格单元格中输入数字0&#xff1a;选中修改的表格范围&#…

多传感器融合 SLAM LVI-SAM

目录 LVI-SAM 简介 A. 系统概述 B. 视觉惯导系统 C.雷达惯导系统 LVI-SAM 安装编译 编译 LVI-SAM 常见问题 LVI-SAM 工程化建议 LVI-SAM 简介 源码地址:https://github.com/TixiaoShan/LVI-SAM 如无法下载,换用 gitee 版本:https://gitee.com/inf_lee/LVI-SAM 改进…

Linux shell脚本3-if语句、case语句、for语句、while语句、until语句、break语句、continue语句,格式说明及程序验证

目录 1.if 控制语句 1.1 if 语句格式 1.2 程序验证 2.case语句 2.1case语句格式 2.2程序验证 2.2.1 终端先执行程序&#xff0c;在输入一个数 2.2.2 终端执行程序时同时输入一个预设变量 2.2.3 case带有按位或运算和通配符匹配 3.for语句 3.1for语句格式 3.2程序验…

图解模糊推理过程(超详细步骤)

我们前面已经讨论了三角形、梯形、高斯型、S型、Z型、Π型6种隶属函数&#xff0c;下一步进入模糊推理阶段。 有关六种隶属函数的特点在“Pi型隶属函数&#xff08;Π-shaped Membership Function&#xff09;的详细介绍及python示例”都有详细讲解&#xff1a;https://lzm07.b…