在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 ...
随机推荐
- quarkus依赖注入之十:学习和改变bean懒加载规则
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<quarkus依赖注入> ...
- jQuery Mobile 使用中的问题
1.点击data-role="page"内的页面,会自动隐藏头部栏和尾部栏. 在data-role="header"或data-role="foote ...
- .NET Core基础到实战案例零碎学习笔记
前言:前段时间根据 [老张的哲学] 大佬讲解的视频做的笔记,讲的很不错.此文主要记录JWT/DI依赖注入/AOP面向切面编程/DTO/解决跨域等相关知识,还包含一些.NET Core项目实战的一些案例 ...
- 产品代码都给你看了,可别再说不会DDD(三):战略设计
这是一个讲解DDD落地的文章系列,作者是<实现领域驱动设计>的译者滕云.本文章系列以一个真实的并已成功上线的软件项目--码如云(https://www.mryqr.com)为例,系统性地讲 ...
- AI绘画创意文字全流程揭秘,你的终极文字艺术实操宝典
本教程收集于:AIGC从入门到精通教程汇总 AIGC技术不断更新迭代,国内出现了越来越多的新玩法,比如最近大家都在热议的AI绘画创意文字. 过去的一周,我把这些新玩法都研究了一遍,并总结了一套完整的制 ...
- Kafka-基础
1. 简介 Kafka(Apache Kafka) 是一种分布式流数据平台,最初由LinkedIn开发,并于后来捐赠给Apache软件基金会,成为了一个Apache顶级项目.它被设计用于处理大规模.实 ...
- 深入了解API接口技术及其应用
尊敬的读者们,大家好!在互联网时代,API(Application Programming Interface)接口已经成为开发者们连接各种应用.获取数据的重要工具.今天,我们将深入探讨API接口技术 ...
- Tongweb远程调试
最近,在对项目进行国产化时,要求springboot项目容器换成tongweb.在部署中,有个问题一直无法在本地重现,搜了下网上资料,基本没法实现,所以我整理了下.注意,项目包代码必须与本地代码保持一 ...
- 开源社区赋能,Walrus 用户体验再升级
基于平台工程理念的应用管理平台 Walrus 已于上月正式开源,目前在 GitHub 已收获 177 颗星 Walrus 希望打造简洁清爽的应用部署与管理体验,帮助研发与运维团队减少"内耗& ...
- BZ全景编辑器(KRPano全景可视化编辑器, 无需编写代码, 图形化制作全景漫游)
软件简介 BZ全景编辑器是一款KRPano全景可视化编辑工具,下载安装即可使用,无需拥有任何KRPano代码基础,便可以制作生成精美的全景漫游作品. BZ全景编辑器群:882083973 最新版软件下 ...