TodoApi - 具有 JWT 身份验证和授权的 ASP.NET Core API

Created at: 2021-05-04 23:37:57
Language: C#
License: MIT

具有 ASP.NET 核心的待办事项应用程序

词

这是一个待办事项应用程序,具有以下功能:

  • Todo.Web - ASP.NET 核心托管的 Blazor WASM 前端应用程序
  • TodoApi - 使用最少API的 ASP.NET 核心REST API后端

图像

它展示了:

  • Blazor WebAssembly
  • 最少的接口
  • 使用 EntityFramework 和 SQLite 进行数据访问
  • 开放接口
  • 使用 ASP.NET 核心身份进行用户管理
  • 饼干身份验证
  • 智威汤逊身份验证
  • 使用 YARP 的 IHttpForwarder 代理来自前端应用程序服务器的请求
  • 速率限制
  • 为 REST API 编写集成测试

先决条件

。网

  1. 安装 .NET 7

数据库

  1. 安装 dotnet-ef 工具:
    dotnet tool install dotnet-ef -g
  2. 导航到该文件夹。
    TodoApi
    1. 运行以创建本地数据库文件夹。
      mkdir .db
    2. 运行以创建数据库。
      dotnet ef database update
  3. 了解有关 dotnet-ef 的更多信息

智威汤逊

  1. 要初始化 JWT 生成的密钥,请运行到 TodoApi 文件夹:

    dotnet user-jwts

    dotnet user-jwts create
    

运行应用程序

