开发环境

系统版本: 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

在NET8中使用简化的 AddJwtBearer 认证的更多相关文章

  1. WCF学习之旅—WCF4.0中的简化配置功能(十五)

    六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...

  2. spring security进阶 使用数据库中的账户和密码认证

    目录 spring security 使用数据库中的账户和密码认证 一.原理分析 二.代码实现 1.新建一个javaWeb工程 2.用户认证的实现 3.测试 三.总结 spring security ...

  3. Asp.net Controller中View 和Action方法认证Authorize 及对AuthorizeAttribute扩展

    Asp.net Controller中View和Action方法认证Authorize 在建立Web 站点安全性时 1.登录后才可访问系统文件 ——限制 Forms认证 <authenticat ...

  4. .net core3.1中实现简单的jwt认证

    1.创建项目 使用visual studio创建一个名为JwtDemo的空项目,创建后如图 2.添加依赖项 在nuget包管理器中搜索 Microsoft.AspNetCore.Authenticat ...

  5. 如何在 Net6.0 中对 WebAPI 进行 JWT 认证和授权

    一.简介 我们做微服务开发,或者说做分布式开发,有一项技术我们是避不开的,那就是WebAPI,在 Net6.0中,有两类 WebAPI,一类是极简 WebAPI,它砍掉了很多冗余的东西,更纯粹的是做 ...

  6. Hadoop-2.2.0中文文档—— Common - 服务层认证

    目的 此文档描写叙述了怎样为Hadoop配置和管理 Service Level Authorization . 预备条件 确保已经安装Hadoop,配置和设置都正确了. 很多其它细节,请看:* 首次使 ...

  7. Laravel5中集成Jasig cas统一认证系统

    CAS : CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,这里介绍下我刚在laravel5上搭建成功的cas.提前准备工作:可运行 ...

  8. 不使用SpringBoot如何将原生Feign集成到Spring中来简化http调用

    在微服务架构中,如果使用得是SpringCloud,那么只需要集成SpringFeign就可以了,SpringFeign可以很友好的帮我们进行服务请求,对象解析等工作. 然而SpingCloud是依赖 ...

  9. 在混合开发框架模式中,简化客户端对Web API的频繁调用

    在混合开发框架模式中,有时候我们在处理树形节点的时候,需要很多关联的处理,可能需要结合用户配置信息,属性字典,以及表的字段分类等信息来展示一个结构树,那么在处理的时候就可能会频繁的对这些接口API进行 ...

  10. 在Kubernetes集群中安装Helm及证书认证

    安装Kubernetes 测试环境使用kubeadm安装kubernetes v1.6.3版本, 安装过程略过. 为Helm创建客户端认证 客户端认证是为了能够使用helm命令行调用Helm的服务端T ...

随机推荐

  1. 不想引入mq?试试debezium

    有句话叫做"如无必要,勿增实体". 在一些小型项目当中,没有引入消息中间件,也不想引入,但有一些业务逻辑想要解耦异步,那怎么办呢? 我们的web项目,单独内网部署,由于大数据背景, ...

  2. 《深入理解Java虚拟机》笔记:垃圾收集算法和HotSpot的算法实现

    一.垃圾收集算法 由于垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程. 垃圾收集算法概要 1 ...

  3. quarkus数据库篇之二:无需数据库也能运行增删改查(dev模式)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇内容并非数据库相关的核心知识,而是对一个 ...

  4. 树莓派4b装系统到运行 Blazor Linux 本地程序全记录

    在Linux下运行gui程序,咱也是第一次做,属于是瞎子过河乱摸一通,写得有什么不对和可以优化的地方,希望各位看官斧正斧正. 1. 下载烧录器 https://www.raspberrypi.com/ ...

  5. 各种SQL连接符Join

    一.连接符分类,内连接,外连接 1.内连接:Inner Join简写Join. 2.外连接:Left Outer Join 简写Left Join:Right Outer Join 简写Right J ...

  6. C++中::和:, .和->的作用和区别

    符号::和:的作用和区别 ::是作用域运算符,A::B表示作用域A中的-名称B,A可以是名字空间.类.结构: 类作用域操作符 "::"指明了成员函数所属的类.如:M::f(s)就表 ...

  7. MySQL系列之MyCat——架构图、准备、安装、配置文件、垂直分表、MyCAT核心特性——分片(水平拆分)、范围分片、枚举分片、Mycat全局表、E-R分片

    文章目录 1. MyCAT基础架构图 2. MyCAT基础架构准备 2.1 环境准备: 2.2 删除历史环境: 2.3 创建相关目录初始化数据 2.4 准备配置文件和启动脚本 2.5 修改权限,启动多 ...

  8. macbook-键盘连击问题002

    https://support.apple.com/zh-cn/HT205662 如何清洁 MacBook 或 MacBook Pro 的键盘 如果您的 MacBook(2015 年及更新机型)或 M ...

  9. jmeter的全局变量(将登陆token设置全局)

    1.首先调用登陆接口,用json提取器,取出响应内的token值  2.在beanshell取样器中设置全局变量 //设置全局变量方法一:用函数__setProperty设置${__setProper ...

  10. Spring扩展接口(2):BeanDefinitionRegistryPostProcessor

    在此系列文章中,我总结了Spring几乎所有的扩展接口,以及各个扩展点的使用场景.并整理出一个bean在spring中从被加载到最终初始化的所有可扩展点的顺序调用图.这样,我们也可以看到bean是如何 ...