在NET8中使用简化的 AddJwtBearer 认证
开发环境
系统版本: 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件事:
- 更新项目的
appsettings.Development.json
,添加了Authentication节点 - 更新项目的
MyJWT.csproj
,添加了UserSecretsId 配置 - 创建了机密文件
%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.csproj
与appsettings.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 认证的更多相关文章
- WCF学习之旅—WCF4.0中的简化配置功能(十五)
六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...
- spring security进阶 使用数据库中的账户和密码认证
目录 spring security 使用数据库中的账户和密码认证 一.原理分析 二.代码实现 1.新建一个javaWeb工程 2.用户认证的实现 3.测试 三.总结 spring security ...
- Asp.net Controller中View 和Action方法认证Authorize 及对AuthorizeAttribute扩展
Asp.net Controller中View和Action方法认证Authorize 在建立Web 站点安全性时 1.登录后才可访问系统文件 ——限制 Forms认证 <authenticat ...
- .net core3.1中实现简单的jwt认证
1.创建项目 使用visual studio创建一个名为JwtDemo的空项目,创建后如图 2.添加依赖项 在nuget包管理器中搜索 Microsoft.AspNetCore.Authenticat ...
- 如何在 Net6.0 中对 WebAPI 进行 JWT 认证和授权
一.简介 我们做微服务开发,或者说做分布式开发,有一项技术我们是避不开的,那就是WebAPI,在 Net6.0中,有两类 WebAPI,一类是极简 WebAPI,它砍掉了很多冗余的东西,更纯粹的是做 ...
- Hadoop-2.2.0中文文档—— Common - 服务层认证
目的 此文档描写叙述了怎样为Hadoop配置和管理 Service Level Authorization . 预备条件 确保已经安装Hadoop,配置和设置都正确了. 很多其它细节,请看:* 首次使 ...
- Laravel5中集成Jasig cas统一认证系统
CAS : CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,这里介绍下我刚在laravel5上搭建成功的cas.提前准备工作:可运行 ...
- 不使用SpringBoot如何将原生Feign集成到Spring中来简化http调用
在微服务架构中,如果使用得是SpringCloud,那么只需要集成SpringFeign就可以了,SpringFeign可以很友好的帮我们进行服务请求,对象解析等工作. 然而SpingCloud是依赖 ...
- 在混合开发框架模式中,简化客户端对Web API的频繁调用
在混合开发框架模式中,有时候我们在处理树形节点的时候,需要很多关联的处理,可能需要结合用户配置信息,属性字典,以及表的字段分类等信息来展示一个结构树,那么在处理的时候就可能会频繁的对这些接口API进行 ...
- 在Kubernetes集群中安装Helm及证书认证
安装Kubernetes 测试环境使用kubeadm安装kubernetes v1.6.3版本, 安装过程略过. 为Helm创建客户端认证 客户端认证是为了能够使用helm命令行调用Helm的服务端T ...
随机推荐
- Pytest+Jenkins 学习笔记
Pytest+Jenkins 学习笔记 在软件测试工作中,单元测试通常是由开发人员执行的.针对最小单元粒度的组件测试,在完成了单元粒度的测试任务之后,通常就需要交由专职的测试人员将这些单元级的组件放到 ...
- MySQL 使用Navicat delete/insert into/update 大量数据表锁死,kill的线程后线程处于killed状态问题解决
MySQL 使用delete/insert into/update 大量数据表锁死,kill的线程后线程处于killed状态问题解决 实际生产环境问题描述: 使用Navicat备份BigData数据表 ...
- 交叉编译 Qt5.12 armv8(aarch64) 带 WebEngine - NVIDIA JETSON TX2
编译平台 Windows10 WSL2 Debian,目标平台 NVIDIA JETSON TX2 (注:Ubuntu <= 16.04 会出现 libclang < 3.8 的问题) 下 ...
- Python/Java/Php/C#/Go/C/C++这几个主力语言,谁到底真的不行
1.前言 阿里最近又进行了史诗级的大裁员,IT行业肉眼可见的持续性衰退与没落.当潮水退却,才能看出谁在裸泳.作为当今计算机编程界的几大主力语言,谁才真正的裸泳者呢? 2.描述 1.Python: Py ...
- KRPANO最新完整汉化中文版 (KRPANO-1.19-PR10-WIN汉化版)
KRPano 最新版本汉化krpano-1.19-pr10-win,由KRPano技术解密群:551278936 提供. 下载地址:http://pan.baidu.com/s/1bBmD5c 如果需 ...
- 用Rust手把手编写一个Proxy(代理), 动工
用Rust手把手编写一个Proxy(代理), 动工 项目 ++wmproxy++ gitee 传送门 github 传送门 设计流程图 flowchart LR A[客户端] -->|Http| ...
- 「luogu - P3911」最小公倍数之和
link. Denote \(cnt_{x}\) = the number of occurrences of \(x\), \(h\) = the maximum of \(a_i\), there ...
- Merkle Tree 简介
Merkle 树(Merkle Tree)是一种树状数据结构,通常用于验证大规模数据集的完整性和一致性.它的名字来源于其发明者 Ralph Merkle.Merkle 树在密码学.分布式系统和区块链等 ...
- oracle优化-分页查询新认识
在写这篇文章之前,对分页查询的认识就是经典的三层嵌套:第①层:获得需要的数据,第②层:用rownum限制展示数据的上限,第③层:用rownum的别名rn限制展示数据的下限. 在生产中遇见一个两层嵌套满 ...
- Django框架——路由控制、视图层
文章目录 1 路由控制 一 Django中路由的作用 二 简单的路由配置 三 有名分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的path 基本示例 path转化器 注册自定 ...