在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 ...
随机推荐
- Flutter系列文章-实战项目
在本篇文章中,我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识,包括保存到数据库.进行 HTTP 请求等.我们将开发一个简单的天气应用,可以根据用户输入的城市名获取该城市的天气信息, ...
- iostat命令安装及详解
iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同vmstat一样,i ...
- 【Hexo】NexT 主题的配置使用记录
目录 简介 版本 安装 配置记录 风格/主题 网页图标 菜单栏 侧边栏 本地搜索 代码块 动画效果 阅读进度 书签 Mermaid lazyload fancybox pangu 捐赠 版权声明 不蒜 ...
- ChatGPT如何生成可视化图表-示例中国近几年出生人口
本教程收集于:AIGC从入门到精通教程汇总 ChatGPT本身不能直接生成可视化图表,但可以配合其他可视化工具或库 方法一:前端可视化开发库 Echarts(地址:Apache ECharts ) 方 ...
- Nomad系列-Nomad网络模式
系列文章 Nomad 系列文章 概述 Nomad 的网络和 Docker 的也有很大不同, 和 K8s 的有很大不同. 另外, Nomad 不同版本(Nomad 1.3 版本前后)或是否集成 Cons ...
- 当开源项目 Issue 遇到了 DevChat
目录 1. 概述 2. Bug 分析与复现 3. Bug 定位与修复 4. 代码测试 5. 文档更新 6. 提交 Commit 7. 总结 1. 概述 没错,又有人给 GoPool 项目提 issue ...
- Elasticsearch整合SpringBoot案例
1.elasticsearch官方文档的使用与介绍 1.1.Rest客户端初始化官方文档链接: https://www.elastic.co/guide/en/elasticsearch/client ...
- MyBatis-Plus和PageHelper冲突导致Factory method sqlSessionFactory threw exception,并且如何分页显示全部
springboot开始引入了mybaits-plus.后来想引入pagehelper进行分页,引入之后报错 Error starting ApplicationContext. To display ...
- zxy 简单 dp 大讲堂
讲课讲得非常清楚啊,我绝赞膜拜.节奏可以,思路清晰,解法自然,为讲师点赞. 第一个题是 loj3282 / joisc2020 - Treatment Project.原问题由 \(\left(S, ...
- SpringCloud-ZipKin搭建保姆级教程
服务链路追踪 一.服务追踪说明 微服务架构是通过业务来划分服务的,使⽤REST调⽤.对外暴露的⼀个接⼝,可能需要 很多个服务协同才能完成这个接⼝功能,如果链路上任何⼀个服务出现问题或者⽹络超 时,都会 ...