首页 > 其他分享 >在NET8中使用简化的 AddJwtBearer 认证

在NET8中使用简化的 AddJwtBearer 认证

时间:2023-12-04 13:23:28浏览次数:40  
标签:PS 00 MyJWT Learn 认证 NET8 var AddJwtBearer localhost

开发环境

系统版本: win10
.NET SDK: NET8
开发工具:vscode
参考引用:使用 dotnet user-jwts 管理开发中的 JSON Web 令牌
注意:以下示例中的端口、token等需替换成你的环境中的信息

创建项目

运行以下命令来创建一个空的 Web 项目,并添加 Microsoft.AspNetCore.Authentication.JwtBearer NuGet 包:

dotnet new web -o MyJWT
cd MyJWT
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

将 Program.cs 的内容替换为以下代码(略微改动):

using System.Security.Claims;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();
// 默认的Scheme是Bearer
// builder.Services.AddAuthentication("Bearer").AddJwtBearer();
builder.Services.AddAuthentication().AddJwtBearer();

var app = builder.Build();

app.UseAuthorization();

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

app.Run();

运行项目并访问接口返回以下内容

PS D:\Learn\MyJWT> curl.exe -i http:///localhost:5276
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Mon, 04 Dec 2023 00:43:03 GMT    
Server: Kestrel
Transfer-Encoding: chunked

Hello, World!

创建 JWT

PS D:\Learn\MyJWT> dotnet user-jwts create
New JWT saved with ID 'c28b968'.
Name: Lingpeng

Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkxpbmdwZW5nIiwic3ViIjoiTGluZ3BlbmciLCJqdGkiOiJjMjhiOTY4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6Mjk3NTQiLCJodHRwczovL2xvY2FsaG9zdDo0NDM2MCIsImh0dHA6Ly9sb2NhbGhvc3Q6NTI3NiIsImh0dHBzOi8vbG9jYWxob3N0OjcyNTMiXSwibmJmIjoxNzAxNjQ5Nzk2LCJleHAiOjE3MDk1MTIxOTYsImlhdCI6MTcwMTY0OTc5NiwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.l52s9_7oNjIKL96TysgdE0k970fUS9FoLTu2xRs-IPo

这个命令做了3件事:

  1. 更新项目的 appsettings.Development.json,添加了Authentication节点
  2. 更新项目的 MyJWT.csproj,添加了UserSecretsId 配置
  3. 创建了机密文件 %APPDATA%\Microsoft\UserSecrets\<secrets_GUID>\user-jwts.json%APPDATA%\Microsoft\UserSecrets\<secrets_GUID>\secrets.json机密管理参考

我们看下这两个机密文件
user-jwts.json

{
    "c28b968": {
        "Id": "c28b968",
        "Scheme": "Bearer",
        "Name": "Lingpeng",
        "Audience": "http://localhost:29754, https://localhost:44360, http://localhost:5276, https://localhost:7253",
        "NotBefore": "2023-12-04T00:29:56+00:00",
        "Expires": "2024-03-04T00:29:56+00:00",
        "Issued": "2023-12-04T00:29:56+00:00",
        "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkxpbmdwZW5nIiwic3ViIjoiTGluZ3BlbmciLCJqdGkiOiJjMjhiOTY4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6Mjk3NTQiLCJodHRwczovL2xvY2FsaG9zdDo0NDM2MCIsImh0dHA6Ly9sb2NhbGhvc3Q6NTI3NiIsImh0dHBzOi8vbG9jYWxob3N0OjcyNTMiXSwibmJmIjoxNzAxNjQ5Nzk2LCJleHAiOjE3MDk1MTIxOTYsImlhdCI6MTcwMTY0OTc5NiwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.l52s9_7oNjIKL96TysgdE0k970fUS9FoLTu2xRs-IPo",
        "Scopes": [],
        "Roles": [],
        "CustomClaims": {}
    }
}

secrets.json

{
    "Authentication:Schemes:Bearer:SigningKeys": [
        {
            "Id": "ff20683d",
            "Issuer": "dotnet-user-jwts",
            "Value": "lDOFmIuEDelFKU0zAaLoT2qYOFDRZGDDTv5FyTa36V8=",
            "Length": 32
        }
    ]
}

测试JWT

我们重新运行程序,用直接访问与携带token两种方式访问/secret接口

PS D:\Learn\MyJWT> curl.exe -i http://localhost:5276/secret
HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Mon, 04 Dec 2023 00:43:25 GMT
Server: Kestrel
WWW-Authenticate: Bearer