要运行应用程序,请同时运行 Todo.Web/ServerTodoApi。以下是运行这两个应用程序的不同方法:

  • Visual Studio - 通过右键单击解决方案并选择“属性”来设置多个启动项目。选择 和 作为启动项目。

    TodoApi
    Todo.Web.Server

    图像
  • Visual Studio Code - 打开 2 个终端窗口,一个在 Todo.Web.Server 中,另一个在 TodoApi run 中:

    dotnet watch run -lp https
    

    这将使用配置文件运行这两个应用程序。

    https

  • Tye - 使用以下命令安装全局工具:

    dotnet tool install --global Microsoft.Tye --version 0.11.0-alpha.22111.1
    

    在存储库根目录中运行并导航到 tye dashboard (通常 http://localhost:8000)以查看两个正在运行的应用程序。

    tye run

  • Docker 撰写 - 打开终端,导航到此项目的根文件夹并运行以下命令:

    1. 直接从 dotnet 发布生成 docker 映像。

      TodoApi

      dotnet publish ./TodoApi/TodoApi.csproj --os linux --arch x64 /t:PublishContainer -c Release
      
    2. 直接从 dotnet 发布生成 docker 映像。

      Todo.Web.Server

      dotnet publish ./Todo.Web/Server/Todo.Web.Server.csproj --os linux --arch x64 /t:PublishContainer -c Release --self-contained true
      
    3. 生成证书并配置本地计算机,以便我们可以使用 docker compose 启动具有 https 支持的应用程序。

      使用 Linux 容器的 Windows

      set PASSWORD YourPasswordHere
      dotnet dev-certs https -ep ${HOME}/.aspnet/https/todoapps.pfx -p $PASSWORD --trust
      

      macOS 或 Linux

      export PASSWORD=YourPasswordHere
      dotnet dev-certs https -ep ~/.aspnet/https/todoapps.pfx -p $PASSWORD --trust
      
    4. 在文件中更改下面的这些变量以匹配你的 https 证书和密码。

      docker-compose.yml

      • ASPNETCORE_Kestrel__Certificates__Default__Password
      • ASPNETCORE_Kestrel__Certificates__Default__Path
    5. 运行以启动应用程序todo-api和todo-web-server以及Jaeger和Prometheus。

      docker-compose up -d

    6. 导航到待办事项 Web 应用程序 https://localhost:5003

自选

独立使用 API

Todo REST API也可以独立运行。你可以运行 TodoApi 项目并使用 Swagger UI(或你选择的客户端)向各种端点发出请求:

图像

在执行任何请求之前,你需要创建一个用户并获取身份验证令牌。

  1. 要创建新用户,请运行应用程序并将 JSON 有效负载发布到终端节点:

    /users

    {
      "username": "myuser",
      "password": "<put a password here>"
    }
  2. 要获取上述用户的令牌,请运行以创建具有上面指定的相同用户名的 JWT 令牌,例如:

    dotnet user-jwts

    dotnet user-jwts create -n myuser
    
  3. 你应该能够使用此令牌向待办事项端点发出经过身份验证的请求。

  4. 了解有关用户 JWTS 的更多信息

社交认证

除了用户名和密码之外,还可以将社交身份验证提供程序配置为使用此待办事项应用程序。默认情况下,它支持Github,Google和Microsoft帐户。

有关设置每个提供程序的说明,请参阅:

获取客户端 ID 和客户端密码后,必须使用以下架构添加这些提供程序的配置:

{
    "Authentication": {
        "Schemes": {
            "<scheme>": {
                "ClientId": "xxx",
                "ClientSecret": "xxxx"
            }
        }
    }
}

或使用环境变量:

Authentication__Schemes__<scheme>__ClientId=xxx
Authentication__Schemes__<scheme>__ClientSecret=xxx

或使用用户机密:

dotnet user-secrets set Authentication:Schemes:<scheme>:ClientId xxx
dotnet user-secrets set Authentication:Schemes:<scheme>:ClientSecret xxx

可以在此处找到其他提供商。这些也必须添加到身份验证扩展中。

注意:不要在配置中存储客户端机密!

外部身份验证服务器

与社交身份验证非常相似,此应用程序还支持外部开放 ID 连接 (OIDC) 服务器。外部身份验证被视为社交身份验证提供程序,但也会生成可与 TodoAPI 一起使用的访问令牌。这需要像Todo.Web.Server应用程序中的社交提供程序一样进行配置,并且需要在TodoAPI中配置其他身份验证方案以接受身份验证服务器颁发的JWT令牌。

流程如下所示:

图像

下面介绍了如何配置身份验证:

{
  "Authentication": {
    "Schemes": {
      "<scheme>": {
      }
    }
  }
}

注意:不要在配置中存储客户端机密!

身份验证0

此示例将 Auth0 配置为 OIDC 服务器。可以使用以下架构对其进行配置:

{
  "Authentication": {
    "Schemes": {
      "Auth0": {
        "Audience": "<audience>",
        "Domain": "<domain>",
        "ClientId": "<client id>",
        "ClientSecret": "<client secret>"
      }
    }
  }
}

下面是配置 TodoAPI 的示例:

{
  "Authentication": {
    "Schemes": {
      "Auth0": {
        "ValidAudiences": [ "<your audience here>" ],
        "Authority": "<your authority here>"
      }
    }
  }
}

在此处了解有关 Auth0 .NET SDK 的详细信息。

开放遥测

TodoApi使用OpenTelemetry来收集日志,指标和跨度。

如果要查看收集的遥测数据,请执行以下步骤。

指标

  1. 使用 Docker 运行 Prometheus:
docker run -d -p 9090:9090 --name prometheus -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
  1. 在浏览器中打开普罗米修斯
  2. 查询收集的指标

跨越

  1. 使用正确的端点 URL 配置环境变量,以便在下面启用 ,在文件中
    OTEL_EXPORTER_OTLP_ENDPOINT
    .AddOtlpExporter
    builder.Services.AddOpenTelemetryTracing
    TodoApi/OpenTelemetryExtensions.cs
  2. 使用 Docker 运行 Jaeger:
docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 -e COLLECTOR_OTLP_ENABLED=true -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 4317:4317 -p 4318:4318 -p 14250:14250 -p 14268:14268 -p 14269:14269 -p 9411:9411 jaegertracing/all-in-one:latest
  1. 在浏览器中打开 Jaeger。
  2. 查看收集的范围

原木

这个应用程序使用,为此目的我们使用Serilog

structured logging

要设置 Serilog,你应该调用 SerilogExtensions 类并使用适当的选项添加部分

AddSerilog
Serilog

  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    }
  }

对于收集和搜索日志,有两种方法,基于生产环境:

optional
your needs

  • Seq(商业用途不是免费的)
  • Elasticsearch 和 Kibana(免费)

要使用 seq,我们应该在 appsettings.json 部分中使用设置值启用它:

SeqUrl
Serilog

  "Serilog": {
     ...
    "SeqUrl": "http://localhost:5341",
     ...
  },

此外,我们应该在docker-compose文件上运行seq服务器,现在seqhttp://localhost:8081 上可用,我们可以看到那里的日志。

Elasticsearch 和 Kibana

对于使用 elasticsearch 和 kibana,我们应该在 appsettings.json 部分中使用设置值来启用它:

ElasticSearchUrl
Serilog

  "Serilog": {
     ...
    "ElasticSearchUrl": "http://localhost:9200",
     ...
  }

此外,我们应该在docker-compose文件上运行Elasticsearch和Kibana,现在我们可以看到我们在kibana url http://localhost:5601 和索引名称上的日志。

todoapi