PS D:\Learn\MyJWT> 
PS D:\Learn\MyJWT> 
PS D:\Learn\MyJWT> curl.exe -i -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkxpbmdwZW5nIiwic3ViIjoiTGluZ3BlbmciLCJqdGkiOiJjMjhiOTY4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6Mjk3NTQiLCJodHRwczovL2xvY2FsaG9zdDo0NDM2MCIsImh0dHA6Ly9sb2NhbGhvc3Q6NTI3NiIsImh0dHBzOi8vbG9jYWxob3N0OjcyNTMiXSwibmJmIjoxNzAxNjQ5Nzk2LCJleHAiOjE3MDk1MTIxOTYsImlhdCI6MTcwMTY0OTc5NiwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.l52s9_7oNjIKL96TysgdE0k970fUS9FoLTu2xRs-IPo" http://localhost:5276/secret
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Mon, 04 Dec 2023 00:45:42 GMT
Server: Kestrel
Transfer-Encoding: chunked

Hello Lingpeng. My secret

至此我们已经实现了JwtBearer的初步使用

一点点改动

示例采用了机密管理,我们也可以把机密文件中的内容迁移至项目中(推荐用机密管理),我们修改MyJWT.csprojappsettings.Development.json如下

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <!-- <UserSecretsId>88d7c163-def1-4747-b01f-cefed382beae</UserSecretsId> -->
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
  </ItemGroup>

</Project>
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [
          "http://localhost:29754",
          "https://localhost:44360",
          "http://localhost:5276",
          "https://localhost:7253"
        ],
        "ValidIssuer": "dotnet-user-jwts",
        "SigningKeys": [
          {
            "Id": "ff20683d",
            "Issuer": "dotnet-user-jwts",
            "Value": "lDOFmIuEDelFKU0zAaLoT2qYOFDRZGDDTv5FyTa36V8=",
            "Length": 32
          }
        ]
      }
    }
  }
}

修改完成后实现相同的功能

JWT Token生成示例

app.MapGet("/login", (string UserName, string Password, [FromServices] IOptionsMonitor<JwtBearerOptions> optionsMonitor) =>
{
    // 1. 密码验证
    // TODO

    // 2. 生成  
    var parameters = optionsMonitor.Get(JwtBearerDefaults.AuthenticationScheme).TokenValidationParameters;
    var signingKey = parameters.IssuerSigningKeys.First();
    var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature);
    var header = new JwtHeader(signingCredentials);
    var payload = new JwtPayload {
        { JwtRegisteredClaimNames.UniqueName, UserName },
        { JwtRegisteredClaimNames.Iss, parameters.ValidIssuers.First() },
        { JwtRegisteredClaimNames.Aud, parameters.ValidAudiences },
        { JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
        { JwtRegisteredClaimNames.Nbf, DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
        { JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddMinutes(30).ToUnixTimeSeconds() }
    };
    var jwtSecurityToken = new JwtSecurityToken(header, payload);
    var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    var token = jwtSecurityTokenHandler.WriteToken(jwtSecurityToken);
    return token;
});

进行一下验证

PS D:\Learn\MyJWT> curl.exe -i "http://localhost:5276/login?username=admin&password=1111"
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Mon, 04 Dec 2023 05:03:36 GMT
Server: Kestrel
Transfer-Encoding: chunked

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiaXNzIjoiZG90bmV0LXVzZXItand0cyIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjI5NzU0IiwiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNjAiLCJodHRwOi8vbG9jYWxob3N0OjUyNzYiLCJodHRwczovL2xvY2FsaG9zdDo3MjUzIl0sImlhdCI6MTcwMTY2NjIxNiwibmJmIjoxNzAxNjY2MjE2LCJleHAiOjE3MDE2NjgwMTZ9.P9t7vIFfM7cddRPs4OQUTVVdo57nWTLt_ea2UynGUpo
PS D:\Learn\MyJWT>
PS D:\Learn\MyJWT>
PS D:\Learn\MyJWT> curl.exe -i -H "Authorization: Bearer eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiaXNzIjoiZG90bmV0LXVzZXItand0cyIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjI5NzU0IiwiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNjAiLCJodHRwOi8vbG9jYWxob3N0OjUyNzYiLCJodHRwczovL2xvY2FsaG9zdDo3MjUzIl0sImlhdCI6MTcwMTY2NjIxNiwibmJmIjoxNzAxNjY2MjE2LCJleHAiOjE3MDE2NjgwMTZ9.P9t7vIFfM7cddRPs4OQUTVVdo57nWTLt_ea2UynGUpo" http://localhost:5276/secret
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Mon, 04 Dec 2023 05:03:50 GMT
Server: Kestrel
Transfer-Encoding: chunked

Hello admin. My secret

标签:PS,00,MyJWT,Learn,认证,NET8,var,AddJwtBearer,localhost
From: https://www.cnblogs.com/lludcmmcdull/p/17874175.html

相关文章

  • .NET8 依赖注入
    依赖注入(DependencyInjection,简称DI)是一种设计模式,用于解耦组件(服务)之间的依赖关系。它通过将依赖关系的创建和管理交给外部容器来实现,而不是在组件(服务)内部直接创建依赖对象。​ 咱就是通过IServiceCollection和IServiceProvider来实现的,他们直接被收入到了runtimelibrari......
  • Windows驱动中数字签名认证(使用 ci.dll)
    1.背景  对于常规应用程序来说,在应用层可以使用WinVerifyTrust,在驱动层使用常规的API无法使用,自己分析数据又太麻烦。  但在内核中ci.dll包装了数据签名验证相关的功能,我们可以使用该dll来实现我们的数字签名验证。  详细的分析见《内核中的代码完整性:深入分析ci......
  • CSP第31次认证题解 2023.9
    A、坐标变换(其一)样例输入3210100010-201-100样例输出21-1120-10题解按照题目,一个循环即可#include<bits/stdc++.h>usingnamespacestd;#defineN200010#definelllonglongtemplate<classT>inlinevoidread(T&a){Tx=0,s=1;......
  • 拓数派云原生数据库PieCloudDB与XSKY产品完成兼容性互认证
    数据库作为数字经济建设的基础,是产业数字化、释放数据价值的基石。而良好的生态建设是数据库发展的重要一环。 拓数派的云原生eMPP数据库产品PieCloudDBDatabase原生兼容PostgreSQL/Greenplum生态组件,兼容包括开源空间数据管理组件PostGIS,Apache开源机器学习库Madlib、开源查......
  • 手把手教学Zabbix7.0+麒麟操作系统,兼容认证
    感谢本文作者李根,Zabbix高级认证工程师(ZCP)。Zabbix6.0在麒麟操作系统上进行部署测试成功,所以此刻想验证Zabbix7.0的兼容性。结果证明是兼容的!主要步骤见下文。Zabbix7.0LTS(长期支持版本)计划于2024年第一季度发布,但其内测版本已于近日在官方更新。信创托底Zabbix提供了百......
  • 世微 降压恒流IC AP5199S LED电源 车灯景观灯舞台灯 过EMC认证线路图
    说明AP5199S是一款外围电路简单的多功能平均电流型LED恒流驱动器,适用于宽电压范围的非隔离式大功率恒流LED驱动领域。芯片PWM端口支持超小占空比的PWM调光,可响应最小60ns脉宽。芯片采用我司算法,为客户提供最佳解决方案,最大限度地发挥灯具优势,以实现景观舞台灯高辉的调......
  • 华为认证 | 华为HCIE笔试一共多少道题?HCIE证书怎么查?
    HCIE证书的含金量非常高。然而,要想获得这张宝贵的证书,考生需要先通过HCIE笔试。那么,华为HCIE笔试到底有多少道题?如何查询HCIE证书呢?下面将为您一一解答。01华为HCIE笔试一共多少道题华为HCIE笔试题目数量并不是固定的,而是根据不同的考试级别和考试内容有所差异。对于HCIE-Datacom......
  • 网工内推 | 高级网工,上市公司,NP认证优先,包吃包住
    01郑州格蒂电力智能科技有限公司招聘岗位:高级网络运维工程师职责描述:1、熟悉主流交换机与路由器的技术特点与性能,掌握其安装实施规范,完成故障处理及设备配置;2、熟练掌握网络布线、测试及维护,熟悉各类网络设备的配置和管理;3、熟练掌握二层相关技术(VLAN、链路聚合、冗余协议、STP、......
  • 标题:考试认证在计算机领域的重要性
    在当今竞争激烈的就业市场上,计算机技能的认证考试越来越受到青睐。无论是寻找工作还是提升职业发展,通过专业的考试认证都可以帮助个人展示自己的技能和知识水平,为自己的职业生涯增添更多可能性。首先,考试认证可以证明一个人在特定领域的专业知识和技能。例如,像Microsoft的MCP、Cisc......
  • CCF认证——202109-2 贡献的变化——差分维护,前缀和算答案
    https://www.acwing.com/problem/content/4010/http://118.190.20.162/view.page?gpid=T130脑子一热抱着玩的心态试了一下三分,当然炸了,就当初认识三分了。正解是考虑p的变化的影响,p变成p+1的时候,答案的值取决于p属于相邻递增数对的值域区间的数量。也可以考虑递减的情况,两......